ref引用信息
理想状态下并不需要访问实例,只要关心数据就行了
但是当项目越来越复杂,难免会有访问组件实例的场景
<!-- `vm.$refs.p` 是DOM节点 -->
<p ref="p">hello</p>
<!-- `vm.$refs.child` 是子组件实例 -->
<child-component ref="child"></child-component>
不要通过层层递归向上或向下引用的方式去访问实例
更建议通过 callback ref 的方式去访问实例
- 主动通知(setXxxRef)
- 主动获取(getXxxRef)
index.vue
<template>
<div>
<ChildrenA />
</div>
</template>
<script>
import ChildrenA from "./ChildrenA";
export default {
components: {
ChildrenA
}
};
</script>
<style>
.border,
.border1,
.border2 {
border: 1px solid #000;
padding: 10px 0;
margin: 10px 10px 0;
}
.border1 {
border-color: #ccc;
}
.border2 {
border-color: #eee;
}
</style>
ChildrenA.vue
<template>
<div class="border">
<h1>A 结点</h1>
<button @click="getEH3Ref">获取E h3 Ref</button>
<ChildrenB />
<ChildrenC />
<ChildrenD />
</div>
</template>
<script>
import ChildrenB from "./ChildrenB";
import ChildrenC from "./ChildrenC";
import ChildrenD from "./ChildrenD";
export default {
components: {
ChildrenB,
ChildrenC,
ChildrenD
},
provide() {
return {
setChildrenRef: (name, ref) => {
this[name] = ref;
},
getChildrenRef: name => {
return this[name];
},
getRef: () => {
return this;
}
};
},
data() {
return {
color: "blue"
};
},
methods: {
getEH3Ref() {
console.log(this.childrenE);
}
}
};
</script>
ChildrenB.vue
<template functional>
<div class="border1">
<h2>B 结点</h2>
</div>
</template>
ChildrenC.vue
<template>
<div class="border1">
<h2>C 结点</h2>
<ChildrenE />
<ChildrenF />
</div>
</template>
<script>
import ChildrenE from "./ChildrenE";
import ChildrenF from "./ChildrenF";
export default {
components: {
ChildrenE,
ChildrenF
}
};
</script>
ChildrenD.vue
<template>
<div class="border1">
<h2>D 结点</h2>
<ChildrenG />
<ChildrenH v-ant-ref="c => setChildrenRef('childrenH', c)" />
<ChildrenI />
</div>
</template>
<script>
import ChildrenG from "./ChildrenG";
import ChildrenH from "./ChildrenH";
import ChildrenI from "./ChildrenI";
export default {
components: {
ChildrenG,
ChildrenH,
ChildrenI
},
inject: {
setChildrenRef: {
default: () => {}
}
}
};
</script>
ChildrenE.vue
<template>
<div class="border2">
<h3 v-ant-ref="c => setChildrenRef('childrenE', c)">
E 结点
</h3>
</div>
</template>
<script>
export default {
components: {},
inject: {
setChildrenRef: {
default: () => {}
}
}
};
</script>
ChildrenF.vue
<template>
<div class="border2">
<h3>F 结点</h3>
<button @click="getARef">获取A Ref</button>
<button @click="getHRef">获取H Ref</button>
</div>
</template>
<script>
export default {
components: {},
inject: {
getParentRef: {
from: "getRef",
default: () => {}
},
getParentChildrenRef: {
from: "getChildrenRef",
default: () => {}
}
},
methods: {
getARef() {
console.log(this.getParentRef());
},
getHRef() {
console.log(this.getParentChildrenRef("childrenH"));
}
}
};
</script>
ChildrenG.vue
<template>
<div class="border2">
<h3>G 结点</h3>
</div>
</template>
<script>
export default {};
</script>
ChildrenH.vue
<template>
<div class="border2">
<h3>H 结点</h3>
</div>
</template>
<script>
export default {};
</script>
ChildrenI.vue
<template functional>
<div class="border2">
<h3 :style="{ color: injections.theme.color }">I 结点</h3>
</div>
</template>
<script>
export default {
inject: {
theme: {
default: () => ({})
}
}
};
</script>