注意以下3个属性:component、children、type
- 代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<h1>Hello Vue</h1>
<p>{{msg}}</p>
<comp-a></comp-a>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script>
// 参考网址: https://juejin.cn/post/6947967614194810893
const compA = {
template: `<p>{{msga}} <comp-b/><comp-c/></p> <div>div</div>`,
data() {
return {
msga: "I am compA"
}
}
}
const compB = {
template: `<p>{{msgb}}</p>`,
data() {
return {
msgb: "I am compB"
}
}
}
const compC = {
template: `<p>I am compC</p>`
}
const app = Vue.createApp({
data() {
return {
msg:'I am app'
}
}
})
app.component('compA',compA);
app.component('compB',compB);
app.component('compC',compC);
console.log(app,"app")
app.mount("#app")
const findComponent = (comp,{within}) => {
const result = find([within.$],comp)
if(result) {
return result
}
}
function find(vnodes, target) {
debugger
if (!Array.isArray(vnodes)) {
return
}
return vnodes.reduce((acc, vnode) => {
if (matches(vnode, target)) {
return vnode
}
if (vnode?.subTree?.children) {
return find(vnode.subTree.children, target)
}
if (vnode?.component?.subTree) {
return find(vnode.component.subTree.children, target)
}
return acc
}, {})
}
function matches(vnode, target) {
return vnode?.type === target
}
const component = findComponent(compA, { within: app })
console.log(component,"component")
</script>
</body>
</html>
app的打印结果
- 第一个
children=>h1打印结果
componentA对象打印结果
componentA中subtree的children
children-1: p标签包含的内容
children-2:空格符串 (对应 p标签 和 div 标签之间的 空格)
children-3: div标签
- 包含组件的
p标签展开的结果
children-1: msg => I am compA
children-2: compB 对象
children-3: compC 对象
- compB 对象下
component展开
- compB 对象
component属性subtree展开