一、props
适用于:
1)父组件 —> 子组件 通信
在子组件定义props,在父组件中引入子组件,并在子组件标签绑定要传递的数据
// 父组件
<template>
<div class="father">
// 传固定String
<Child :msg="123123" />
</div>
</template>
<script>
// 引入子组件
import Child from "./child"
export default {
data () {
return {}
},
components: {
Child
},
}
</script>
// 子组件
<template>
<div class="child">
<span>{{msg}}</span>
</div>
</template>
<script>
export default {
data () {
return {}
},
// 接收来自父组件的数据; props可以是数组,也可以是对象(校验)
// props: [ 'msg' ]
props: {
msg: {
type: String, // 指定msg类型
require: false, // 是否必传,这里如果为true,在父组件不传msg,页面会报错
default: "啦啦啦" // msg的默认值
}
}
}
</script>
2)子组件 —> 父组件 通信(要求父先给子一个函数)
3)路由组件传递props :布尔值、对象、函数
二、自定义事件
- 适用于:子传父
- 使用场景:子组件想给父组件传数据,就要在父组件中给子组件中绑定自定义事件(事件的回调留在父组件中)
- 绑定自定义事件
1)第一种方式:在父组件中:
<Demo @fandou="test"/> 或 <Demo v-on:fandou="test"> //<Demo/>是子组件
2)第二种方式:在父组件中:
<Demo ref="demo"/>
......
mounted() {
this.$refs.xxx.$on("fandou",this.test)
}
3)若想自定义事件只能触发一次,可以使用once修饰符,或$once方法
- 触发自定义事件:this.$emit(‘fandou’,数据)
- 解绑自定义事件:this.$off(‘fandou’)
- 组件上也可以绑定原生DOM事件,需要使用native修饰符
- 注意:通过this.$ refs.xxx.$on(“fandou”,回调)绑定自定义事件,回调要么配置在methods,要么用箭头函数,否则this指向会出现问题
第二种写法:使用ref
三、全局事件总线$bus
- 适用于任意组件间通信
- 安装全局事件总线:在入口文件main.js中
new Vue ({
......
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
},
......
})
- 使用事件总线
1)接收数据:A组件想接收数据,则在A组件中给$bus绑自定义事件,事件的回调留在A组件中
methods() {
demo(data) {
......
},
},
mounted() {
this.$bus.$on('xxx',this.demo)
}
2) 提供数据: this.
b
u
s
.
bus.
bus.emit(‘xxx’,demo)
4. 最好在beforeDestory钩子中,用$off去解绑当前组件所用到的事件
四、消息订阅与发布(pubsub-js)
- 适用于任意组件间通信
- 引入:import pubsub from ‘pubsub-js’
- 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身
methods(){
demo(data){
......
},
},
......
mounted() {
this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
}
- 提供数据:pubsub.publish(‘xxx’,数据)
- 最好在beforeDestroy钩子中,用pubsub.unsubscribe(pid)
五、Vuex
- 在Vue中实现集中式状态(数据)的管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),适用于任意组件间通信
- 何时使用? ————多个组件需要共享数据时
- 搭建Vuex环境
1)创建文件:src/store/index.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions对象———响应组件中用户的动作
const actions = {}
// 准备mutations——用于操作数据(state)
const mutations = {}
// 准备state——用于存储数据
const state = {}
// 准备getters——用于加工数据
const getters = {}
Vue.use(Vuex)
// 创建并暴露store
export default new Vuex.Store({
actions:actions,
mutations,
state,
getters,
})
2)在main.js中创建vm时传入store配置项
......
//引入store
import store from './store'
......
//创建vm
new Vue({
el:'#app',
render: h => h(App),
store
})
- 组件读取vuex中的数据:$store.state.xxx || $store.getters.yyy
- 组件中修改vuex中的数据:$store.dispatch(‘action中的方法名’,数据) 或 $store.commit(‘mutations中的方法名’,数据)
- 备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit
- 四个map方法的使用
1)mapState方法:用于帮助我们映射state中的数据为计算属性
computed: {
//借助mapState生成计算属性:sum、school、subject(对象写法)
...mapState({sum:'sum',school:'school',subject:'subject'})
//借助mapState生成计算属性:sum、school、subject(数组写法)
...mapState(['sum','school','subject'])
}
2)mapGetters方法:用于帮助我们映射gettes中的数据为计算属性
computed: {
//借助mapGetters生成计算属性:bigSum(对象写法)
...mapGetters({bigSum:'bigSum'})
//借助mapGetters生成计算属性:bigSum(数组写法)
...mapGetters(['bigSum'])
}
3) mapActions方法:用于帮助我们生成actions对话的方法,即:包含$store.dispatch(xxx)的函数
methods:{
//靠mapActions生成:incrementOdd、incrementWait(对象形式)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
//靠mapActions生成:incrementOdd、incrementWai(数组形式)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
}
4) mapMutations方法:用于帮助我们生成与mutations对话的方法。即:包含$store.commit(xxx)的函数
methods: {
//靠mapMutations生成,increment、decrement(对象形式)
...mapMutations({increment:'JIA',decrement:'JIAN'})
//靠mapMutations生成,JIA、JIAN(数组形式)
...mapMutations([]JIA','JIAN'])
}
备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象
- 模块化 + 命名空间
1. 目的:让代码更好维护,让多种数据分类更加明确
2. 修改store.js
const countAbout = {
namespaced:true,//开启命名空间
state:{x:1},
mutations:{....},
actions:{....},
getters:{
bigSum(state) {
return state.sum * 10
}
}
}
const personAbout = {
namespaced:true,//开启命名空间
state:{....},
mutations:{....},
actions:{....},
}
const store = new Vuex.Store({
modules:{
countAbout:countOptions,
personAbout:personOptions
}
})
- 开启命名空间后,组件中读取state数据:
//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取
...mapState('countAbout',['sum','school','subject']),
- 开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapState读取
...mapGetters('countAbout',['bigSum'])
- 开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonXiao',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
- 开启命名空间后,组件中调用commit
//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapActions('countAbout',{increment:'JIA',decrement:'jIAN'})