Vue組件傳值、refs、插槽


一、組件傳值

1.父組件向子組件傳值

因為子組件本身不能拿到父組件的data數據來用,所以在子組件里用props接收,props是一個數組

父組件向子組件傳值
<div id="app">
    <com1 :parent="msg" :parentarr="arr"></com1>
</div>
<template id="com">
    <div>
        {{parent}}
        <ul>
            <li v-for="i in parentarr">{{i}}</li>
        </ul>
    </div>
</template>
<script src="lib/vue-2.4.0.js"></script>
<script type="text/javascript">            
var vm=new Vue({
    el:"#app",
    data:{
        msg:"父組件的msg",
        arr:[1,2,3],
    },
    components:{
        com1:{
            template:"#com",
            props:["parent",'parentarr'],//父組件向子組件傳值,用props    
        }
    }
})
</script>

2.子組件向父組件傳值

子組件不能直接使用父組件的data和methods,子組件向父組件傳值用 @和$emit實現(通過函數的形式傳出,在父組件接收)

做法:

在父組件里定義一個@xxx="xxx2"的方法,父組件把方法傳遞給子組件,this.$emit()的第一個參數和xxx的名稱一樣,父元素的方法xxx2傳一個實參進去就相當於是當前傳回來的值

this.$emit("fun1",this.xxx) 方法名字/要傳出的值

子組件向父組件傳值
<div id="app1">
    <com-name @fun1="getData"></com-name>
</div>

<template id="com2">
    <div>
        <button @click="getsonData">調用父組件的getdata</button>
    </div>
</template>
<script src="lib/vue-2.4.0.js"></script>
<script type="text/javascript">
var vm=new Vue({
    el:"#app1",
    data:{
        fromson:""
    },
    methods:{
        getData(x){//傳實參
            console.log("父元素的方法getdata拿到子組件里的數據是==="+x)
            this.fromson=x;
        }
    },
    components:{
        comName:{
            template:"#com2",
            data(){
                return {
                    sonmsg:"子組件里的msg"
                }
            },
            methods:{
                getsonData(){
                    this.$emit("fun1",this.sonmsg)//$emit調用fun1
                }
            }
        },
        
    }
})
</script>

二、refs獲取dom節點

Vue不提倡用原生的dom操作獲取節點,它封裝了自己的方法來實現獲取dom

做法:

給要獲取的dom一個ref屬性,起一個名字,通過this.$refs來得到組件里所有有ref屬性的dom節點,返回的是一個json

<div id="app">
   <p ref="p1">父組件里的p</p>
   <button @click="getCon">獲取內容</button>
   <com ref="login"></com>
</div>
<template id="login">
    <div>
        <p>{{sonmsg}}</p>
    </div>
</template>
<script src="lib/vue.js"></script>
<script>
    Vue.component("com",{
        template:"#login",
        data(){
            return {
                sonmsg:"子組件的msg"
            }
        },
    })
    var vm=new Vue({
        el:"#app",
        methods:{
            getCon(){
                console.log(this.$refs.login.sonmsg)//子組件的msg
                console.log(this.$refs.p1.innerHTML)//父組件里的p
            }
        }
    })
</script>

那么,子組件向父組件傳值就有倆種方法

①用@和$emit

②組件也可以有ref屬性,可以通過組件的ref屬性拿到子組件的data和method

三、插槽 (slot)

插槽是將父組件中的子組件模板數據正常顯示出來

假設組件的名稱為child

1.插槽的概念

child組件開標簽和閉標簽之間的內容正常不會顯示在頁面中,如果想要讓他顯示,用slot標簽代表這些內容,想要讓她在哪兒顯示就放在模板的哪個位置

理解插槽:

組件就相當於是封裝的html 那么插槽就相當於是封裝函數里的參數,是每次調用時候都可以賦不同的值的東西

2.具名插槽(傳遞name屬性)

給放在child開標簽和閉標簽之間的模板或者組件加上v-slot:自定義名字  的指令,在用的時候使用slot標簽,在子組件中的 <slot><slot> 里面添加 name='自定義名字' ,通過name屬性選擇調用哪個插槽。如果父組件中有一部分沒有添加 slot 屬性,則此處就是默認的插槽,在子組件中的slot直接就是使用的父組件的默認插槽部分

3.后備內容

在<slot></slot>標簽中的內容將在沒有匹配到插槽內容時渲染

4.作用域插槽

插槽雖然是屬於這個組件的,但是因為他沒有放在組件的模板里,所以不能直接使用組件的data數據,如果要想使用組件的data 應該用屬性傳值的方法把數據傳過去 在插槽里通過v-slot:xx="" 等號后面的值接收數據,接收到的數據是一個json 因為有可能傳過來不只一個值

v-slot:xx="yy"  xx代表插槽的名字 yy代表接收到組件的data數據

<div id="app">
    <child>
        <template   v-slot:head="datas">
            <div>
                <h5>組件child里的頭部模板=={{datas.textcon}}</h5>
            </div>
        </template>
        
        <template v-slot:foot>    
            <div>
                <h5>組件child里的尾部模板</h5>
            </div>
        </template>

        <template>
            <div>我是一個沒有名字的插槽</div>
        </template>
    </child>

    <child>
        <template v-slot:head>
            <div>
                <h4>第二次調用組件child的頭部模板</h4>
            </div>
        </template>
        <template v-slot:foot>
            <div>
                <h4>第二次調用組件child的的尾部模板</h4>
            </div>
        </template>
    </child>

</div>
<template id="login">
    <div>
        <header>
            <slot name="head" :textcon="text" ></slot>
        </header>
        <p>{{text}}</p>
        <slot>AA</slot>
        <!-- 后備內容放在slot標簽里,如果插槽沒有傳過來內容的話 默認顯示AA,如果傳過來內容就取代AA -->
        <footer>
            <slot name="foot"></slot>
        </footer>
    </div>
</template>
<script src="lib/vue.js"></script>
<script>
    Vue.component("child", {
        template: "#login",
        data() {
            return {
                text: "子組件的內容",
            }
        },
    })

    var vm = new Vue({
        el: "#app",
    })
</script>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM