1. 程式人生 > 其它 >11組-Beta衝刺-5/5

11組-Beta衝刺-5/5

Vue 元件傳值

一. 父子元件傳值

​ 步驟: 1. 在子元件標籤中通過v-bind把自定義屬性賦值為父元件的動態資料

​ 2. 在子元件物件中通過props欄位新增自定義屬性
​ props: ["myData"]
​ 3, 在子元件模板中, 使用自定義屬性渲染資料
{{myData}}

<body>
    <script src='vue.js'></script>
    <!-- vue模板 -->
    <div id='myApp'>
        父元件中的輸入: 
        <input type="text" v-model="name"> <br>
        <hr>
        子元件的顯示:
        <my-com :my-data="name"></my-com>
    </div>
    <!-- 元件模板 -->
    <template id='com'>
        <span>
            {{myData}}
        </span>
    </template>  
    <script>
        // 元件
        Vue.component('myCom',{
            template: '#com',
            // 使用props欄位新增自定義屬性,用於接收父元件傳值, 值是陣列結構
            props: ["myData"],
            // created() {
            //     console.log(this.myData)
            // },
            // watch:{
            //     myData(newValue){console.log(newValue)}
            // },
            // computed:{ }
        })
        // 根元件
        var vm = new Vue({
            el: '#myApp',
            data: {
                name: "張三"
            }
        })
        // 總結: 父元件向子元件傳值步驟: 
        // 1, 在子元件物件中通過props欄位新增自定義屬性
            // props: ["myData"]
        // 2, 在子元件標籤中通過v-bind把自定義屬性賦值為父元件的動態資料
            // <my-com :my-data="name"></my-com>
        // 3, 在子元件模板中, 使用自定義屬性渲染資料
            // <span> {{myData}} </span>
    </script>

二 . 子傳父

<body>
    <script src='vue.js'></script>
    <!-- vue模板 -->
    <div id='myApp'>
        <!-- 在元件標籤上使用v-on繫結自定義事件, 呼叫父元件中的函式  -->
        <my-com @myevent="getData"></my-com> <hr>
        父元件顯示: {{fatherData}}
    </div>
    <!-- 元件模板 -->
    <template id='com'>
        <div>
            子元件輸入: <input type="text" v-model="childData">
        </div>
    </template>
    <script>
        // 元件
        Vue.component('myCom',{
            template: '#com',
            data(){
                return{
                    childData: "child"
                }
            },
            watch:{
                childData(newValue){
                    // 監聽到子元件資料更新時,把新資料傳送給父元件
                    // 原理: 子元件呼叫$emit函式發射一個自定義事件, 在父元件中監聽事件並在事件函式中取值
                    this.$emit("myevent", newValue) 
                    // 引數一是自定義事件名, 事件名必須用小寫
                    // 引數二是傳送的資料
                }
            }
        })
        // 根元件
        var vm = new Vue({
            el: '#myApp',
            data: {
                fatherData:""
            },
            methods: {
                //在父元件的事件函式中拿到引數中的資料並展示
                getData(data){
                    this.fatherData = data
                }
            }
        })
        // 總結: 子元件向父元件傳值的步驟:
        // 1, 在子元件中合適的位置, 通過$emit函式發射自定義事件,把資料發出去
            // this.$emit("myevent", newValue) 
        // 2, 在子元件標籤上, 通過v-on繫結自定義事件,呼叫父元件中的事件函式
            // <my-com @myevent="getData"></my-com>
        // 3, 在父元件的事件函式中拿到引數中的資料並展示
            //  getData(data){ this.fatherData = data } 
    </script>
</body>

