Skip to content

Instantly share code, notes, and snippets.

@JonathanDn
Last active June 20, 2023 15:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonathanDn/0a82e36d517302538592571b448c2a55 to your computer and use it in GitHub Desktop.
Save JonathanDn/0a82e36d517302538592571b448c2a55 to your computer and use it in GitHub Desktop.
Vue.js 2/3 - Vue.Observable - Simple Store Implementation, returning a reactive object.
// component importing and mutating state from store.js (all getters, mutations, actions)
// reference = https://austincooper.dev/2019/08/09/vue-observable-state-store/
<template>
<div>
<div>Radius: {{ radius }}</div>
<div>Color: {{ color }}</div>
<button @:click="setRadius(0)">Reset radius</button>
<button @:click="fetchColorFromApi">Fetch color</button>
</div>
</template>
<script>
import { getters, mutations, actions } from 'store.js';
export default {
data() { return {}; },
computed() {
...getters // radius(), color()
},
created() {
this.fetchRadiusFromApi(); // fetching data right away
this.fetchColorFromApi().then(() => {
console.log('You can chain then after actions, if you return the request');
});
}
methods() {
...mutations, // setRadius(val), setColor(val)
...actions // fetchRadiusFromApi(), fetchColorFromApi()
}
}
</script>
// component importing and mutating state from store.js with specific imported methods
// from store and expose it via local method in a .vue component
computed() {
// ...getters <- instead of this, do this:
radius() {
return getters.radius;
},
diameter() {
return getters.radius * 2;
}
// this component doesn't need color
}
// store.js standard setup with Vue.Observable()
import Vue from 'vue';
import axios from 'axios';
const state = Vue.Observable({ // this is the magic
radius: 0,
color: 'red'
});
export const getters {
radius: () => state.radius,
color: () => state.color
}
export const mutations {
setRadius: (val) => state.radius = val,
setColor: (val) => state.color = val
}
export const actions {
fetchRadiusFromApi() {
return axios
.get('http://localhost:5001/api/radius')
.then((res) => {
mutations.setRadius(res.data);
});
},
fetchColorFromApi() {
return axios
.get('http://localhost:5001/api/color')
.then((res) => {
mutations.setColor(res.data);
});
}
}
@gregg-cbs
Copy link

hmm with Vue 3 im getting the error:
"can't access property "Observable""

@dimer47
Copy link

dimer47 commented Aug 14, 2022

Hi @gregg-cbs

I suggest you to use import { reactive } from "vue"; instead of import Vue from 'vue'; and replace const state = Vue.Observable({ .... }) with export const store = reactive({ .... }).

This is work for me in Vue 3.

// store.js standard setup with Vue.Observable()
import { reactive } from "vue";
import axios from 'axios';

export const store = reactive({
    radius: 0,
    color: 'red'
});

export const getters {
    radius: () => state.radius,
    color: () => state.color
}

export const mutations {
    setRadius: (val) => state.radius = val,
    setColor: (val) => state.color = val
}

export const actions {
    fetchRadiusFromApi() {
        return axios
            .get('http://localhost:5001/api/radius')
            .then((res) => {
                mutations.setRadius(res.data);
            });
    },
    fetchColorFromApi() {
        return axios
            .get('http://localhost:5001/api/color')
            .then((res) => {
                mutations.setColor(res.data);
            });
    }
}

@Nielson
Copy link

Nielson commented Sep 15, 2022

Thanks @dimer47!

This worked for me :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment