【Vue 开发实战】学习笔记。
比如E节点更新就通知A组件,A组件进行ref的缓存即可
组件A
<template>
<div class="border">
<h1>A 结点h1>
<button @click="getHRef">获取子孙节点 E Refbutton>
<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) => {
console.log("A 组件 setChildrenRef", name);
this[name] = ref;
},
getChildrenRef: name => {
console.log("A 组件 getChildrenRef", name);
return this[name];
},
getRef: () => {
console.log("A 组件 getRef");
return this;
}
};
},
data() {
return {
color: "blue"
};
},
methods: {
getHRef() {
console.log(this.childrenE);
}
}
};
script>
组件D
<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>
组件E
<template>
<div class="border2">
<h3 v-ant-ref="c => setChildrenRef('childrenE', c)">
E 结点
h3>
div>
template>
<script>
export default {
components: {},
inject: {
setChildrenRef: {
default: () => {}
}
}
};
script>
组件F
<template>
<div class="border2">
<h3>F 结点h3>
<button @click="getARef">获取祖先节点 A Refbutton>
<button @click="getHRef">获取同级节点 H Refbutton>
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>
然后点击三个按钮
这里面使用了 v-ant-ref
这个指令,用于通知上层节点更新。我们可以找一下依赖 vue-ref 这个包,看一下指令源码
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = {
install: function install(Vue) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var directiveName = options.name || 'ref';
Vue.directive(directiveName, {
bind: function bind(el, binding, vnode) {
binding.value(vnode.componentInstance || el, vnode.key);
},
update: function update(el, binding, vnode, oldVnode) {
if (oldVnode.data && oldVnode.data.directives) {
var oldBinding = oldVnode.data.directives.find(function (directive) {
var name = directive.name;
return name === directiveName;
});
if (oldBinding && oldBinding.value !== binding.value) {
oldBinding && oldBinding.value(null, oldVnode.key);
binding.value(vnode.componentInstance || el, vnode.key);
return;
}
}
// Should not have this situation
if (vnode.componentInstance !== oldVnode.componentInstance || vnode.elm !== oldVnode.elm) {
binding.value(vnode.componentInstance || el, vnode.key);
}
},
unbind: function unbind(el, binding, vnode) {
binding.value(null, vnode.key);
}
});
}
};
完整demo源码可以参考这个https://github.com/kaimo313/vue-development-practice/tree/master/vue-demo/src/views/demo13