Cod*_*iwi 12 javascript vue.js vue-reactivity vuejs3 vue-composition-api
代码笔:https ://codepen.io/codingkiwi_/pen/XWMBRpW
假设你有一堂课:
class MyClass {
constructor(){
this.entries = ["a"];
//=== example change triggered from INSIDE the class ===
setTimeout(() => {
this.entries.push("c");
}, 1000);
}
}
Run Code Online (Sandbox Code Playgroud)
在组件中,您可以获得该类的一个实例:
const { reactive } = Vue;
const App = {
setup() {
const myobject = reactive(new MyClass());
//=== example change triggered from OUTSIDE the class ===
setTimeout(() => {
myobject.entries.push("b");
}, 500);
return {
myobject
};
}
}
Run Code Online (Sandbox Code Playgroud)
DOM 中的 myobject.entries 数组将显示条目"a"和"b",但不显示"c"
正如另一个答案所解释的,reactive创建代理对象以启用反应性。this构造函数中引用原始MyClass实例而不是代理,因此它不能是反应性的。
这表明代码中存在问题。reactive考虑MyClass构造函数中发生的同步操作。在构造函数中执行异步副作用是一种反模式,原因包括使用此类构造函数的代码可能产生的影响。
这可以通过以下方法解决:
class MyClass {
constructor(){
// synchronous stuff only
this.entries = ["a"];
}
init() {
// asynchronous stuff, probably return a promise
setTimeout(() => {
this.entries.push("c");
}, 1000);
}
}
Run Code Online (Sandbox Code Playgroud)
和
const myobject = reactive(new MyClass());
myobject.init() // `this` is a proxy inside `init`
Run Code Online (Sandbox Code Playgroud)
DOM 中的 myobject.entries 数组将显示条目
"a"和"b",但不显示"c"
这是因为"a"当我们使实例具有反应性时, 已经在数组中,并且"b"通过代理从对象外部进行推送。
需要明确的是:const myobject不包含MyClass实例,它包含一个Proxy处理/包装原始实例的实例!它是传递给 DOM/模板的代理。
推送是"c"从对象内部发生的,而不是通过代理。所以"c"将被推送到数组,但不会触发任何反应性更改。
显式标记我们从类内部更改的数组,如下所示reactive:
class MyClass {
constructor(){
this.entries = reactive(["a"]);
//=== example change triggered from INSIDE the class ===
setTimeout(() => {
this.entries.push("c");
}, 1000);
}
}
Run Code Online (Sandbox Code Playgroud)
或者尝试仅使用代理对象,如文档建议的那样:
这里的最佳实践是永远不要保留对原始原始对象的引用,而只使用反应版本:
文档:https://v3.vuejs.org/guide/reactivity.html#proxy-vs-original-identity
| 归档时间: |
|
| 查看次数: |
10331 次 |
| 最近记录: |