Vue - 组件通信

父子通信

实现: 自定义属性

  • 使用:

    1
    2
    3
    4
    5
    6
    // 子组件里面
    export default {
    props:['属性名1','属性名2']
    }
    // 子模板里面
    {{属性名1}} {{属性名2}}
    1
    2
    <!--父组件里面-->
    <子组件 属性名1="值" :属性名2="变量" />

为了保证组件内部数据的统一性,我们要对组件的自定义属性,进行类型的验证!

props验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
props:['属性名']    // 尽量不要使用数组模式

props:{ // 对象模式
属性名:类型,
属性名:[类型1,类型2],
属性名:{
type:类型, // 单类型 // 类型校验
type:[类型1,类型2], // 多类型
default:默认值 // 默认值
default(){
return 对象/数组
},
required:true/false, // 是否必须
validator(val){ // 自定义校验函数
return true/false
}
}
}

哪些类型?

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

修改props,不是真的修改

  • props 用来传递一个初始值赋给组件的data

  • props 赋给计算属性

  • 传入一个对象的所有property

    如果你想要将一个对象的所有 property 都作为 prop 传入,你可以使用不带参数的 v-bind (取代 v-bind:prop-name)。例如,对于一个给定的对象 post

    1
    2
    3
    4
    post: {
    id: 1,
    title: 'My Journey with Vue'
    }

    下面的模板:

    1
    <blog-post v-bind="post"></blog-post>

    等价于:

    1
    2
    3
    4
    <blog-post
    v-bind:id="post.id"
    v-bind:title="post.title"
    ></blog-post>
  • 总结:

    • props的使用
    • props验证
    • 单项数据流

子父通信

实现: 自定义事件

  • 使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 父的模板里面
    <子组件名 @自定义事件名="父的事件函数" />

    // 父的JS里面
    methods:{
    父的事件函数(形参){
    ....
    }
    }
    1
    this.$emit("自定义事件名",实参)    // 本质调用了,父的事件函数

祖先后代通信

  • 目的: 实现祖先的数据,后代都可以使用(一般用于全局变量)

  • 实现:

    1
    2
    3
    4
    5
    // 祖先组件
    provide:{
    key1:val1,
    key2:val2
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 后代任意组件中
    inject:[key1,key2]
    inject:{
    newkey:{
    from:key1,
    default:"默认值"
    }
    }


    {{key1}} {{key2}}

非父子通信

  • 实现任意两个组件之间的通信!

  • 核心:利用vue里面的$emit 和 $on 实现 组件的监听事件和触发事件

  • 实现:

    1
    2
    3
    4
    // main.js中
    let bus = new Vue();
    // 在Vue的原型上面添加数据,所有的组件里都可以获取到
    Vue.prototype.$bus = bus
    1
    2
    3
    4
    5
    6
    // 任意组件中  事件订阅
    created(){
    this.$bus.$on('自定义事件名',function(形参){
    ...
    })
    }
    1
    2
    // 任意其他组件中  事件发布
    this.$bus.$emit('自定义事件名',实参)

总结

  • 父子通信
    • 自定义属性(props)、自定义事件($emit)
  • 祖先后代
    • provide (祖先)
    • inject (后代)
  • 非父子
    • $on 和 $emit 自定义事件
  • 本地存储
  • 父子关系
    • $parent
    • $children、$refs
  • vuex