0%

vue组件通信

vue组件通信

组件通信

父给子组件通信

  • 子组件通过props属性接收

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    var father = {
    template:
    `
    <div>
    <button @click="handleClick"></button>
    <!-- 静态传值 zhangsan -->
    <son name="name"></son>
    <!-- 动态传值 zhangsi -->
    <son :name="name"></son>
    </div>
    `,
    data() {
    return {
    name: "zhangsan"
    }
    },
    methods: {
    handleClick (){
    this.name = "zhangsi"
    }
    }
    }


    var son = {
    props: ['name'],
    template:
    `
    <div>
    <p>{{name}}</p>
    </div>
    `
    }
    • props 对象写法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      props: {
      title: String,
      likes: Number,
      isPublished: Boolean,
      commentIds: Array,
      author: Object,
      callback: Function,
      contactsPromise: Promise, // or any other constructor
      // 多个可能的类型
      propB: [String, Number],
      name: {
      // 类型定义
      type: String,
      // 必传字段
      required: true,
      default: "zhangsan"
      },
      age: {
      type: Nubmer,
      // 默认值
      default: 100
      },
      // 自定义验证函数
      propF: {
      validator(value) {
      // 这个值必须与下列字符串中的其中一个相匹配
      return ['success', 'warning', 'danger'].includes(value)
      }
      },
      // 具有默认值的函数
      propG: {
      type: Function,
      // 与对象或数组的默认值不同,这不是一个工厂函数——这是一个用作默认值的函数
      default() {
      return 'Default function'
      }
      }
      }

      必传变量

      1
      2
      3
      4
      5
      6
      7
      name: {
      // 类型定义
      type: String,
      // 必传字段
      required: true,
      default: "zhangsan"
      },

      默认值

      1
      2
      3
      4
      5
      age: {
      type: Nubmer,
      // 默认值
      default: 100
      },

子给父组件通信

  • 通过父组件传递方法给子组件

  • 子组件通过this.$emit("方法名") 触发父组件传递过来方法,

  • this.$emit("方法名", 数据)的第二个参数把数据传递给父组件

  • 父给子传递方法

    • hClick 自定义事件

    • this.$emit("hClick") 触发事件

    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      var father = {
      template:
      `
      <div>
      <button @click="handleClick"></button>
      <!-- 静态传值 zhangsan -->
      <son name="name"></son>
      <!-- 动态传值 zhangsi -->
      <son :name="name" @hClick="handleClick"></son>
      </div>
      `,
      data() {
      return {
      name: "zhangsan"
      }
      },
      methods: {
      handleClick (){
      this.name = "zhangsi"
      }
      }
      }

      var son = {
      props: ['name'],
      template:
      `
      <div>
      <p>{{name}}</p>
      </div>
      `
      }

兄弟组件通信

  • 1.创建一个gege组件,一个didi组件

  • 2.创建 eventBus对象,let eventBus = new Vue()

  • 3.gege 组件通过eventBus.$emit("自定义事件", 数据)

  • 4.didi 组件通过eventBus.$on("自定义事件", callbackFn)

  • let eventBus = new Vue();
    
    var gege = {
        data (){
            return {
                name: 'gege',
            }
        },
        methods: {
            handlePass (){
                eventBus.$emit('receive', this.name)
            }
        }
    }
    
    var didi = {
        data (){
            return {
                name: 'didi',
            }
        },
        methods: {
        },
        created (){
            handlePass (){
                // 监听方法
                eventBus.$on('receive', function(res){
                    console.log(res)
                })
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    ### 跨级组件通讯

    yeye组件,想给sunzi组件通信

    - 爷爷组件

    - provide , 数据提供者
    - inject , 数据接收者,
    - yeye组件不需要知道哪些sunzi组件使用了它 provide 的 property
    - sunzi组件不需要知道 inject 的 property 来自哪

    const app = Vue.createApp({}) app.component('grandfa', { data() { return { todos: ['Feed a cat', 'Buy tickets'], name: "zhangsan" } }, methods: { handleChange(){ this.name = "lisi" } } provide: { // 返回 this的属性值, 就必须返回对象 return { name: {name: this.name} getname: ()=>{ {username: this.name} } }, template: ` <div> {{ todos.length }} <!-- 模板的其余部分 --> <button @click="handleChange"></button> </div> ` }) app.component('grandson', { inject: ["name", "getname" ], computed: { username (){ return this.getname().username } } template: ` <div> {{ todos.length }} <!-- 模板的其余部分 --> </div> ` })
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
      





    ### 插槽

    具名插槽

    - 具有名字的插槽

    - 使用 <slot> 中的 "name" 属性绑定元素

    - ```
    <!DOCTYPE html>
    <html lang="en">

    <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    </head>

    <body>
    <div id="app">
    <grandfa>

    <template #mySolt>
    <h2>我在哪里呢1</h2>
    </template>
    <template #default>
    <h3>laoer</h3>
    </template>
    </grandfa>


    </div>
    <script src="./js/vue.js"></script>
    <script type="" ></script>
    <script>


    Vue.component('grandfa', {

    data() {
    return {
    todos: ['Feed a cat', 'Buy tickets'],

    }
    },
    methods: {
    handleChange(res) {
    eventBus.$emit("transmini", this.todos)
    }
    },
    template: `
    <div>
    <hr></hr>
    <h1>具名插槽</h1>
    <slot name="mySolt"></slot>
    <hr></hr>

    <h1>默认插槽</h1>
    <slot></slot>
    <hr></hr>

    <grandson @handle="handleChange"></grandson>
    </div>
    `,


    })

    Vue.component('grandson', {

    props: ["name", "handle"],
    data (){
    return {
    list: null,
    }
    },
    template: `
    <div>

    <button @click="handleClick">点击事件</button>
    <p>{{list}}</p>

    </div>
    `,
    methods: {
    handleClick(){
    this.$emit("handle", "数据1")
    console.log(1);
    }
    },


    })

    new Vue({
    el: "#app",
    })

    </script>
    </body>

    </html>

​ 作用域插槽

  • 父组件对子组件加工处理

  • 既可以复用子组件的slot,又可以使slot内容不一致

  • <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <div id="app">
            <grandfa>
    
                <template #mySolt>
                    <h2>我在哪里呢1</h2>
    
                </template>
                <template #default>
                    <h3>laoer</h3>
                </template>
            </grandfa>
    
    
  </div>
  <script src="./js/vue.js"></script>
  <script type="" ></script>
  <script>


      Vue.component('grandfa', {

          data() {
              return {

              }
          },
          methods: {
          },
          template: `
              <div>

              <grandson  @handle="handleChange">
                  <!----作用域插槽----->
                  <template slot-scope="slotProps">
                  <h4>{{slotProps}}</h4>
                      <ul>
                      <li v-for="item in slotProps.list">
                          {{item}}
                      </li>
                      </ul>
                  </template>

              </grandson>
              </div>
          `,


      })

      Vue.component('grandson', {

          props: ["name", "handle"],
          data (){
              return {
                  list: [1,23,4234,32432,2432,43,2,4,32],
              }
          },
          template: `
              <div>

              <slot :list="list"></slot>

              </div>
          `,
          methods: {
              handleClick(){
                  this.$emit("handle", "数据1")
                  console.log(1);
              }
          },


      })

      new Vue({
          el: "#app",


      })

  </script>
```
------ 本文结束------

欢迎关注我的其它发布渠道