三 . 非父子元件傳值

 <script src='vue.js'></script>
    <!-- vue模板 -->
    <div id='myApp'>
        <my-com1></my-com1>
        <my-com2></my-com2>
    </div>
    <!-- 元件模板 -->
    <template id='com1'>
        <div>
            元件1輸入 : <input type="text" v-model="name">
        </div>
    </template>
    <template id='com2'>
        <div>
            元件2顯示 : {{name2}}
        </div>
    </template>
    <script>

        // 匯流排: 在全域性作用域建立一個空的vue物件,視作匯流排.用於非父子傳值
        var bus = new Vue();

        // 元件1
        Vue.component('myCom1',{
            template: '#com1',
            data(){
                return{
                    name:"張三"
                }
            },
            watch: {
                name(value){
                    // 呼叫$emit自定義事件把資料發出去
                    // this.$emit()
                    // 使用bus匯流排呼叫$emit傳送資料
                    bus.$emit("myevent", value)
                    console.log("傳送")
                }
            }
        })
        // 元件2
        Vue.component('myCom2',{
            template: '#com2',
            data(){
                return{
                    name2: ""
                }
            },
            created() {
                console.log(this)
                // 在另一個元件的初始化函式created中使用bus匯流排監聽自定義事件,取值
                // bus.$on("myevent", function(data){
                //     // 在事件函式中this指向事件目標bus, 不是當前元件com2
                //     console.log("接收",data, this)
                //     this.name2 = data
                // })
                // 使用箭頭函式保證函式中的this和函式外的this保持一致為com2
                bus.$on("myevent", (data)=>{
                    // 在事件函式中this指向事件目標bus, 不是當前元件com2
                    console.log("接收",data, this)
                    this.name2 = data
                })

                // 注意: 每一個元件物件中都有屬性 _uid 它是一個索引值, 記錄的是這個元件建立的順序(第一個建立的元件,_uid是0, 往後依次增加)
            },
        })
        // 根元件
        var vm = new Vue({
            el: '#myApp',
            data: {
            },
            methods: {
            }
        })
    
        // 總結: 非父子元件傳值/兄弟元件傳值/bus匯流排傳值  
        // 1, 在全域性作用域中建立空的vue物件, 稱之為匯流排bus
            // var bus = new Vue();
        // 2, 在一個元件中合適的位置,通過bus匯流排呼叫$emit傳送資料
            // bus.$emit("myevent", value)
        // 3, 在另一個元件中的初始化函式created中,使用bus匯流排監聽事件, 接收資料並展示
            // bus.$on("myevent", (data)=>{ this.name2 = data })
           </script>

四 . 插槽傳值

 <script src='vue.js'></script>
    <!-- vue模板 -->
    <div id='myApp'>
        父元件輸入:                           
        <input type="text" v-model="name"> <hr>
        <my-com>預設在元件標籤之間的資訊會被忽略</my-com>
        <!-- 把父元件中的動態資料寫入子元件標籤中 -->
        <my-com>{{name}}</my-com>
    </div>
    <!-- 元件模板 -->
    <template id='com'>
        <div>
            <!-- 使用slot插槽標籤顯示子元件標籤中的資訊 -->
            子元件顯示: <slot></slot>
        </div>
    </template>
    <script>
        // 元件
        Vue.component('myCom',{
            template: '#com',
            created() {
                // 在元件物件中拿不到插槽資料
            },
        })
        // 根元件
        var vm = new Vue({
            el: '#myApp',
            data: {
                name: "張三"
            }
        })

五 . 具名插槽

    <script src='vue.js'></script>
    <!-- vue模板 -->
    <div id='myApp'>
        <my-com>父元件動態資料</my-com> <hr>
        <my-com>
            <span slot="s1">父元件資料1</span>
            <span slot="s2">父元件資料3</span>
        </my-com>
    </div>
    <!-- 元件模板 -->
    <template id='com'>
        <div>
            <!-- 子元件模板中的每一個slot標籤都會把插槽資料渲染一遍 -->
            <!-- 子元件顯示: <slot></slot> <slot></slot> -->

            <!-- 當給slot標籤新增name屬性時, slot插槽就叫具名插槽 -->
            <!-- 具名插槽: 作用可以把插槽中的部分資料分發給不同的slot標籤單獨渲染 -->
            <slot name="s1"></slot> <br>
            子元件資料2 <br>
            <slot name="s2"></slot>
        </div>
    </template>
    <script>
        // 元件
        Vue.component('myCom',{
            template: '#com'
        })
        // 根元件
        var vm = new Vue({
            el: '#myApp'
        })
        // 總結: 插槽的用法
        // 1, 子元件模板中slot標籤如果沒有name屬性會把插槽資料全部渲染
        // 2, slot標籤新增name屬性後,只會渲染插槽資料中擁有slot屬性且name屬性和slot屬性值相同的資料
    </script>