文章目录

  • 前言
  • 一、Vue组件关系
  • 二、Vue组件通信方式
    • 1. props / $emit
      • 1.1 props 父传子
      • 1.2 $emit 子传父
      • 1.3 父子组件双向绑定
        • 1.3.1 v-model
        • 1.3.2 .sync
    • 2. $parent / $children
      • 2.1 $parent / $children
      • 2.2 $dispatch / $broadcast
    • 3. $attrs / $listeners
    • 4. provide / inject
      • 4.1 provide / inject 使用方法
      • 4.2 实现 provide / inject 数据响应式
    • 5. ref
    • 6. EventBus
    • 7. Vuex
    • 8. localStorage / sessionStorage
  • 三、总结
  • 四、其他
  • 参考文章

前言

组件(Component)是 Vue 最核心的功能,也是整个框架设计最出彩的地方,而组件实例的作用域是相互独立的,也就是说不同组件间的数据是无法直接互相引用的。那么,组件之间是如何进行通信传递数据的呢?这就需要我们先搞清楚组件之间的关系:

一、Vue组件关系


如上图所示,组件间的关系有:

  • 父子关系:A与B、A与C、B与D、C与E
  • 兄弟关系:B与C
  • 隔代关系(可能隔多代):A与D、A与E
  • 非直系亲属关系:D与E

以上关系可总结为三大类:父子组件通信、兄弟组件通信、跨级组件通信。

二、Vue组件通信方式

Vue组件的通信方式,总结起来有以下8种:

1. props / $emit

1.1 props 父传子

父组件向子组件传递数据或参数,是通过 props 来实现的。在父组件中在自定义的子组件标签上添加要传递的 props 的名称及数据(可通过v-bind动态绑定props的值),而子组件通过选项 props 来声明需要从父组件接收的数据,props 的值分为两种:一种是字符串数组,一种是对象(当prop需要验证时使用,推荐)。

<!--parent.vue-->
<template><div><!--props的值可以直接传递也可以动态绑定--><child message1="我是父组件直接传递的数据" :message2="message"></child></div>
</template><script>import child from "./child"export default {name: 'parent',components: {child},data() {return {message: ['我是父组件动态绑定传递的数据1', '我是父组件动态绑定传递的数据2', '我是父组件动态绑定传递的数据3']}}}
</script>
 <!--child.vue-->
