1.前言Vue的父子组件之间的通信是什么?:prop和$emit的组合。如果它是祖父母组件怎么办?:然后使用父组件转发数据和事件。爷孙组件呢?:当然是vuexemmmok,我没事,我先走了。不行,我还能挣扎一阵子!肯定有一些兄弟项目比较小,组件通信的情况不多。他们懒得引入vuex,所以provide/inject是祖辈之间沟通问题的最佳解决方案(不限于孙子/父子,不管中间有多少层级)。计划吧!2.复制自官方文档的介绍这对选项需要配合使用才能让一个祖先组件对它所有的后代组件注入一个依赖,不管这个组件层级有多深,并且一直在上游时生效并建立下游关系。provide选项应该是一个对象或一个返回对象的函数。该对象包含可以注入其后代的属性。您可以使用ES2015Symbols作为此对象中的键,但这仅适用于本机支持Symbol和Reflect.ownKeys的环境。inject选项应该是:一个字符串数组,或者一个对象(详情点这里)3.基本用法//祖先组件提供foo//第一种exportdefault{name:"grandfather",provide(){return{foo:'halo'}},}//第二种exportdefault{name:"grandfather",provide:{foo:'halo~~~~'},}//后代组件注入fooexportdefault{inject:['foo'],}以上两种用法有区别吗?如果你只是传递一个字符串,像上面的'halo',那么就没有区别,后人也能读懂。如果需要传递一个对象(如下代码所示),那么第二个方法就不能传递,子孙组件就无法获取到数据。所以建议只写第一种类型//传递对象给后代时provide(){return{test:this.msg}}注意:一旦注入了某个数据,比如上例中的foo,那么在这个组件中就不能再声明foo的数据了,因为它已经被parent拥有了。4.什么时候响应?如果你用过vuex,那么你会想,在上面的例子中,如果我把foo:'halo'改成foo:'world',子组件会及时响应数据变化,视图也会更新。遗憾的是,在vue官方文档中并没有这样一句话:provideandinjectbindingsarenotresponsive。这是故意的。但是,如果你传入一个listenable对象,它的属性仍然是响应式的。这里不讨论vue为什么要这样设计。我只显示何时提供/注入可以响应)=>{this.msg="haloworld";console.log(this._provided.msg)//log:WelcometoYourVue.jsApp},3000)},如上所示,这是不行的,打印出来的provided中的数据没有变化,子组件获取的值也没有变化。甚至可以直接给this._provided.msg赋值,但是即使_provided.msg中的值发生变化,子组件的值还是保持不变。当你喜欢下面的时候,你可以响应provide(){return{test:this.activeData}},data(){return{activeData:{name:'halo'},}}mounted(){setTimeout(()=>{this.activeData.name='world';},3000)}这个是vue写的对象的属性是响应式的。但是,如果你传入一个可监听的对象,那么它的对象属性仍然是响应式的。5.实现全局变量全局变量?provide/inject不是只从祖先传递给后代吗?没错,我们只需要绑定到最顶层的组件即可。是你!我们将整个app.vue实例扔给后代!//app.vueexportdefault{name:'App',provide(){return{app:this}},data(){return{text:"白天黑夜难分"}},methods:{say(){console.log("Desperado,whydon'tyoucometoyoursenses?")}}}//所有其??他需要全局变量的子组件只能按需注入app。exportdefault{inject:['foo','app'],mounted(){console.log(this.app.text);//获取app中的变量this.app.say();//可以执行app中的方法,变成了全局方法!}}这个也是响应式的~6.实现页面刷新1.使用vue-router重新路由到当前页面,页面不会刷新2.使用window.reload(),或者router.go(0)进行刷新,整个浏览器都重新加载了,闪烁,体验不好,怎么办?类似上面的原理,我们只在组件中写一个控制路由的函数(使用v-if控制router-view的显示和隐藏,这里原理不再赘述),然后将这个函数传递给后代,然后在后代组件中调用该方法刷新路由。//app.vue
