最近的项目中又重新用起了vue,在此项目中遇到了组件间通信难的问题。这篇文章主要根据自己查到的资料及实操介绍下vue组件间通信的解决方法
父子组件之间的传值
父组件向子组件传值
父组件传值给子组件用 ":子组件接收的参数名=要传的值"。如图:
子组件用props接收来自父组件的参数。如图:
关于props的几种写法:
第一种方法
props:['setImKey','setImObj']
第二种方法(限制了参数类型,如果类型不一致会警告)
props:{
'setImKey': String,
'setImObj': Object
}
第三种方法(限制了参数类型,以及给定默认值)
props:{
'setImKey': {
'type': String,
'default': 'SETIM'
},
'setImObj': {
'type': Object
'default': {}
}
}
子组件向父组件传值
先在父组件中给子组件传入事件。"@子组件自定义的方法名=触发的父组件方法"
子组件中用"this.$emit(子组件自定义的方法名, 要传的值)"传值给父组件
子组件直接使用父组件属性或方法
this.$parent.父组件中某方法名() 或 this.$parent.父组件中某属性
父组件直接调用子组件方法或修改子组件的值
给子组件加上索引,用this.$refs.索引名 调用该组件内的方法或修改值。
eventBus通信(适用于中小型项目)
1、新建一个eventBus.js,里面只有两行代码
import Vue from 'vue'
export default new Vue()
2、组件里引入eventBus.js,并在created()钩子中调用$on监听事件获取参数
import Bus from '../eventBus.js'
created: {
Bus.$on('getTarget', function(val) {
console.log(val);
})
}
3、组件里引入eventBus.js,调用$emit设置参数
import Bus from '../eventBus.js'
Bus.$emit('getTarget', 'TargetVal');
vuex
状态?我把它理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态。简单的说就是data中需要共用的属性。
引入Vuex(前提是已经用Vue脚手架工具构建好项目)
1.利用npm包管理工具,进行安装 vuex。
npm install vuex --save
2、为了便于管理,新建一个config文件夹(这个不是必须的),并在文件夹下新建store.js文件,文件中引入我们的vue和vuex,引入之后用Vue.use进行引用。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
3、在main.js 中引入新建的vuex文件
import store from './config/store.js'
4、再然后 , 在实例化 Vue对象时加入 store 对象 :
new Vue({
el: '#app',
router,
store, // 使用store
components: { App },
template: ''
})
定义变量
在store.js文件中用export default 封装代码,让外部可以引用。
export default new Vuex.Store({
state: {
// 存储状态。也就是变量;
name: '张三',
age: 10,
obj: {}
},
getters: {
// 派生状态。
info (stateObj) { // 这里的stateObj对应上面的state
return '我的名字是:${stateObj.name}。今年${stateObj.age}岁。';
}
},
mutations: {
// 提交状态修改,为同步修改。(我们不能直接修改state里的变量,如果想修改变量必须用$store.commit(mutations定义的对应方法名, 要修改的值)。)
setAge (stateObj, age) { // 这里的stateObj对应上面的state
stateObj.age = age
}
},
actions: {
// 和mutations类似,为异步修改。用$store.dispatch()来触发actions里的方法
setAgeAction (context, age) { // 这里的context对应整个$store对象
context.commit('SET_AGE', age);
// 你还可以在这里触发其他的mutations方法
}
}
})
使用
模板中使用
<span class="name">{{ $store.state.name }}</span>
<p>{{ $store.getters.info }}</p>
修改变量
this.$store.commit('setAge', 10); // 同步修改
this.$store.dispatch('setAgeAction', 10); // 异步修改
监听变化
通过computed赋值给某个变量,监听该变量的变化从而达到监听state的效果
computed: {
myAge () {
return this.$store.state.age;
}
},
watch: {
myAge () {
console.log('年龄发生了改变')
}
}
用mapState、mapGetters、mapMutations、mapActions简化模板写法
首先在组件中用import引入我们的mapXXX
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
在computed中使用mapState、mapGetters,在methods中使用mapMutations、mapActions
computed: {
// 这里的三点叫做 扩展运算符 (ES6中的写法)
...mapState(['name', 'age']),
...mapGetters(['info'])
}
},
methods: {
...mapMutations(['setAge']),
...mapActions(['setAgeAction'])
}
}
现在可以在组件中像原来那样使用这些变量、方法了
<span @click="setAge(20)">{{ name }}</span>