vue组要思想之一就是组件式开发,那么组件和组件之间通信也就是很重要的一个点。
组件间的关系包括: 父子关系、 兄弟关系、隔代关系
1.父子组件传值问题
(1)通过props父组件可以直接的给子组件传值,每一次父组件更新时,子组件的props会刷新成最新值。
父组件中给引入的子组件上绑定数据(就是要传递的数据)
在子组件中,通过props接收参数
(2)子组件中调用父组件中的方法 && 子组件向父组件传值
例如:子组件中修改了参数在需要调用父组件重的刷新页面获取数据的方法:
父组件中的刷新方法名
给父组件中引用的子组件上通过v-on(@)绑定gitDictClassify事件,来监听子组件的触发事件
在子组件中通过this.$emit(’ xxx ')触发父组件注册的事件来处理数据逻辑
(3)子组件向父组件传参
子组件中
this.$emit(‘方法名’,数据)
父组件中绑定子组件中的定义的方法
2. $attrs 和 $listeners
作用: (父)A——>B——>C 直接让A组件传消息给C组件
3. EventBus 中央事件总线
EventBus是安卓 发布/订阅事件总线的优化。
优点:简化组件间通信问题
EventBus 3.0版本后,开发者能够自定义订阅方法的名字,而没必要规定以“onEventXX”开头的方法了
任意组件之间通信,在项目规模不大的情况下,可以使用EventBus方式 ,中大型项目,使用vuex状态管理。
使用EventBus的方法:
(1)新建一个Vue的bus对象.
通过建立一个eventBus.js文件,暴露一个空的Vue实例
import Vue from 'vue'
export defalut new Vue()
在需要通信的两个组件中分别引入eventBus文件
import bus from ‘common/utils/eventBus’
(2)然后通过$emit触发(提交)事件,
页面A
bus.$emit('eventBusName', 'data') //data包含数据和参数
(3)$on监听事件
例如:页面B中 created时接收数据
created(){
bus.$on('eventBusName', this.handleData)
},
methods:{
handleData() {}
}
存在问题:
1.第一次触发的时候组件B中的on事件没有被触发,2.且第二次以后触发时,事件触发执行越来越多
原因&&解决:
1.当我们在A页面时,页面B还没生成, B中created监听的事件还没有被触发,这时候B是监听不到的。(生命周期)。
解决:将A页面的emit事件写在beforeDestory中去,这个时候,B组件已经被Created了,所以这样能触发$on 事件。
A页面
beforeDestroy () {
bus.$emit('get', data)
},
2.由于on事件是不会自动清除销毁的,所以每一次调用,前一个一直在,就导致了累加,故需要我们手动销毁。
解决: 在B组件页面添加bus.$off来关闭on对应的事件
B页面
beforeDestroy () {
bus.$off('get', this.handleData)
}
总结: 所以,如果想要用bus 来进行页面组件之间的数据传递,需要注意
组件A 的emit事件应在beforeDestory生命周期内。
组件B内的$on记得要用off销毁。
4. vuex状态管理
首先通过npm安装:npm install vuex --save
vuex进行组件间通信的核心思路就是将vuex作为一个store,将子组件的数据都存进去,子组件再从vuex里面获取数据,数据改变时再通过commit提交到store里。
通过store.state来获取状态对象
通过store.commit方法来触发状态更新
Vuex有五个属性:State、Getter、Mutation、Action、Module。
组件不允许直接修改属于 store 实例的 state,而应执行 action 来分发 (dispatch) 事件通知 store 去改变
1. State里放入的是仓库的数据,类似于js里的data
//Vuex里的数据需要从计算属性(computed)里读取
import { mapState ,mapMutations} from 'vuex'
export default {
compoted:{
...mapState(['name'])
},
}
2.getters 为组件提供经处理的数据源,比如: 把原变量名简化,转化数据类型等
getter: {
token: state => state.user.token
}
- Mutations 是更改state里的数据的的唯一标准方式(同步),
mutation中式存放处理数据的方法的集合。使用时需要commit(同步函数)。
即修改state里的数据只能用mutations里面的方法,这些方法是同步的
你可以在组件中使用 this.$store.commit(‘xxx’) 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit
// js 中mutations的方法
const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
setToken(token)
},
}
4.Actions:组件通过actions提交mutation(异步)
actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法。
分发 Action通过store.disoatch方法触发。
store.dispatch(‘handleLogin’)
js
const actions = {
// 使用 ticket 登录
handleLogin({ commit }, ticket) {
return new Promise((resolve, reject) => {
login(ticket).then(res => {
// 设置 token
commit('SET_TOKEN', res.data.ticket)
resolve()
}).catch(err => {
reject(err)
})
})
},
页面中需要用
import { mapActions } from 'vuex'
methods: {
...mapActions(['handleLogin'])
}
补充:javascript中的计算相关奇怪的问题
console.log(0.1 + 0.2);
console.log(0.1 + 0.2 == 0.3);
一个稍微有点编程基础的回答是:“你不能确定。可能会输出“0.3”和“true”,也可能不会。
所以我们又测试了几个例子发现能够得处按照正常的数学运算的结果。
乍一看是不是觉得很神奇?
原因是:JavaScript中的数字和浮点精度的处理相同,因此,可能不会总是产生预期的结果。