<template><div><p>{{message1}}</p><ul><li v-for="(item,index) in message2" :key=index>{{item}}</li></ul></div>
</template><script>export default {name: 'child',//props: ['message1', 'message2'], //props的第一种:字符串数组props: {//props的第二种:对象message1: {type: String,default: ''},message2: {type: Array,default: () => []}},data() {return {}}}
</script>

1.2 $emit 子传父

通过props传递数据是单向的,父组件数据变化时会传递给子组件,但子组件不能通过修改props传过来的数据来修改父组件的相应状态,即所谓的单向数据流。因为这种特性,子组件需要向父组件传递数据时,就要用到自定义事件。子组件用 $emit() 来出发事件,父组件用 $on() 来监听子组件的事件,也可以直接在子组件的自定义标签上使用v-on来监听子组件触发的自定义事件。

<!--parent.vue-->
<template><div><p>{{parentData}}</p><!--在子组件自定义标签上用v-on(此处用的语法糖@)监听子组件触发的自定义事件clickEvent--><child @clickEvent='parentClickEvent'></child></div>
</template><script>import child from "./child"export default {name: 'parent',components: {child},data() {return {parentData: '父组件本来的数据'}},methods: {parentClickEvent(val) {this.parentData = val; //val是子组件传递过来的数据}}}
</script>
<!--child.vue-->
<template><button @click="childClickEvent">点击修改父组件数据</button>
</template><script>export default {name: 'child',data() {return {}},methods: {childClickEvent() {//$emit方法第一个参数是自定义事件(clickEvent),后面的参数都是要传递的数据,可以不填或填写多个this.$emit('clickEvent', '子组件向父组件传递的数据');}}}
</script>

1.3 父子组件双向绑定

1.3.1 v-model

Vue 2.X 可以在自定义组件上使用 v-model 指令,实现父子组件之间的通信,该方式与上面介绍的方式类似,是一个语法糖。父组件通过 v-model 向子组件传递数据时,会自动传递一个 valueprop 属性,而子组件通过 this.$emit('input',val) 自动修改 v-model 绑定的值。

<!--parent.vue-->
<template><div><h2>我是父组件</h2><p>我是父组件的数据:{{pData}}</p><child v-model="pData"></child></div>
</template>
<script>import child from './child'export default {name: 'parent',components: {child},data() {return {pData: '我是父组件的数据'}}}
</script>
<!--child.vue-->
<template><div><h2>我是子组件</h2><p>我是子组件的数据: {{cData}}</p><p>我是父组件传递过来的数据: {{msg}}</p><button @click="handleClick">点击传递子组件数据给父组件</button></div>
</template>
<script>export default {name: 'child',props: ['value'],//v-model 会自动传递一个字段为 value 的 props 属性data() {return {msg: this.value,cData: '我是子组件的数据'}},methods: {handleClick() {this.$emit('input', this.cData);//通过emit特定的input事件可以改变父组件上v-model绑定的值}}}
</script>

1.3.2 .sync

某些情况下,我们需要实现某个 prop 的双向绑定,而真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,且在父子组件中都没有明显的改动来源,所以官方推荐以 update:my-prop-name 的模式触发事件实现 “上行绑定“” 最终实现 “双向绑定“。而 .sync 是一个编译时的语法糖,它会被自动扩展为一个自动更新父组件属性的 v-on 监听器。如:<child :abc.sync=”msg”></child> 就会被扩展为: <child :abc=”data” @update:abc=”val => data= val”>@v-on 的简写)。当子组件需要更新 abc 的值的时候,他需要显示的触发一个更新事件:this.$emit( “update:abc”, newValue )。当使用一个对象一次性设置多个属性的时候,这个 .sync 修饰符也可以和 v-bind 一起使用。如:<child v-bind.sync = “{ a: data1, b: data2}”></child> (不能写成 :.sync=...,否则会报错),这样会为 ab 同时添加用于更新的 v-on 监听器。

<!--parent.vue-->
<template><div><h2>我是父组件</h2><p>我是父组件的数据(单属性):{{pData}}</p><p>我是父组件的数据(多属性):{{myProps.a1}},{{myProps.a2}}</p><!--1.单个属性传递--><child :abc.sync="pData" :ifShow="true"></child><!-- <child :abc="pData" @update:abc="val=>pData= val"></child> 上面会自动扩展为该形式--><!--2.多个属性传递--><child v-bind.sync="myProps" :ifShow="false"></child> <!-- 不能写成字面量形式如 v-bind.sync="{ a1: '我是父组件的pData1', a2: '我是父组件的pData2'}"--></div>
</template>
<script>import child from './child'export default {name: 'parent',components: {child},data() {return {pData: 'Hi!我是父组件!',myProps: { a1: '我是父组件的pData1', a2: '我是父组件的pData2' }}}}
</script>
<!--child.vue-->
<template><div><h2>我是子组件</h2><p v-if="ifShow">我是子组件接收到的父组件单个属性:{{abc}}</p><p v-else>我是子组件接收到的父组件的多个属性:{{a1}},{{a2}}</p><button @click="handleClick">点击传递子组件数据给父组件</button></div>
</template>
<script>export default {name: 'child',props: ['ifShow', 'abc', 'a1', 'a2'],data() {return {cData: 'Hi!我是子组件!'}},methods: {handleClick() {this.$emit("update:abc", this.cData);this.$emit("update:a1", this.cData);this.$emit("update:a2", this.cData);}}}
</script>

如果你只是单纯的在子组件中修改父组件的某个数据,建议使用.sync

注意:将 v-bind.sync 用在一个字面量的对象上,例如v-bind.sync=”{ title: doc.title
}”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。

v-model.sync 都可以实现 props 的双向绑定,但是 v-model 有局限性,只能传递 value 属性,而 .sync 可以传递其他的属性值。

2. $parent / $children

2.1 $parent / $children

子组件使用 $parent 可以直接访问父组件的实例(对象),而父组件通过 $children 可以访问所有的子组件实例(数组),并且可以递归向上或向下无限访问,直到根实例或最内层组件。虽然 Vue 允许这样操作,但在实际处理中,不建议这么做,因为这样会使父子组件紧耦合,而且会使父组件的状态因为可能被任意组件修改而难以理解。

<!--parent.vue-->
<template><div><child></child><button @click="parentClickEvent">点击修改子组件数据</button></div>
</template><script>import child from "./child"export default {name: 'parent',components: {child},data() {return {parentData: '父组件的数据'}},methods: {parentClickEvent() {this.$children[0].childData = '这是父组件修改的子组件数据';}}}
</script>
<!--child.vue-->
<template><div><p>子组件数据:{{childData}}</p><p>子组件获取的父组件数据:{{parentData}}</p></div>
</template><script>export default {name: 'child',data() {return {childData: '子组件的数据'}},computed: {parentData() {return this.$parent.parentData;}}}
</script>

2.2 $dispatch / $broadcast

这也是一组成对出现的方法,在 Vue2.0 中被废弃了,但是还是有很多开源软件自己封装了这种组件通信方式,如 Mint UI、Element UI 和 iView 等,可以解决父子组件、嵌套父子组件的通信。核心是向上寻找 $parent 和遍历 $children,使用 $on$emit 进行事件的监听和调用。通过 $dispatch$broadcast 定向的向某个父或者子组件远程调用事件,这样就避免了通过传 props 或者使用 refs 调用组件实例方法的操作。

//main.js
import Vue from 'vue'
import parent from './parent'//在Vue的原型上添加$dispatch方法,通过this.$dispatch调用
Vue.prototype.$dispatch = function (eventName, params) {let parent = this.$parent;while (parent) {parent.$emit(eventName, params);parent = parent.$parent;}
};//在Vue的原型上添加$broadcast方法,通过this.$broadcast调用
Vue.prototype.$broadcast = function (eventName, params) {//获取当前组件下所有的子孙组件,递归调用const boradcast = children => {children.forEach(child => {child.$emit(eventName, params);if (child.$children) {boradcast(child.$children);}});}boradcast(this.$children);
};new Vue({render: h => h(parent)
}).$mount("#app")
<!--parent.vue-->
<template><div><h2>我是parent.vue</h2><p>parent组件:{{pData}}</p><button @click="clickEvent">所有子孙组件(-100)</button><child></child></div>
</template>
<script>import child from './child'export default {name: 'parent',components: {child},data() {return {pData: 100}},methods: {test(val) {this.pData += val;},clickEvent() {this.$broadcast('broadcastEvent', -100);//向所有子孙广播}},mounted() {this.$on('dispatchEvent', this.test);//用$on监听}}
</script>
<!--child.vue-->
<template><div><h2>我是child.vue</h2><p>child组件:{{cData}}</p><grandson></grandson></div>
</template>
<script>import grandson from './grandson'export default {name: 'child',components: {grandson},data() {return {cData: 200}},methods: {test(val) {this.cData += val;}},mounted() {this.$on('dispatchEvent', this.test);//用$on监听dispatchEventthis.$on('broadcastEvent', this.test);//用$on监听broadcastEvent},}
</script>
<!--grandson.vue-->
<template><div><h2>我是grandson.vue</h2><p>grandson组件:{{gData}}</p><button @click="clickEvent">所有祖先组件(+100)</button></div>
</template>
<script>export default {name: 'grandson',data() {return {gData: 100}},methods: {test(val) {this.gData += val;},clickEvent() {this.$dispatch('dispatchEvent', 100);//向所有的祖先派发}},mounted() {this.$on('broadcastEvent', this.test);//用$on监听broadcastEvent}}
</script>

3. $attrs / $listeners

对于隔代关系,如上图中父组件A和孙组件D之间想要传递数据,按照上面的方法,只能是在组件A,组件B,组件D这个链条中一级级使用 props$emit向下和向上进行数据传递,如果中间有更多的层级,这种方式就更加复杂难以维护。为此,Vue2.4 版本提供了 $attrs$listeners 来解决这种跨级通信的需求:

  • $attrs:包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。
  • $listeners :包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件。
<!--parent.vue-->
<template><div><child :a1="a1" :a2="a2" :a3="a3" :a4="a4" @click.native="clickEventNative" @click="clickEvent"@pEvent1="parentEvent1" @pEvent2="parentEvent2"></child></div>
</template><script>import child from "./child"export default {name: 'parent',components: {child},data() {return {a1: "我是parent属性1的数据",a2: "我是parent属性2的数据",a3: "我是parent属性3的数据",a4: "我是parent属性4的数据",}},methods: {clickEventNative() {console.log('我是parent的native事件');},clickEvent() {console.log('我是parent事件0');},parentEvent1() {console.log('我是parent事件1');},parentEvent2() {console.log('我是parent事件2');}}}
</script>
<!--child.vue-->
<template><div><p>child中接收到的a1: {{a1}}</p><p>child中接收到的$attrs: {{$attrs}}</p><grandson v-bind="$attrs" v-on="$listeners"></grandson></div>
</template><script>import grandson from './grandson'export default {name: 'child',components: {grandson},props: ['a1'],mounted() {console.log(this.$listeners);//{click: ƒ, pEvent1: ƒ, pEvent2: ƒ}this.$emit('pEvent1');//parent方法调用方式1},}
</script>
<!--grandson.vue-->
<template><div><p>grandson中接收到的a2: {{a2}}</p><p>grandson中接收到的a3: {{a3}}</p><p>grandson中接收到的$attrs: {{$attrs}}</p></div>
</template><script>import grandSon from './grandson'export default {name: 'child',inheritAttrs: false, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性props: ['a2', 'a3'],mounted() {this.$listeners.pEvent2();//parent方法调用方式2},}
</script>

运行结果:

例子中,给 grandson.vue 加上 inheritAttrs:false 属性前后如图所示:

4. provide / inject

4.1 provide / inject 使用方法

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。即,在父组件中通过 provider 来提供属性,然后在子组件中通过 inject 来注入变量。不论子组件有多深,只要调用了 inject 那么就可以注入在 provider 中提供的数据,只要在父组件的生命周期内,子组件都可以调用。

<!--parent.vue-->
<template><div><child></child></div>
</template><script>import child from "./child"export default {name: 'parent',components: {child},provide: {//provide选项可以是一个对象或返回一个对象的函数parentData: '我是父组件的数据'},}
</script>
<!--child.vue-->
<template><div>{{parentData}}</div>
</template><script>export default {name: 'child',inject: ['parentData']//injec选项可以是一个字符串数组或一个对象}
</script>

4.2 实现 provide / inject 数据响应式

provide 和 inject 绑定并不是可响应的,即修改了上例中 parent.vue 中的parentData,child.vue 中的 parentData 是不会改变的。要实现数据响应式,有两种方法:

  1. provide 祖先组件的实例,在后代组件中注入依赖。这样就可以在后代组件中直接修改祖先组件实例的属性。
  2. 使用 Vue. observable 优化响应式 provide(2.6新增API,推荐)
<!--parent.vue-->
<template><div><p>{{pData}}</p><child></child><button @click=changeData>改变parentData</button></div>
</template><script>import Vue from 'vue'import child from "./child"export default {name: 'parent',components: {child},data() {return {pData: '我是父组件数据'}},//初始用法        // provide() {//     return {//         parentData: this.pData,//该方式绑定的数据不是响应式的,即祖先组件中parentData变化,后代组件中不会跟着变//     }// },// methods: {//     changeData() {//         this.pData = "我是改变以后的父组件数据";//     }// }//方法一        // provide() {//     return {//         parentData: this,//provide祖先组件的实例//     }// },// methods: {//     changeData() {//         this.pData = "我是改变以后的父组件数据1";//     }// }//方法二       provide() {this.parentData = Vue.observable({pData: this.pData});return {parentData: this.parentData}},methods: {changeData() {this.parentData.pData = "我是改变以后的父组件数据2";}}}
</script>
<!--child.vue-->
<template><div>{{parentData.pData}}</div>
</template><script>export default {name: 'child',inject: {parentData: {default: () => { }}}}
</script>

另外, provideinject 主要为高阶插件/组件库提供用例,不推荐直接用于应用程序代码,可视情况采用。

5. ref

ref 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据。

<!--parent.vue-->
<template><div><p>我是父组件获取的子组件的数据:{{pData}}</p><child ref='compChild'></child></div>
</template>
<script>import child from './child'export default {name: 'parent',components: {child},data() {return {pData: ''}},methods: {parentEvent() {let compChild = this.$refs.compChild;//通过this.$refs获取子组件实例this.pData = compChild.childData;//获取子组件数据compChild.childEvent();//调用子组件方法}},mounted() {this.parentEvent();},}
</script>
<!--child.vue-->
<template><div></div>
</template>
<script>export default {name: 'child',data() {return {childData: '我是child的数据'}},methods: {childEvent() {console.log('我是child的方法');}}}
</script>

6. EventBus

中央事件总线(EventBus)可以巧妙而轻量地实现任何组件间的通信,包括父子、兄弟、跨级。如深入使用,可以扩展 bus 实例,给它添加 data、methods、computed 等选项,进行公用,业务中,一些需要共享的通用信息如用户登录信息,授权token等,只需在初始化时让 bus 获取一次,任何时间、组件就可以直接使用,在协同开发及单页应用(SPA)中特别实用。但是,当项目较大时,这种方式不太容易维护,可以选择后面要说的状态管理解决方案 Vuex。

//eventBus.js
import Vue from 'vue'
export const bus = new Vue();
<!--compA.vue-->
<template><div><comp-b></comp-b><comp-c></comp-c></div>
</template>
<script>import compB from './compB'import compC from './compC'export default {name: 'compA',components: {compB, compC}}
</script>
<!--compB.vue-->
<template><div><p>compB:{{dataB}}</p><button @click='handleEventB'>点击emit组件compB的数据</button></div>
</template>
<script>import { bus } from './eventBus'export default {name: 'compB',data() {return {dataB: '我是组件compB中的数据'}},methods: {handleEventB() {bus.$emit('on-msg', this.dataB);//发送事件}}}
</script>
<!--compC.vue-->
<template><div><p>{{dataC}}</p></div>
</template>
<script>import { bus } from './eventBus'export default {name: 'compC',data() {return {dataC: '我是组件compC中的数据'}},methods: {handleEventC() {//接收事件bus.$on('on-msg', val => {this.dataC = val;})}},mounted() {this.handleEventC();},beforeDestroy() {bus.$off('on-msg', {})//移除事件监听},}
</script>

7. Vuex

Vuex 是一个专为 Vue 服务,用于管理页面数据状态、提供统一数据操作的生态系统。它集中于 MVC 模式中的 Model 层,规定所有的数据操作必须通过 action - mutation - state change 的流程来进行,再结合 Vue 的数据视图双向绑定特性来实现页面的展示更新。

Vuex 各模块的主要功能:

  • Vue Components: Vue组件。HTML页面上,负责接收用户操作等交互行为,执行 dispatch 方法触发对应 action 进行回应。
  • dispatch: 操作行为触发方法,是唯一能执行 action 的方法。
  • actions: 操作行为处理模块。负责处理 Vue Components 接收到的所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。向后台API请求的操作就在这个模块中进行,包括触发其他 action 以及提交 mutation 的操作。该模块提供了 Promise 的封装,以支持 action 的链式触发。
  • commit: 状态改变提交操作方法。对 mutation 进行提交,是唯一能执行mutation 的方法。
  • mutations: 状态改变操作方法。是 Vuex 修改 state 的唯一推荐方法,其他修改方式在严格模式下将会报错。该方法只能进行同步操作,且方法名只能全局唯一。操作之中会有一些 hook 暴露出来,以进行 state 的监控等。
  • state: 页面状态管理容器对象。集中存储 Vue components 中 data 对象的零散数据,全局唯一,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取,利用 Vue 的细粒度数据响应机制来进行高效的状态更新。
  • getters: state 对象读取方法。图中没有单独列出该模块,应该被包含在了render 中,Vue Components 通过该方法读取全局state对象。

下面看个实例:

//main.js 入口文件
import Vue from 'vue'
import compA from './compA'
import store from './store';  //使用storeVue.config.productionTip = false;
new Vue({store,  //关联storerender: h => h(compA)
}).$mount("#app")
//store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {dataB: '',dataC: ''
}const mutations = {setDataB(state, data) {// 将compA组件的数据存放于statestate.dataB = data},setDataC(state, data) {// 将compB组件的数据存放于statestate.dataC = data}
}export default new Vuex.Store({state,mutations
})
<!--compA.vue-->
<template><div><comp-b></comp-b><comp-C></comp-c></div>
</template>
<script>import compB from './compB'import compC from './compC'export default {name: 'compA',components: {compB, compC}}
</script>
<!--compB.vue-->
<template><div><h2>我是compB组件</h2><p>compB组件获取到的数据:{{showDataB}}</p><button @click="handleEventB">点击将compB的数据传给compC</button></div>
</template>
<script>export default {name: 'compB',data() {return {dataB: '我是compB的数据'}},computed: {showDataB() {return this.$store.state.dataB//获取数据dataB}},methods: {handleEventB() {this.$store.commit('setDataC', this.dataB);//修改数据dataC}}}
</script>
<!--compC.vue-->
<template><div><h2>我是compC组件</h2><p>compB组件获取到的数据:{{showDataC}}</p><button @click="handleEventC">点击将compC的数据传给compB</button></div>
</template>
<script>export default {name: 'compC',data() {return {dataC: '我是compC的数据'}},computed: {showDataC() {return this.$store.state.dataC//获取数据dataC}},methods: {handleEventC() {this.$store.commit('setDataB', this.dataC);//修改数据dataB}}}
</script>

效果如下:

Vuex 存储的数据是响应式的,但并不会保存,刷新之后会回到初始状态,要解决这个问题,可以结合下面要说的 localStorage 来实现,当 Vuex 中数据变化时,将数据存储到 localStorage 中,刷新之后,如果 localStorage 中有数据,取出来替换 store 中的 state

8. localStorage / sessionStorage

HTML5 的本地存储 API 中的 localStoragesessionStorage 在使用方法上是相同的,区别在于 sessionStorage 在关闭页面后即被清空,而 localStorage 则会一直保存。存储的内容是以 Json 的形式存储的,JSON.parse() 用于将一个 JSON 字符串转换为对象,JSON.stringify() 可以将对象转换为字符串。

  • sessionSorage: 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
  • localSorage: 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。

保存数据到本地:

sessionStorage.setItem('key', JSON.stringify(value));
localStorage.setItem('key', JSON.stringify(value));

取得本地的数据:

let data1 = JSON.parse(sessionStorage.getItem('key'));
let data2 = JSON.parse(localStorage.getItem('key'));

清空全部数据:

sessionStorage.clear()
localStorage.clear()

删除单个数据:

localStorage.removeItem(key);
sessionStorage.removeItem(key);

得到某个索引的key:

localStorage.key(index);
sessionStorage.key(index);

三、总结

综上所述,Vue 组件通信的方式大概有八大类:

  1. props / $emit
  2. $children / $parent
  3. $attrs / $listeners
  4. provide / inject
  5. ref
  6. EventBus
  7. Vuex
  8. localStorage / sessionStorage

按组件间的关系对应合适的使用场景可大致归纳如下:

  • 父子组件通信:
    props / $emit , $parent / $children , $attrs / $listeners , provide / inject , ref , EventBus , Vuex , localStorage/sessionStorage
  • 兄弟组件通信:
    EventBus , Vuex , localStorage/sessionStorage
  • 跨级组件通信:
    $attrs / $listeners , provide / inject , EventBus , Vuex , localStorage/sessionStorage

四、其他

本文所示的例子都已上传至 github,都采用快速原型开发,如果需要可参考以下步骤:

  1. 使用如下命令安装 vue-cli3
npm install @vue/cli -g

或者

yarn global add @vue/cli
  1. 使用如下命令安装一个额外的全局插件,这样就可以使用 vue serve 和 vue build 命令独立运行单个 * .vue 文件:
npm install -g @vue/cli-service-global

或者

yarn global add @vue/cli-service-global
  1. 新建 *.vue 文件
  2. 在 *.vue 文件所在目录下运行如下命令:
# App.vue
vue serve
# 指定入口文件
vue serve component.vue

参考文章

  1. 珠峰架构课(强烈推荐)
  2. Vue.js 官方文档
  3. Vue.js实战 梁灏编著
  4. Vue组件间通信6种方式
  5. Vuex框架原理与源码分析
  6. localStorage 与 sessionStorage 使用方式
  7. Vue $dispatch 和 $broadcast

超实用的 Vue 组件通信方式大汇总(8种)相关推荐

  1. Vue 组件通信方式居然有这么多?你了解几种

    ↓推荐关注↓ 前端技术编程 专注于分享前端技术:JS,HTML5,CSS3,Vue.js,React,Angular 等前端框架和前端开源项目推荐! 0篇原创内容 公众号 vue组件通信的方式,这是在 ...

  2. Vue组件之间传值的几种方法 (直接上代码)

    vue组件之间传值的几种方法总结 一. props(父传子) 父组件 传递 <template><div><HelloWorld :msg="msg" ...

  3. 8种vue组件通信方式

    vue是数据驱动视图更新的框架,所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 首先我们需要知道在vue中组件之间存在什么样的关系, 才更容易理解他们的通信方式, 就好 ...

  4. vue组件间常用的几种通信方式

    第一种方式:props 这种通信方式适用与父向子传递数据 //父组件 <template><div class="father"><span>我 ...

  5. 2019年 Vue 组件库大评测 Element, iView, HeyUI, Ant Design Vue

    2018年我写的Vue组件库对比文档: https://juejin.im/post/5a9628415188257a7b5ac678 一年的时间,每一个组件库都有了更多的发展,Ant Design ...

  6. Vue组件间通信的几种方式

    引入 用vue可以是要组件复用的,而组件实例的作用域是相互独立,这意味着不同组件之间的数据无法互相引用 一般来说,组件之间可以有几种关系: 如上图所示,A 和 B.B 和 C.B 和 D 都是父子关系 ...

  7. vue组件间通信的13种方式

    前言 vue是数据驱动视图更新的框架, 我们平时开发,都会把页面不同模块拆分成一个一个vue组件, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 首先我们需要知道在v ...

  8. vue组件之间传值的几种方式

    vue组件传值 父子组件之间传值.几种常见方式 第一种方式(父传子) 父组件 <m-child :childMsg="parentMsg"></m-child&g ...

  9. vue组件通信大总结

    文章目录 1. props / $emit 2. sync / update 3. provide / inject 4. $attrs / $listeners 5. $children / $pa ...

最新文章

  1. css规则_CSS规则,将使您的生活更轻松
  2. GNU Radio的hello world(转)
  3. python怎么安装pin库_Python库之numpy库的安装教程
  4. mysql8开启远程访问
  5. “echo ”和“echo ”的区别
  6. HDU1317 —— 最长路+判断正环
  7. cad 打开硬件加速卡_CAD:“你的图纸缺少shx字体!”不知道该怎么办?不存在的!...
  8. h5-video3 解决html5 audio iphone,ipd,safari不能自动播放问题
  9. 考研数学第三章复习:曲率、曲率圆、曲率半径
  10. Windows11关机键在哪 Win11系统关机键的位置
  11. Thingworx- 创建一个网络
  12. 手机配件市场上的“隐形巨头”:80后长沙夫妻创办,IPO首日市值逼近600亿
  13. Valley Numer II(状压dp)
  14. 7-214 泰勒级数展开近似sin(x)的值7-215 求班级平均分7-216 同数异形体
  15. 21、关于破解点触的验证码
  16. oracle安装界面空白,在windows 2012中安装oracle 12c R2界面空白挂起无响应CPU达到100%的问题...
  17. 为何excel中数据无法计算机,Excel中数字无法正常求和怎么办?
  18. 栈的实现(C语言版)
  19. 个人网站的设计与实现
  20. Servlet连接SQLite数据库出现Out of Memory

热门文章

  1. 搜索引擎突然无法访问问题
  2. MyHDL中文手册(十)——转换成Verilog和VHDL
  3. 什么是Nofollow
  4. 【论文学习】《“Hello, It’s Me”: Deep Learning-based Speech Synthesis Attacks in the Real World》
  5. 在计算机上怎么搜共享打印机,如何共享电脑中的打印机?共享电脑打印机步骤...
  6. Docker常用基础命令
  7. 搭建react项目教程(二)
  8. 信雅达,一家不尊重应聘者的公司
  9. 内核提速开机linux,Linux系统开机提速我有招!
  10. 冯诺依曼结构、哈佛结构、改进型哈佛结构