组件通讯

组件通讯

1.为何要进行组件通讯vue

​ 组件能够说是具备独立功能的总体,可是当咱们要将这些组件拼接在一块儿的时候,这些组件相互之间要创建联系,这个联系咱们就称之为通讯vuex

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

​ 1.父子组件通讯app

​ 使用props来实现dom

​ 2.子父组件通讯函数

​ 自定义事件this

​ 3.非父子组件通讯es5

​ ref链code

​ bus事件总线component

​ 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>
相关文章
相关标签/搜索