舉個例子來解釋一下何為父組件,何為子組件?
index.vue導入sunui-cell組件的時候,我們就稱index.vue為父組件依次類推,在vue中只要能獲取到組件的實例,那么就可以調用組件的屬性或是方法進行操作
一、props(一般用來單向傳值)
1. 何為單向傳值?
即父組件傳值給子組件(首次)但不能動態(再次)改變子組件現有的值,但我非要改呢? 通過watch監聽或者通過$ref標識獲取實例后修改以及使用v-modal,使用v-modal會存在不同步情況->使用.sync
2.props靜態傳值
子組件通過props選項來聲明一個自定義的屬性,然后父組件就可以在嵌套標簽的時候,通過這個屬性往子組件傳遞數據 - 引用腳本之家
3. props動態傳值
通過v-bind綁定props的自定義的屬性,傳遞去過的就不是靜態的字符串了,它可以是一個表達式、布爾值、對象等等任何類型的值 - 引用腳本之家
4. props最適合傳遞數據,它並不能調用子組件里的屬性和方法
二、$ref
1.不大適合傳遞數據
主要用來調用子組件里的屬性和方法
2. 通常是初始化頁面(也就是視圖層渲染完以后)才能調用
如果是初始化的話建議在mounted生命周期或者使用this.$nextTick()將回調延遲到下次 DOM 更新循環之后執行(但我們首先得標識ref,相同組件ref的值如果重復會被后面的組件覆蓋),如果不是初始化的話必須要等待它加載完以后才能夠調用(this.nextTick)
三、$emit
1. $emit 綁定一個自定義事件event,當這個這個語句被執行到的時候,就會將參數arg傳遞給父組件,父組件通過@event監聽並接收參數
四、$on(非父組件之間傳值)
1.父組件需要導入A和B組件
<template>
<view class="content">
<view style="padding: 12px 15px;">
點擊hover效果
</view>
<onA></onA>
<onB></onB>
</view>
</template>
<script>
import onA from '@/components/onA.vue';
import onB from '@/components/onB.vue';
export default {
data() {
return {
title: 'Hello'
}
},
components: {
onA,
onB
},
onLoad() {
},
mounted() {
},
methods: {
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
2. onA組件
<template>
<view>
<button type="primary" @click="onSend">傳值給onB組件</button>
</view>
</template>
<script>
import bridge from '@/utils/bridge.js';
export default {
data() {
return {
msg: 'hello,onB'
};
},
methods: {
onSend() {
bridge.$emit('receiveA', this.msg);
}
},
mounted() {
bridge.$on('receiveB', (val) => {
console.log('我是onA組件,接收來自onB的值:', val);
});
}
}
</script>
<style>
</style>
3.onB組件
<template>
<view>
<button type="primary" @click="onSend">傳值給onA組件</button>
</view>
</template>
<script>
import bridge from '@/utils/bridge.js';
export default {
data() {
return {
msg: 'hello,onA'
};
},
methods: {
onSend() {
bridge.$emit('receiveB', this.msg);
}
},
mounted() {
bridge.$on('receiveA', (val) => {
console.log('我是onB組件,接收來自onA的值:', val);
});
}
}
</script>
<style>
</style>
4.bridge.js
import Vue from 'vue'
export default new Vue()
五、$parent(用於子組件獲取父組件實例) - 當前組件樹的根 Vue 實例。如果當前實例沒有父實例,此實例將會是其自己
六、$child - 當前實例的直接子組件。需要注意 $children
並不保證順序,也不是響應式的。如果你發現自己正在嘗試使用 $children
來進行數據綁定,考慮使用一個數組配合 v-for
來生成子組件,並且使用 Array 作為真正的來源
<template>
<view class="content">
<view style="padding: 12px 15px;">
點擊hover效果
</view>
<onA></onA>
<onB></onB>
</view>
</template>
<script>
import onA from '@/components/onA.vue';
import onB from '@/components/onB.vue';
export default {
data() {
return {
title: 'Hello'
}
},
components: {
onA,
onB
},
onLoad() {
},
mounted() {
console.log(this.$root.$children[0].$children[0]._data);
console.log(this.$root.$children[0].$children[1]._data.msg);
console.log(this.$root.$children[0].$children[2]._data.msg);
},
methods: {
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
七、$set - 在開發過程中,我們時常會遇到這樣一種情況:當vue的data里邊聲明或者已經賦值過的對象或者數組(數組里邊的值是對象)時,向對象中添加新的屬性,如果更新此屬性的值,是不會更新視圖的
1.運行這個示例時,我們發現對象新增的屬性(e)是不會更新的
<template>
<view>
<view @click="addd(obj)">點擊增加1:{{obj.d}}</view>
<view @click="adde(obj)">點擊增加2:{{obj.e}}</view>
</view>
</template>
<script>
export default {
data() {
return {
obj: {}
}
},
mounted() {
// 原有的
this.obj = {
d: 0
};
// 新增的對象.e
this.obj.e = 0;
console.log('after--', this.obj);
},
methods: {
addd(item) {
item.d = item.d + 1;
console.log('item--1', item);
},
adde(item) {
item.e = item.e + 1;
// this.$forceUpdate();
console.log('item--2', item);
}
}
}
</script>
2. 我們有兩種解決方案,一種是利用this.$set或者this.$foreUpdate();讓它渲染到視圖層 - 代碼引用簡書:https://www.jianshu.com/p/71b1807b1815
<template> <view> <view @click="addd(obj)">點擊增加1:{{obj.d}}</view> <view @click="adde(obj)">點擊增加2:{{obj.e}}</view> </view> </template> <script> export default { data() { return { obj: {} } }, mounted() { // 原有的 this.obj = { d: 0 }; // 新增的對象.e // this.obj.e = 0; this.$set(this.obj, 'e', 0); console.log('after--', this.obj); }, methods: { addd(item) { item.d = item.d + 1; console.log('item--1', item); }, adde(item) { item.e = item.e + 1; // this.$forceUpdate(); console.log('item--2', item); } } } </script>
理清一下已經使用過的vue實例,可能會再次更新(-.-)