zoukankan      html  css  js  c++  java
  • 386 vue组件通信:概述,父组件传递给子组件 (props),子组件传递给父组件($emit)

    五、组件通讯 (介绍)

    导入 : 演示子组件访问父组件数据,发现报错 【父组件访问子组件数据,也报错】

    • 组件是一个独立、封闭的个体

      • 也就是说 : 默认情况下,组件中的数据, 只能在组件内部使用,无法直接在组件外部使用

      • 可以将 vue 实例看做一个组件

    • 对于组件之间需要相互使用彼此的情况,应该使用 组件通讯 机制来解决

    • 组件通讯的三种情况 :

      1. 父组件将数据传递给子组件(父 -> 子)
      2. 子组件将数据传递给父组件 (子 => 父)
      3. 非父子组件(兄弟组件)

    03-组件的通信.html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
    </head>
    
    <body>
        <div id="app">
            <!-- 报错 -->
            <div>{{ cmsg }}</div>
            <child></child>
        </div>
    
        <script src="./vue.js"></script>
        <script>
            /**/
            /**
              * 组件是独立 封闭的个体, 
                组件之间是不能直接访问数据的 , 根据组件之间的通信机制去访问
    
                通信机制
                1. 父组件把数据传递给子组件 (父传子)
                2. 子组件把数据传递给父组件 (子传父)
                3. 非父子之间传递数据 (兄弟级)
            */
    
            // 注册组件
            // 子组件
            Vue.component('child', {
                template: `
                    // 报错
                    <div> 子组件 : {{ pmsg }}  </div>
                `,
                data() {
                    return {
                        cmsg: '子组件的信息'
                    }
                }
            })
    
            // 父组件
            const vm = new Vue({
                el: '#app',
                data: {
                    pmsg: '父组件的数据'
                }
            })
        </script>
    </body>
    
    </html>
    

    六、父 ==> 子 (重点) 两步

    1. 通过属性, 父组件将要传递的数据,传递给子组件
    <child :msg="pmsg"></child>
    
    1. 子组件通过 props 配置项,来指定要接收的数据
    props: ['msg']
    
    // 以后使用
    - 组件内 :  msg
    - 事件中 : this.msg
    

    完善 TodoMVC => 完成 传值 + 渲染列表页


    04-父传子.html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
    </head>
    
    <body>
        <!-- 
            父传子 父组件的数据传递给子组件,
            父传子 (两步)
            1. 通过属性, 父组件把数据传递给子组件  :msg='pmsg'
            2. 子组件通过props配置项, 指定一下要接收过来的数据 props:['msg']
    	-->
    
        <div id="app">
            <!-- 第一步 : 通过属性, 父组件把数据传递给子组件 -->
            <child :msg="pmsg"></child>
        </div>
    
        <script src="./vue.js"></script>
        <script>
            // 子组件
            Vue.component('child', {
                template: `
                  	<div> 子组件 : {{ msg }} </div>
                 `,
                // 第二步 : 子组件通过 props 配置项 指定一下要接收过来的数据
                props: ['msg']
            })
    
            // 父组件
            const vm = new Vue({
                el: '#app',
                data: {
                    pmsg: '父组件里的信息'
                }
            })
        </script>
    </body>
    
    </html>
    

    七、子 ==> 父 (重点) 三步

    1. 父组件中定义一个方法
    // 【这里的父组件里不用写成bus中的$on,就methods中的一个普通方法。】
    pfn(arg) {
        console.log('父组件中接受到子组件传递过来的数据:', arg)
     }
    
    1. 通过自定义事件, 父组件将这个方法传递给子组件
    // 自定义事件,注意加 @ 
    <child @fn="pfn"></child>
    
    1. 子组件调用这个方法( 触发父组件中传递过来的自定义事件 )
    // 在钩子函数里演示也可以,自己调用
     created() {
        // 调用父组件中的方法 pfn
        // 注意:通过 $emit 方法来触发事件 fn 
        // 第一个参数:表示要触发的自定义事件名称,也就是 @fn
        // 第二个参数:表示要传递给父组件的数据
        this.$emit('fn', 'child msg')
    }
    

    完善 TodoMVC => 完成 传值 +添加+ 删除+修改数据+清除完成


    05-子传父.html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
    </head>
    
    <body>
        <!-- 
            子传父  子组件把数据传递给父组件  
            三步骤
            1. 父组件准备一个方法  pfn(){}
            2. 通过自定义事件, 把方法传递给子组件  @fn='pfn'
            3. 子组件通过$emit触发事件,等同于调用了这个方法
               this.$emit('fn','子组件里的数据')
          -->
        <div id="app">
            <!-- 第二步 : 通过自定义事件 把方法传递给子组件  -->
            <!-- 例子  @click="f"  注意加 @  -->
            <child @fn="pfn"></child>
        </div>
    
        <script src="./vue.js"></script>
        <script>
            // 子组件
            Vue.component('child', {
                template: `
                    <div> 子组件 :  </div>
                `,
                created() {
                    // 例子
                    // @click='f'
                    // 1. 点击 => 调用f
                    // 2. 手动触发 this.$emit('click') => f
    
                    // 第三步 : 子组件里面触发这个事件,就调用了pfn
                    // $emit(参数1:事件  参数2:传递的数据)
                    this.$emit('fn', '我是子组件里的数据')
                }
            })
    
            const vm = new Vue({
                el: '#app',
                data: {},
                // 第一步: 父组件准备好一个方法
                methods: {
                    // 【这里的父组件里不用写bus中的$on那样,就methods中的一个普通方法。】
                    pfn(res) {
                        console.log('pfn调用了:', res) // pfn调用了: 我是子组件里的数据
                    }
                }
            })
        </script>
    </body>
    
    </html>
    

    补充的案例

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    
    <body>
      <div id="app">
        <one @c-fn="pFn"></one>
      </div>
    
      <script src="./vue.js"></script>
      <!-- <script src="./node_modules/vuex/dist/vuex.js"></script> -->
    
      <script>
        Vue.component('one', {
          template: `<div><button @click="btnClick">按钮</button></div>`,
          methods: {
            btnClick() {
              console.log(111)
              this.$emit('c-fn', 222)
            }
          },
          created() {
            // this.$emit('c-fn', 333)
          },
        })
    
    
        const vm = new Vue({
          el: '#app',
          data: {
            msg: ''
          },
          methods: {
            pFn(param) {
              console.log('父组件', param)
            }
          }
        })
      </script>
    
    </body>
    
    </html>
    
  • 相关阅读:
    my eye
    html与HTML5的区别
    h5css样式
    h5css3弹性盒子
    简单js的介绍
    2020.8.16(周报6)
    2020.8.18
    2020.8.20
    2020.8.17
    2020.8.15
  • 原文地址:https://www.cnblogs.com/jianjie/p/12529378.html
Copyright © 2011-2022 走看看