11組-Beta衝刺-5/5
阿新 • • 發佈:2021-11-27
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>