Vue.js注意mounted不保证所有子组件也都挂载了吗?
Vue.js Note that mounted does not guarantee that all child components have also been mounted?
有人可以从 VUE 文档 https://vuejs.org/v2/api/#mounted 解释下面的通知吗?
Note that mounted does not guarantee that all child components have also been mounted.
我已经测试了安装子项和子项,但它们总是在 root/app 组件之前安装,因此在没有 $nextTick 访问 DOM 的情况下使用 "mounted" 是安全的。子组件和子组件可以访问 root/app 模板中的 DOM 元素,尽管它安装在子组件之后。另一方面 root/app 也可以访问子模板中的 DOM 元素。考虑这个例子...
<div id="app">
{{ message }}
<child></child>
<span id="root"></span>
</div>
<script type="text/javascript">
var subchild = {
template: `<div>SUBCHILD<span id="subchild"></span></div>`,
mounted() {
console.log("Mounted SUBCHILD", document.getElementById('root'));
}
};
var child = {
template: `<div>CHILD<span id="child"></span><subchild></subchild></div>`,
components : { subchild },
mounted() {
console.log("Mounted CHILD", document.getElementById('root'));
}
};
var app = new Vue({
el: '#app',
components : { child },
data() {
return { message: 'APP' };
},
mounted() {
console.log("Mounted APP", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
})
</script>
https://jsfiddle.net/ecobyxrn/
控制台输出...
Mounted SUBCHILD [object HTMLSpan...] [object HTMLSpan...] [object HTMLSpan...]
Mounted CHILD [object HTMLSpan...] [object HTMLSpan...] [object HTMLSpan...]
Mounted APP [object HTMLSpan...] [object HTMLSpan...] [object HTMLSpan...]
因此,就我而言,我不理解 VUE 通知。有人可以展示在 root/app 之后安装子项的用例吗?我觉得VUE doc很差,解释的不是很好。我还尝试通过注释掉 el: '#app'
+ 添加 setTimeout(function() { app.$mount('#app'); }, 2000);
来延迟安装 root/app 但结果是一样的。
另外看这张图...
图片来源:https://medium.com/@brockreece/vue-parent-and-child-lifecycle-hooks-5d6236bd561f
在源页面,有人在评论中警告图像作者提到的 VUE 通知,但没有解释。那个通知好像大家都知道,但是没人解释。
如@RandyCasburn 所述,组件可以异步加载。 components
对象的每个 属性 可以被赋予一个组件定义对象,或者一个 Promise
最终解析为一个组件定义对象。因此,在这些情况下,可能是在异步加载的子组件完成加载之前调用了父组件的 mounted
挂钩。
作为对此的简单测试,您可以更改基本组件的 component
对象以在延迟后加载 child
组件:
components: {
child: () => new Promise((resolve) => {
setTimeout(() => {
resolve(child)
}, 2000)
})
}
您会看到 mounted
挂钩中对子组件的引用在触发时是 null
。
Vue 文档没有提到这是他们警告的场景的潜在原因,这似乎没有帮助。而且,除了使用异步组件之外,我想不出另一种情况,即当父组件的 mounted
钩子被触发时子组件不会被挂载。
这是使用您的代码的完整示例:
Vue.config.productionTip = false
var subchild = {
template: `<div>SUBCHILD<span id="subchild"></span></div>`,
mounted() {
console.log("Mounted SUBCHILD", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
};
var child = {
template: `<div>CHILD<span id="child"></span><subchild></subchild></div>`,
components : { subchild: () => new Promise((resolve) => {
setTimeout(() => {
resolve(subchild)
}, 2000)
}) },
mounted() {
console.log("Mounted CHILD", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
};
var app = new Vue({
el: '#app',
components : { child: () => new Promise((resolve) => {
setTimeout(() => {
resolve(child)
}, 2000)
}) },
data() {
return { message: 'APP' };
},
mounted() {
console.log("Mounted APP", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
{{ message }}
<child ref="child"></child>
<span id="root"></span>
</div>
有人可以从 VUE 文档 https://vuejs.org/v2/api/#mounted 解释下面的通知吗?
Note that mounted does not guarantee that all child components have also been mounted.
我已经测试了安装子项和子项,但它们总是在 root/app 组件之前安装,因此在没有 $nextTick 访问 DOM 的情况下使用 "mounted" 是安全的。子组件和子组件可以访问 root/app 模板中的 DOM 元素,尽管它安装在子组件之后。另一方面 root/app 也可以访问子模板中的 DOM 元素。考虑这个例子...
<div id="app">
{{ message }}
<child></child>
<span id="root"></span>
</div>
<script type="text/javascript">
var subchild = {
template: `<div>SUBCHILD<span id="subchild"></span></div>`,
mounted() {
console.log("Mounted SUBCHILD", document.getElementById('root'));
}
};
var child = {
template: `<div>CHILD<span id="child"></span><subchild></subchild></div>`,
components : { subchild },
mounted() {
console.log("Mounted CHILD", document.getElementById('root'));
}
};
var app = new Vue({
el: '#app',
components : { child },
data() {
return { message: 'APP' };
},
mounted() {
console.log("Mounted APP", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
})
</script>
https://jsfiddle.net/ecobyxrn/
控制台输出...
Mounted SUBCHILD [object HTMLSpan...] [object HTMLSpan...] [object HTMLSpan...]
Mounted CHILD [object HTMLSpan...] [object HTMLSpan...] [object HTMLSpan...]
Mounted APP [object HTMLSpan...] [object HTMLSpan...] [object HTMLSpan...]
因此,就我而言,我不理解 VUE 通知。有人可以展示在 root/app 之后安装子项的用例吗?我觉得VUE doc很差,解释的不是很好。我还尝试通过注释掉 el: '#app'
+ 添加 setTimeout(function() { app.$mount('#app'); }, 2000);
来延迟安装 root/app 但结果是一样的。
另外看这张图...
图片来源:https://medium.com/@brockreece/vue-parent-and-child-lifecycle-hooks-5d6236bd561f
在源页面,有人在评论中警告图像作者提到的 VUE 通知,但没有解释。那个通知好像大家都知道,但是没人解释。
如@RandyCasburn 所述,组件可以异步加载。 components
对象的每个 属性 可以被赋予一个组件定义对象,或者一个 Promise
最终解析为一个组件定义对象。因此,在这些情况下,可能是在异步加载的子组件完成加载之前调用了父组件的 mounted
挂钩。
作为对此的简单测试,您可以更改基本组件的 component
对象以在延迟后加载 child
组件:
components: {
child: () => new Promise((resolve) => {
setTimeout(() => {
resolve(child)
}, 2000)
})
}
您会看到 mounted
挂钩中对子组件的引用在触发时是 null
。
Vue 文档没有提到这是他们警告的场景的潜在原因,这似乎没有帮助。而且,除了使用异步组件之外,我想不出另一种情况,即当父组件的 mounted
钩子被触发时子组件不会被挂载。
这是使用您的代码的完整示例:
Vue.config.productionTip = false
var subchild = {
template: `<div>SUBCHILD<span id="subchild"></span></div>`,
mounted() {
console.log("Mounted SUBCHILD", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
};
var child = {
template: `<div>CHILD<span id="child"></span><subchild></subchild></div>`,
components : { subchild: () => new Promise((resolve) => {
setTimeout(() => {
resolve(subchild)
}, 2000)
}) },
mounted() {
console.log("Mounted CHILD", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
};
var app = new Vue({
el: '#app',
components : { child: () => new Promise((resolve) => {
setTimeout(() => {
resolve(child)
}, 2000)
}) },
data() {
return { message: 'APP' };
},
mounted() {
console.log("Mounted APP", document.getElementById('root'), document.getElementById('child'), document.getElementById('subchild'));
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
{{ message }}
<child ref="child"></child>
<span id="root"></span>
</div>