admin管理员组文章数量:1291600
I have a VueJS ponent like this
const MyComponent = Vue.extend({
props: ["myHandle"],
puted: {
name: {
get: function() { return myHandle.getName() },
set: function(newName) { myHandle.setName(newName) },
}
}
})
The problem is that setting the puted property name
does not trigger VueJs to update the property. Meaning the old name is what gets displayed on re-render.
Now, I'm fairly new to VueJS and i can see how this might be code smell, but the thing is that the myHandle
property is actually a handle to access data in a WebAssembly module written in rust. The rust code is where most of my state/model/source of truth lives.
The two unsatisfactory solutions i have found thus far are:
Use a method to retrieve the name instead of a puted property. Basically add a
getName
method to my ponent and change my template code from<p> Your name is {{ name }}</p>
to<p> Your name is {{ getName() }}</p>
. Which will cause VueJs to not cache. In the future I'm planing to do expensive putations meaning unnecessary performance costCopy state from the rust side to my ponent. This I do not want to do since I would get multiple source of truth.
So is there some way to:
A: Get VueJS to understand that myHandle.setName
is a mutating method that should cause name
puted property to be updated.
B: Manually trigger an update.
C Solve it in some other manner?
I have a VueJS ponent like this
const MyComponent = Vue.extend({
props: ["myHandle"],
puted: {
name: {
get: function() { return myHandle.getName() },
set: function(newName) { myHandle.setName(newName) },
}
}
})
The problem is that setting the puted property name
does not trigger VueJs to update the property. Meaning the old name is what gets displayed on re-render.
Now, I'm fairly new to VueJS and i can see how this might be code smell, but the thing is that the myHandle
property is actually a handle to access data in a WebAssembly module written in rust. The rust code is where most of my state/model/source of truth lives.
The two unsatisfactory solutions i have found thus far are:
Use a method to retrieve the name instead of a puted property. Basically add a
getName
method to my ponent and change my template code from<p> Your name is {{ name }}</p>
to<p> Your name is {{ getName() }}</p>
. Which will cause VueJs to not cache. In the future I'm planing to do expensive putations meaning unnecessary performance costCopy state from the rust side to my ponent. This I do not want to do since I would get multiple source of truth.
So is there some way to:
A: Get VueJS to understand that myHandle.setName
is a mutating method that should cause name
puted property to be updated.
B: Manually trigger an update.
C Solve it in some other manner?
Share edited Jan 29, 2019 at 10:08 Emma asked Jan 29, 2019 at 10:04 EmmaEmma 3141 gold badge4 silver badges11 bronze badges4 Answers
Reset to default 3Computed properties are cached based on their dependencies (data, props and other puted properties). If I've understood correctly, your puted property won't be reactive cause the only dependency is myHandle, and I assume that will never change. Look at it this way, Vue can only check that getName is returning a different value by actually calling the method, so there's nothing to cache.
If the name can only be changed from your Vue ponent, you can set it as a data field and add a watcher to update the WebAssembly value. Otherwise, if the name can be changed from non-Vue sources and you must call the getName method from the handler every time, you will have to e up with your own mechanism (maybe using a debounce function to limit the number of calls).
I don't know how your implementation of setName() is, but if it is
setName(newName) { this.name = newName; }
you might have run into the problem described here: https://v2.vuejs/v2/guide/reactivity.html#Change-Detection-Caveats
I would like to add that it is probably not a good idea to mutate myHandle as a prop, so I suggest that if you can refactor your code to use myHandle as a data property, to do so.
I hope this example will help you
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app">
<my-ponent :myhandle="myhandle">
</my-ponent>
<h2>Vue app Object: {{myhandle.name}}</h2>
</div>
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<script>
Vue.ponent('my-ponent', Vue.extend({
props: ["myhandle"],
data () {
return {
name:""
}
},
watch: {
myhandle:{
handler (val, oldVal) {
console.log('Prop changed');
// do your stuff
},
deep: true, // nested data
}
},
methods: {
chName(){
this.myhandle.name = "Henry";
}
},
template:'<div><h1>{{myhandle.name }}</h1><br><button @click="chName()">Cahnge name</button></div>',
}),
);
var app = new Vue({
el:'#app',
data (){
return {
myhandle:{
name:'Jack'
}
}
}
});
</script>
</body>
</html>
There is a simple trick - dummy_toogle - just place it in your ponent data: {toggle:false} and in your getter/setter: get: function(){this.toggle; ... } set:function(name){...; this.toggle=!this.toggle;} Now vue will think that puted property is dependent on the toggle and repute it if toggle is changed + you can make a very stupid callback and pass it to non-vue part of your app as update-trigger
本文标签: javascriptVueJs make computed property reactiveStack Overflow
版权声明:本文标题:javascript - VueJs make computed property reactive - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741534073a2383928.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论