Vue组件通信
2017-08-25 16:15
190 查看
父子组件通信
父组件和子组件通信
使用ref为子组件指定一个索引
ID
<div id="counter-event-example"> <p @click="clickB">{{ msg }}</p> <button-counter-a ></button-counter-a> <button-counter-b ref="refB"></button-counter-b> </div>
然后便可以在父组件中通过
this.$refs.refB访问子组件方法了
Vue.component('button-counter-a', { template: '<button v-on:click="eventClick">{{ msg }}</button>', data: function () { return { msg: '组件A' } }, methods: { eventClick: function () { } } }) Vue.component('button-counter-b', { template: '<button>{{ msg }}</button>', data: function () { return { msg: '组件B' } }, methods: { eventClick: function (msg) { console.log(msg) } } }) new Vue({ el: '#counter-event-example', data: { msg: '父组件' }, methods: { clickB () { this.$refs.refB.eventClick(this.msg); } } })
点击父组件便可以在控制台上看到子组件的输出了
可以在 这里 看看效果。
子组件和父组件通信
首先在父组件使用$on(eventName)监听, 然后在子组件
$emit(eventName)触发事件。
如 官网 中的计数器实例,先是在父组件上监听事件
incrementTotal
<div id="counter-event-example"> <p>{{ total }}</p> <button-counter :count="count" v-on:increment="incrementTotal"></button-counter> <button-counter :count="count" v-on:increment="incrementTotal"></button-counter> </div>
然后在子组件中触发父组件事件,动态更改计数
Vue.component('button-counter', { template: '<button v-on:click="incrementCounter">{{ counter }}</button>', props : ["count"], data: function () { return { counter: 0 } }, methods: { incrementCounter: function () { this.counter += 1 this.$emit('increment', this.counter) // 第二个参数,可以传递到父组件中 console.log(this.count) // 调用父组件方法,然后发现count值变了,这里相当于接收返回值了 } } }) new Vue({ el: '#counter-event-example', data: { total: 0, count: 0 }, methods: { incrementTotal: function (count) { console.log(count) // 接收子组件中的参数 this.count += 1 this.total += 1 } } })
这里父子组件通信,父组件通过
props向子组件传值,子组件通过自定义是事件与父组件通信
可以在 这里 看看效果。
兄弟组件通信
若A组件想要和
B组件通信,按照父子组件通信的思维,则是
A和父组件通信,然后父组件再和
B组件通信,比较绕。有没有更好的方法呢,事实上,
Vue提供了个
Event Bus(中央事件总线)的机制。
bus.js
import Vue from 'vue'; export default new Vue();
在A组件中触发组件 B 中的事件
import bus from 'bus.js'; bus.$emit('eventB', 'A')
在组件 B 创建的钩子中监听事件
import bus from 'bus.js'; bus.$on('eventB', function (msg) { console.log(msg) })
可以在 这里 看看效果。
Vuex
对于复杂的组件通信, 还是推崇Vue专门用来状态管理模式的
Vuex。来看看下面官网上的这张图
图中的
State, 就是驱动应用的原始数据源,以声明方式将这些
State映射到
View中,而要改变
State,则要通过一些
Action来驱动。
图中绿色虚线
Vuex部分显示发生在
Component上的一次事件中来
Commit一个相应的
Mutations方法,
Mutations方法来
Mutate对应的
State,然后在组件中通过计算属性的监测,响应式更新视图。
来看个简单的计数器 实例
<div id="app"> <p>{{ count }}</p> <p> <button @click="increment">+</button> <button @click="decrement">-</button> </p> </div>
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment: state => state.count++, // 箭头函数,相当于 function (state) {return state.count++} decrement: state => state.count-- } }) new Vue({ el: '#app', computed: { count () { return store.state.count } }, methods: { increment () { store.commit('increment') }, decrement () { store.commit('decrement') } } })
最后来个在实际项目中
Vuex实例,需要安装
npm install vuex vuex-persistedstate,
vuex-persistedstate实际上使用了
HTML 5中的
localStorage来做缓存,这样在刷新页面后之前
state的数据不会丢失。
mutation-type.js
// 更新 count export const UPDATE_COUNT = 'UPDATE_COUNT';
mutation.js
import * as types from './mutation-types' export default { // 更新 count [types.UPDATE_COUNT] (state, count) { state.count= count } }
actions.js 【需注意在
mutations里都是用大写下划线连接,在
actions里都用小写驼峰对应】
import * as types from './mutation-types' export default { updateCount({ commit }, count) { commit(types.UPDATE_COUNT, count) } }
getters.js
export default { evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd' }
state 【index.js】
import Vue from 'vue' import Vuex from 'vuex' import createPersistedState from 'vuex-persistedstate' import mutations from './mutations' import actions from './actions' import getters from './getters' Vue.use(Vuex); const state = { count: 0 }; export default new Vuex.Store({ state, mutations, actions, getters, plugins: [createPersistedState()] })
main.js
import store from './store' new Vue({ el: '#app', store, template: '<App/>', components: { App } })
在具体某个组件中应用
<template> <div @click="increment">{{count}} {{isEvenOrOdd}}</div> </template> <script> export default { name: 'bar', computed: { count () { return this.$store.state.count }, isEvenOrOdd () { return this.$store.getters.evenOrOdd } }, methods: { increment () { this.count += 1 this.$store.dispatch('updateCount', this.count) } } } </script>
如果项目较大,而且操作的状态又多,要是都放在一棵树上,那么
store对象就先显得臃肿,这时可以可以把
store按一定逻辑分割成
module(模块)
app.js
const app = { state: { count: 0 }, mutations: { UPDATE_COUNT: (state, count) => { state.count += count } }, actions: { updateCount({ commit }, count) { commit('UPDATE_COUNT', count) } } getters: { evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd' } } export default app;
store/index.js
import Vue from 'vue'; import Vuex from 'vuex'; import createPersistedState from 'vuex-persistedstate' import app from './modules/app'; Vue.use(Vuex); const store = new Vuex.Store({ modules: { app }, plugins: [createPersistedState()] }); export default store
引用
this.$store.state.app.count // 加上模块名 this.$store.dispatch('updateCount', 1)
相关文章推荐
- vue组件父与子通信详解(一)
- vue组件之间的通信
- Vue组件--非父子组件间的通信
- vue组件通信需要注意普通类型的数据
- vue子父组件通信的实现代码
- vue开发:Vue 非父子组件通信方法(非Vuex)
- vue prop 父组件向子组件通信
- [js高手之路]Vue2.0基于vue-cli+webpack父子组件通信教程
- Vue 非父子组件通信
- Vue2.0学习之详解Vue 组件及父子组件通信
- Vue.js-----轻量高效的MVVM框架(十、父子组件通信)
- Vue2.0 组件之间的通信
- Vue基础:组件--组件及组件通信
- 使用Vue开发网站之路2-多组件通信1(利用bus总线进行事件触发)
- vue2.0组件之间传值、通信的多种方式(干货)
- Vue.js入门(三)——关于组件以及组件通信
- vue.js父子组件通信动态绑定的实例
- Vue之父子、同级组件的通信详解
- vue2.0父子组件以及非父子组件通信传参详解
- Vue 兄弟组件通信的方法(不使用Vuex)