阐明:上面我总结了比拟罕用的vue组件之前通信的形式,最近筹备面试,所以有些总结贴上来分享
props和$emit
只有父子关系才能够用这种形式,父组件向子组件传递参数用props,子向父传递应用触发$emit自定义事件
props
<!-- parent.vue, 能够传递`动态`的props和`动静`的props, 动态的参数只能是个String类型的,如果是其余类型的肯定要记得加`:`来示意这是一个 js 表达式而不是一个字符串 --><Child :name="name" :age="18" address="xxxxx"></Child>...data () { return { name: 'marry' }}<!-- 传一个参数所有props, 尽管目前我没有这个需要,应用不带参数的 v-bind --><blog-post v-bind="post"></blog-post>post: { id: 1, title: 'My Journey with Vue'}//等价于上面<blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post><!-- child.vue -->...//以字符串数组模式列出的 propprops: ['name', 'age', 'address']//prop验证, 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的正告//留神:以下类型不能写成'String'这种带引号的模式props: { // 根底的类型查看 (`null` 和 `undefined` 会通过任何类型验证) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function () { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function (value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } }}//留神那些 prop 会在一个组件实例创立之前进行验证,所以实例的 property (如 data、computed 等) 在 default 或 validator 函数中是不可用的。
$emit
<!-- parent.vue --><Child @my-event="myEvent"></Child>...methods: { myEvent(name){ this.name = name }}<!-- child.vue --><div> <button @click="$emit('my-event', name)"></button></div>//应用自定义事件将子组件的值抛给父组件
地方事件总线 bus
用于解决跨级和兄弟组件通信问题,奇妙的应用一个公共的vue实例,利用$on, $emit, $off(移除自定义事件监听器)
办法一:
能够在main.js中,在Vue的原型上挂载一个公共的Vue实例 $bus,这样全局任何一个中央都能够应用
Vue.prototype.$bus = new Vue()
而后在须要的中央注册自定义事件和接管参数的回调函数
this.$bus.$on('changeName', name => { this.name = name})
在须要扭转的时候触发事件并抛出参数
this.$bus.$emit('changeName', 'wzj')
办法二:
定义一个util.js文件
import Vue from 'vue'const bus = new Vue()export default bus
在须要用到bus的文件中引入
import bus from '../util' //文件门路不肯定//在一个文件定义事件bus.$on('changeName', name => { this.name = name})//另一个文件抛出参数bus.$emit('changeName', 'wzj')
vuex
对于我的项目比较复杂,多组件共享状态,不同层级须要通信
外围概念:
state, getter, mutation, action, module
//store/index.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export dafault new Vuex.Store({ state: { name: '', age: 0 }, getters: { tranName(state){ return 'name: ' + state.name } }, mutations: { changeName(state, name){ state.name = name } }, /*Action 函数承受一个与 store 实例具备雷同办法和属性的 context 对象,因而你能够调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters */ actions: { //异步函数,但还是要通过提交commit触发mutations函数操作state changeName(context, name){ context.commit('changeName', name) } }, modules: {}})
在组件中应用
办法一:
//拜访state属性this.$store.state.name//拜访getters属性this.$store.getters.tranName//拜访mutationsthis.$store.commit('changeName', 'wzj')//拜访actionsthis.$store.dispatch('changeName', 'wzj')
办法二:应用辅助函数映射到本地,这里只列举了简便的形式,更多查阅官网吧
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'//state 和 getters 映射到本地的computed属性中,作为计算属性应用computed: { ...mapState(['name', 'age']), ...mapGetters(['tranName'])}//mutations 和 actionsmethods: { // 将 `this.changeName()` 映射为 `this.$store.commit('changeName')` ...mapMutations(['changeName']) // 将 `this.changeName()` 映射为 `this.$store.dispatch('changeName')` ...mapActions(['changeName'])}
$attrs 和 $listeners
父组件与后辈组件,用以上办法有点大材小用或者第一种有些不不便
- $attrs 蕴含了父作用域中不作为 prop 被辨认 (且获取) 的 attribute 绑定 (
class
和style
除外)。当一个组件没有申明任何 prop 时,这里会蕴含所有父作用域的绑定 (class
和style
除外),并且能够通过v-bind="$attrs"
传入外部组件。 - $listeners 蕴含了父作用域中的 (不含
.native
润饰器的)v-on
事件监听器。它能够通过v-on="$listeners"
传入外部组件——在创立更高层次的组件时十分有用。
例子:
//app.vue<div> <One name="wzj" :age="age" address="xian" @changeAge="changeAge"></One></div>...data(){ return { age: 10 }},methods: { changeAge(age){ this.age = age }}//one.vue<div> <div>姓名:{{ name }}</div> <div>年龄:{{ age }}</div> <Two v-bind="$attrs" v-on="$listeners"></Two> <button @click="change">点我2</button></div>...props: ['name', 'age'],//two.vue<div> <div>{{ address }}</div> <button @click="change">点我2</button></div>...props: ['address'], //用$attrs传递到最初的属性,在应用的时候还是要申明propsmethods: { change(){ this.$emit('changeAge', 30) }}
了解:其实先人组件的属性和事件还是一层层往下传,不过用$attrs 和 $listeners优化和简便了传递过程中书写,而且在传递的过程中,任何一个申明了 $listeners的组件都能够触发外面的所有事件,而申明了$attrs的组件只能应用之前未用props申明的剩下的属性。