vue 组件通讯

14 种组件通讯

1. props

  这个就是父传子属性, props 值可以是一个数组或对象

// 数组:不建议使用
props:[]

// 对象
props:{
 inpVal:{
  type:Number, //传入值限定类型
  // type 值可为String,Number,Boolean,Array,Object,Date,Function,Symbol
  // type 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认
  required: true, //是否必传
  default:200,  //默认值,对象或数组默认值必须从一个工厂函数获取如 default:()=>[]
  validator:(value) {
    // 这个值必须匹配下列字符串中的一个
    return ['success', 'warning', 'danger'].indexOf(value) !== -1
  }
 }
}

2. $emit

  这个也非常常见, 触发父组件的自定义事件, 其实就是父传子的方法

1 // 父组件
2 <home @title="title">
3 // 子组件
4 this.$emit('title',[{title:'这是title'}])

3. vuex

  vuex 是一个状态管理器,

  一个独立的插件, 适合数据共享多的项目里面, 因为如果只是简单的通讯, 使用起来会比较重

1 state:定义存贮数据的仓库 ,可通过this.$store.state 或mapState访问
2 getter:获取 store 值,可认为是 store 的计算属性,可通过this.$store.getter 或 mapGetters访问
4 mutation:同步改变 store 值,为什么会设计成同步,因为mutation是直接改变 store 值,
5          vue 对操作进行了记录,如果是异步无法追踪改变.可通过mapMutations调用
6 action:异步调用函数执行mutation,进而改变 store 值,可通过 this.$dispatch或mapActions 访问
8 modules:模块,如果状态过多,可以拆分成模块,最后在入口通过...解构引入

4. $attrs 和 $listeners

   2.4.0 新增 这两个是不常用的属性, 但是高级用法很常见; 

  $attrs 场景: 如果父传子有很多值, 那么在子组件需要定义多个

  props解决: attrs 获取子传父中未在props定义的值(在 $attrs里面只会有props没有注册的属性) -> (class 和 style 除外)

1 // 父组件
2 <home title="这是标题" width="80" height="80" imgUrl="imgUrl"/>
3 
4 // 子组件
5 mounted() {
6   console.log(this.$attrs) //{title: "这是标题", width: "80", height: "80", imgUrl: "imgUrl"}
7 },

    

1 props: {
2   width: {              // 父组件的width 在子组件props中注册后, 那么在$attrs上取不到
3     type: String,
4     default: ''
5   }
6 },
7 mounted() {
8   console.log(this.$attrs) //{title: "这是标题", height: "80", imgUrl: "imgUrl"}
9 },

    

$listeners 场景: 子组件需要调用父组件的方法解决: 父组件的方法可以通过 v-on="listeners" 传入内部组件 ----- 在创建更高层次的组件时非常有用 

1 // 父组件
2 <home @change="change"/>
3 
4 // 子组件
5 mounted() {
6   console.log(this.$listeners) //即可拿到 change 事件
7 }

$inheritAttrs 

组件内未被注册的属性将作为普通html元素属性被渲染

 1 // 父组件
 2 <home title="这是标题" width="80" height="80" imgUrl="imgUrl"/>
 3 
 4 // 子组件
 5 mounted() {
 6   console.log(this.$attrs) //{title: "这是标题", width: "80", height: "80", imgUrl: "imgUrl"}
 7 },
 8 
 9 inheritAttrs默认值为 true,也就是父组件上的属性会显示到根组件上
10 如果设置为 false 就会隐藏

5. provide 和 inject

    2.2.0 版本新增

  使用场景: 以允许一个祖先组件向其所有子孙后代注入一个依赖, 不论组件层次有多深, 并在起上下游关系成立的时间里始终生效。

   provide :一个对象或返回一个对象的函数

   inject : 一个字符串数组,或一个对象,对象的key是本地的绑定名

 1 <template>         // 父组件
 2     <div id="app">
 3     </div>
 4 </template>
 5     <script>
 6         export default {
 7             data () {
 8                     return {
 9                         datas: [
10                             {
11                                 id: 1,
12                                 label: '产品一'
13                             },
14                             {
15                                 id: 1,
16                                 label: '产品二'
17                             },
18                             {
19                                 id: 1,
20                                 label: '产品三'
21                             }
22                         ]
23                     }
24             },
25             provide {
26                 return {
27                     datas: this.datas
28                 }
29             }
30         }
31     </script>
<template>    // 后代组件
    <div>
        <ul>
        <li v-for="(item, index) in datas" :key="index">
            {{ item.label }}
        </li>
        </ul>
    </div>
</template>
    <script>
        export default {
            inject: ['datas']
        }
    </script>

 注意: provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个监听的对象,那么其对象的属性还是可响应的。

 响应式示例:

父组件中提供
  provide() {
    return {
      map_nodeObj: { map_node: this.obj }
      // 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
    }
  },

子组件中引入
  inject: {
    map_nodeObj: {
      default: () => {
        return {map_node: '0'}
      }
    }
  },
使用: this.map_nodeObj.map_node

// 运行顺序
data
provide
created  // 在这个阶段$el还未生成,在这先处理privide的逻辑,子孙组件才可以取到inject的值
mounted
...

6. $parent 和 $children

    $parent:指代的父组件, 返回的是一个组件集合 

  用法:this.$parent     (如果当前组件没有父组件,那么返回当前组件)

  $children:指代的子组件,返回的是一个组件集合

  用法: this.$children   (如果你能清楚的知道子组件的顺序,可以使用下标来表示)

注意:(1) 组件只能有一个根节点

   (2) 可以在子组件中使用this.$parent.属性值, 或者函数

   (3) 在父组件中可以使用this.$children[i].属性

   (4) 需要注意this的指向

7. ref 和 $refs

  ref 有三种用法:

  (1) ref加在普通的元素上,用this.$refs.name 获取到的是dom元素

  (2) ref 加在子组件上, 用this.$refs.name 获取到的是组件实例,可以使用组件的所有方法

  ref 和 v-for 在一起的情况

        

                             

8. $root

  $root 设置全局属性

let app = new Vue({
    el: '#app',
    // 全局数据,在其他页面或者组建可改变
    data: function () {
    return {
        s: ''
    }
    }, 
    router,
    store,
    template: '<router-view></router-view>'
})

// a.vue
    this.$root.s = '设置了s属性'

// b.vue
    console.log(this.$root.s)  //设置了s属性

9.  .sync

  从2.3.0起重新引入的 .sync 修饰符,.sync被作为一个编译时的语法糖,它会被扩展为一个自动更新父组件属性的 v-on 监听器

// 父组件
<comp :foo.sync="bar"></comp>

// 编译时会被扩展为:
<comp :foo="bar" @update:foo="val => bar = val"></comp>


//子组件

//当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:
// 所以子组件可以通过$emit 触发 update 方法改变
this.$emit('update:foo', newValue)

10. v-slot 插槽

  2.6.0新增

  (1) 匿名插槽

  (2) 具名插槽

  (3) 作用域插槽

    

猜你喜欢

转载自www.cnblogs.com/shenjilin/p/11649867.html
今日推荐