• 组件通信


    组件通信

    1.为什么要进行组件通信

    ​ 组件可以说是具有独立功能的整体,但是当我们要将这些组件拼接在一起的时候,这些组件相互之间要建立联系,这个联系我们就称之为通信

    2.组件通信的方式有一下几种

    ​ 1.父子组件通信

    ​ 使用props来实现

    ​ 2.子父组件通信

    ​ 自定义事件

    ​ 3.非父子组件通信

    ​ ref链

    ​ bus事件总线

    ​ 4.多组件状态共享(多个组件共用同一个数据) 大知识点(vuex) 这边只讲前3个

    ​ vuex

    知识点: app实例的手动挂载

    ​ new Vue({
    ​ el:'#app'
    ​ }).$mount('#app')


    父子组件通信

    案例:

    <body>
        <div id='app'>
            <father></father>
        </div>
    
    
        <template id='father'>
            <div>
                <p>这是Father组件</p>
                <hr>
                <son :qwer = "money"></son>   
                <!-- 子组件做数据绑定   绑定父组件里面的数据 -->
            </div>
        </template>
    
        <template id='son'>
            <div>
                <p>这是son组件</p>
                <p>父亲给了我{{qwer}}元</p>  
                <!-- 子组件可以全局调用这个数据 -->
            </div>
        </template>
    
    
        <script>
            // props
            //     1.在父组件的模板中将数据用单项数据绑定的形式,绑定在子组件上
            //     2.在子组件的配置项中可以使用一个props配置项来接收这个数据,接收时,props的取值可以是一个数组
            //     3.在子组件模板中,接收到的属性可以像全局一样使用
    
    
            // 这里全局注册Father这个组件
            Vue.component('Father', {
                template: '#father',
                data() {
                    return {
                        money: 2000
                    }
                }
            })
    
            // 这里全局注册Son这个组件
            Vue.component('Son', {
                template: '#son',
                props: ['qwer'] //子组件用props来接收这个数据
            })
    
    
            new Vue({
                el: '#app'
            })
        </script>
    </body>
    

    产生的问题:

    问题一:props接收的money和子组件上绑定的自定义属性money是不是同一个?     
          
          不是, 绑定自定义属性名字可以自定义(个人一般会写成一样的)
    
          注意:自定义命名不能有大写字母 用-a来表示
    
    问题二:为什么data要定义一个函数
            1.组件是一个独立的个体,那么他应该拥有自己的数据,这个数据应该是一个独立的数据
            2.也就是说这个数据应该有独立的作用域(需要一个独立的使用范围,这个范围就是这个组件内)
            3.函数提供了独立的作用域
            
    问题三:为什么data要有返回值?返回值还是一个对象
    
            因为Vue是通过observe来观察data选项的,所以必须要有返回值
            因为Vue要通过es5的Object.defineProperty属性对对象进行getter和setter设置
    

    子父组件通信

    <body>
        <div id="app">
            <Father></Father>
        </div>
    
        <template id='father'>
            <div>
                <h3>这里是father组件</h3>
                <p>儿子给了我{{money}}元钱</p>
                <Son @give='getHongbao'></Son>  
                <!--  这里是第一步! 绑定一个自定义事件在子组件身上 -->
            </div>
        </template>
    
        <template id='son'>
                <div>
                    <button @click = 'giveFather'>give</button>
                    <h3>这里是son组件</h3>
                </div>
        </template>
    
    
        <script>
            Vue.component('Father', {
                template: '#father',
                data() {
                    return {
                        money: 0
                    }
                },
                methods: {
                    getHongbao(val) {
                        console.log(1)
                        this.money = val
                    }
                }
            })
    
            Vue.component('Son', {
                template: '#son',
                data() {
                    return {
                        hongbao: 500 //要把这个数据发给父组件 , 首先要在父组件中定义一个数据用来接收这个数据
                    }
                },
                methods: {
                    giveFather() {
                        //如何进行父组件给子组件的自定义事件触发?
                        // 这里是第二步骤!!!
                        this.$emit('give', this.hongbao)
                    }
                }
            })
    
            new Vue({
                el: '#app',
            })
        </script>
    
        <!-- 自定义事件
            1.自定义的 通过 $on 定义  $emit用来触发
    
            2.通过绑定在组件身上定义   $emit用来触发 -->
    
    
        <!-- 总结:   
                1.在父组件的模板中,通过事件绑定的形式,绑定一个自定义事件在子组件身上 
                
                2.在子组件中 (子组件的配置项methods中)写一个事件处理函数,在事件处理函数中触发父组件绑定的自定义事件
    
                3.将子组件定义的事件处理函数 绑定在子组件的按钮身上(点击触发 实现步骤2) -->
    </body>
    

    非父子组件通信(ref链)

    <body>
        <div id="app">
            <Father></Father>
        </div>
    
        <template id="father">
            <div>
                <h3>这里是father</h3>
                <button @click = 'look'>点击查看father的this</button>
                <p>father的n: {{ n }}</p>
                <hr>
                <Son ref = 'son'></Son>
                <hr>
                <Girl ref = 'girl' :n = 'n'></Girl>   
    
                <!-- 通过ref绑定组件后,我们发现在他们共同父组件的$refs里面可以找到子组件 -->
    
            </div>
        </template>
    
        <template id="son">
            <div>
                <h3>这里是son组件</h3>
            </div>
        </template>
    
    
        <template id="girl">
            <div>
                <h3>这里是girl组件</h3>
                <button @click = 'out'> 输出girl的this </button>
            </div>
        </template>
    
        <script>
            Vue.component('Father', {
                template: '#father',
                data() {
                    return {
                        n: 0
                    }
                },
                methods: {
                    look() {
                        this.n = this.$refs.son.money
                    }
                }
            })
    
            Vue.component('Son', {
                template: '#son',
                data() {
                    return {
                        money: 1000
                    }
                }
            })
    
            Vue.component('Girl', {
                template: '#girl',
                data() {
                    return {
                        num: 0
                    }
                },
                methods: {
                    out() {
                        console.log(this)
                        console.log(this.$attrs.n)
                    }
                }
            })
    
    
            new Vue({
                el: '#app'
            })
        </script>
    
        <!-- 总结:ref链可以实现非父子组件的通信,但是如果层级太多就比较繁琐了 -->
    </body>
    

    非父子组件通信(bus事件总线)

        <div id='app'>
            <Bro></Bro>
            <Sma></Sma>
        </div>
    
        <template id="big">
            <div>
                <h3>这里是哥哥组件</h3>
                <button @click = 'hick'>揍</button>
            </div>
        </template>
    
        <template id="sma">
            <div>
                <h3>这里是弟弟组件</h3>
                <p v-show = 'flag'>呜呜呜呜呜呜wuwuwuu</p>
            </div>
        </template>
    
        <script>
            var bus = new Vue()
    
            Vue.component('Bro', {
                template: '#big',
                methods: {
                    hick() {
                        bus.$emit('aa');
                    }
                }
            })
    
            Vue.component('Sma', {
                template: '#sma',
                data() {
                    return {
                        flag: false
                    }
                },
                mounted() {
                    var _this = this
    
                    //当前组件挂载结束,也就是我们在页面当中看到真实的dom
                    //mounted这个钩子函数的触发条件是组件创建时会自动触发
                    bus.$on('aa', function() {
    
                        _this.flag = true
    
                    })
                }
            })
    
            new Vue({
                el: '#app'
            })
        </script>
        
        <!-- 总结:
            1.在其中一个组件的挂载钩子函数上做事件的声明
    
            2.在另一个组件中,通过 bus.$emit('事件名称')来触发自定义事件 -->
    

    非常规手段(不推荐使用)

    子父通信

    <body>
        <div id='app'>
            <Father></Father>
        </div>
    
        <template id='father'>
            <div>
                <h3>这里是father组件</h3>
                <p>这里是父组件的n:{{n}}</p>
                <Son :add = 'add'></Son>
            </div>
        </template>
    
        <template id='son'>
                <div>
                    <h3>这里是son组件</h3>
                    <button @click = 'add(2000)'>give</button>
                </div>
        </template>
    
        <script>
            //我们要进行子父组件通信
            //理解:使用自定义事件实现
    
            Vue.component('Father', {
                template: '#father',
                data() {
                    return {
                        n: 0
                    }
                },
                methods: {
                    add(val) {
                        this.n = val
                    }
                }
            })
    
            Vue.component('Son', {
                template: '#son',
                data() {
                    return {
                        money: 1000
                    }
                },
                props: ['add']
            })
    
            new Vue({
                el: '#app'
            })
        </script>
    </body>
    

    动态组件

    1.什么是动态组件

    ​ 可以改变的组件

    2.使用

    ​ 通过Vue提供了一个component+is属性使用

    3.动态组件指定就是component这个组件

      <div id="app">
        <button @click = "change"> 切换 </button>
        <!-- <keep-alive include="">
          <component :is = "type"></component>
        </keep-alive> -->
        
        
        <component :is = "type"></component>
    
      </div>
    </body>
    <script>
    /* 
      业务: 点击一个按钮进行两个组件的切换
    
     */
      Vue.component('Aa',{
        template: '<div> Aa </div>'
      })
    
      Vue.component('Bb',{
        template: '<div> Bb </div>'
      })
    
      new Vue({
        data: {
          type: 'Aa'
        },
        methods: {
          change () {
            this.type = (this.type === 'Aa'?'Bb':'Aa')
          }
        }
      }).$mount('#app')
    </script>
    
  • 相关阅读:
    ruby 二进制转十进制 Integer("0b101") = 5
    开始菜单和我的文档的我的图片及我的音乐变成 my pictrues 正常图标了
    ruby watir 莫名其妙的错误
    Excel SaveAS是去掉提示框
    apache && jboss安装
    ruby require include的区别
    ruby控制鼠标
    This error is raised because the column 'type' is reserved for storing the class in case of inheritance
    用正则表达式限制文本框只能输入数字,小数点,英文字母,汉字等各类代码
    ASP.NET 如何动态修改 Header 属性如添加 Meta 标签 keywords description!
  • 原文地址:https://www.cnblogs.com/xiaohanga/p/11087241.html
Copyright © 2020-2023  润新知