我有一个像这样的VueJS组件
const MyComponent = Vue.extend({
props: ["myHandle"],
computed: {
name: {
get: function() { return myHandle.getName() },
set: function(newName) { myHandle.setName(newName) },
}
}
})
问题在于,设置计算属性name
不会触发VueJ更新属性。意思是旧名称是重新渲染时显示的内容。
现在,我对VueJS还是相当陌生,我可以看到这可能是代码的味道,但事实是myHandle
属性实际上是访问以rust编写的WebAssembly模块中的数据的句柄。锈代码是我大多数状态/模型/ 真理之源的住所。
到目前为止,我发现的两个不令人满意的解决方案是:
使用一种方法而不是计算属性来检索名称。基本上向我的组件添加一个getName
方法,并将模板代码从<p> Your name is {{ name }}</p>
更改为<p> Your name is {{ getName() }}</p>
。这将导致VueJ无法缓存。将来我打算进行昂贵的计算,这意味着不必要的性能成本
将状态从生锈的一侧复制到我的组件。我不想这样做,因为我会得到多个事实来源。
那么有什么方法可以做到:
A :让VueJS了解myHandle.setName
是一种变异方法,该方法应导致name
计算属性得到更新。
B :手动触发更新。
C 是否以其他方式解决?
答案 0 :(得分:2)
我不知道您对setName()的实现如何,但是如果是这样的话
setName(newName) { this.name = newName; }
您可能遇到了此处描述的问题: https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
我想补充一点,将myHandle用作道具可能不是一个好主意,因此我建议,如果可以重构代码以将myHandle用作数据属性,则可以这样做。
答案 1 :(得分:0)
我希望这个例子对您有帮助
<!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-component :myhandle="myhandle">
</my-component>
<h2>Vue app Object: {{myhandle.name}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>
<script>
Vue.component('my-component', 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>
答案 2 :(得分:0)
基于计算属性的依赖关系(数据,属性和其他计算属性)进行缓存。如果我正确理解,则您的计算属性将不会是反应性的,因为唯一的依赖关系是myHandle,并且我认为这永远不会改变。这样看,Vue只能通过实际调用方法来检查getName是否返回了不同的值,因此没有要缓存的内容。
如果只能从Vue组件更改名称,则可以将其设置为数据字段,并添加观察程序以更新WebAssembly值。否则,如果可以从非Vue来源更改名称,并且每次都必须从处理程序调用getName方法,则必须提出自己的机制(也许使用去抖动功能来限制调用次数)。
答案 3 :(得分:0)
有一个简单的技巧-dummy_toogle-只需将其放在您的组件数据中即可:{toggle:false} 在您的getter / setter中: 得到:function(){this.toggle; ...} 设置:功能(名称){...; this.toggle =!this.toggle;} 现在vue会认为计算属性取决于切换,如果切换被更改,则重新计算它+您可以进行非常愚蠢的回调并将其作为update-trigger传递给应用的非vue部分