I'm starting with VueJS 2 and I created a simple plugin which adds parameter to Vue instance.
I have problem because when I update this value my computed properties are still same.
My example plugin's code:
export default function (Vue) {
Vue.MyProperty = "test"
Object.defineProperties(Vue.prototype, {
"$myProperty": {
"get": function () {
return Vue.MyProperty
},
"set": function (value) {
Vue.MyProperty = value
return this
}
}
})
}
And my component's code
export default {
"computed": {
"test": function () {
return this.$myProperty
}
}
}
When I changed this.$myProperty
in other component my component returns vaid value (in example when I changed from "test"
into "newvalue"
I can see "newvalue"
) but computed property test
is still old value ("test"
in my example).
I tried to use this.$set(this, "$myProperty", value)
but this still not working.
How can I use or declare this property to use it in computed or watched properties?
The reason the data value is not automatically updated in the computed is because the property you added to Vue, MyProperty
is not an observed property. Fundamentally, Vue's reactivity works because all values added to data are converted into observed properties; under the hood they are converted into getter/setter pairs with some additional code so that when one of those properties changes, Vue knows to propagate the changes to all the things that depend on it's value.
The code in the question, however, just adds a normal property to the Vue object. You can change it, but it's not reactive.
That said, it's relatively easy to make it reactive. I cover how to do this in the comments to my answer here. Basically, instead of adding your property to Vue, just create a new Vue object (which has very low overhead) and make the property you want to be reactive a property of that Vue. Here is a working example.
console.clear()
function MyPlugin(Vue) {
let store = new Vue({data:{MyProperty: "some value"}})
Object.defineProperties(Vue.prototype, {
"$myProperty": {
"get": function () {
return store.MyProperty
},
"set": function (value) {
store.MyProperty = value
return this
}
}
})
}
Vue.use(MyPlugin)
const MyComponent = {
template:`<div>{{test}}</div>`,
"computed": {
"test": function () {
return this.$myProperty
}
}
}
new Vue({
el: "#app",
components:{
MyComponent
}
})
<script src="https://unpkg.com/vue@2.4.2"></script>
<div id="app">
<my-component></my-component>
<button @click="$myProperty = 'new value'">Change</button>
</div>