1.動態組件
前兩天產品經理來了新的需求了,告訴我,需要根據用戶的權限不同,頁面上要顯示不同的內容,然後我就哼哧哼哧的將不同權限對應的組件寫了出來,然後再通過v-if來判斷要顯示哪個組件,就有了下面的代碼
一般都會通過v-if,v-else-if去做判斷,,我感覺我的代碼潔癖症要犯了,不行,這樣code review過不了關,我連自己這一關都過不了,這時候就改動態組件發揮作用了。
<template>
<div class="info">
<component :is="roleComponent" v-if="roleComponent" />
</div>
</template>
<script>
import AdminInfo from './admin-info'
import BookkeeperInfo from './bookkeeper-info'
import HrInfo from './hr-info'
import UserInfo from './user-info'
export default {
components: {
AdminInfo,
BookkeeperInfo,
HrInfo,
UserInfo
},
data() {
return {
roleComponents: {
admin: AdminInfo,
bookkeeper: BookkeeperInfo,
hr: HrInfo,
user: UserInfo
},
role: 'user',
roleComponent: undefined
}
},
created() {
const { role, roleComponents } = this
this.roleComponent = roleComponents[role]
}
}
</script>
2.mixins,更高效的實現組件內容的複用
mixins是Vue提供的一種混合機制,用來更高效的實現組件內容的複用。怎麼去理解混入呢,我覺得和Object.assign,但實際與Object.assign又有所不同。
基本實例:在開發echarts圖表組件時,需要在窗口尺寸發生變化時,重置圖表的大小,此時如果在每個組件裏面都去實現一段監聽代碼,代碼重複太多了,此時就可以使用混入來解決這個問題
// 混入代碼 resize-mixins.js
import { debounce } from 'lodash'
const resizeChartMethod = '$__resizeChartMethod'
export default {
data() {
// 在組件內部將圖表init的引用映射到chart屬性上
return {
chart: null
}
},
created() {
window.addEventListener('resize', this[resizeChartMethod])
},
beforeDestroy() {
window.removeEventListener('reisze', this[resizeChartMethod])
},
methods: {
// 通過lodash的防抖函數來控制resize的頻率
[resizeChartMethod]: debounce(function() {
if (this.chart) {
this.chart.resize()
}
}, 100)
}
}
<!--圖表組件代碼-->
<template>
<div class="chart"></div>
</template>
<script>
import echartMixins from './echarts-mixins'
export default {
// mixins屬性用於導入混入,是一個數組,數組可以傳入多個混入對象
mixins: [echartMixins],
data() {
return {
chart: null
}
},
mounted() {
this.chart = echarts.init(this.$el)
}
}
</script>
3.使用.sync,更優雅的實現數據雙向綁定
在Vue中,props屬性是單向數據傳輸的,父級的prop的更新會向下流動到子組件中,但是反過來不行。可是有些情況,我們需要對prop進行“雙向綁定”。上文中,我們提到了使用v-model實現雙向綁定。但有時候我們希望一個組件可以實現多個數據的“雙向綁定”,而v-model一個組件只能有一個(Vue3.0可以有多個),這時候就需要使用到.sync。
.sync與v-model的異同
相同點:
兩者的本質都是語法糖,目的都是實現組件與外部數據的雙向綁定
兩個都是通過屬性+事件來實現的
不同點(個人觀點,如有不對,麻煩下方評論指出,謝謝):
一個組件只能定義一個v-model,但可以定義多個.sync
v-model與.sync對於的事件名稱不同,v-model默認事件爲input,可以通過配置model來修改,.sync事件名稱固定爲update:屬性名
自定義.sync
在開發業務時,有時候需要使用一個遮罩層來阻止用戶的行爲(更多會使用遮罩層+loading動畫),下面通過自定義.sync來實現一個遮罩層
<!--調用方式-->
<template>
<custom-overlay :visible.sync="visible" />
</template>
<script>
export default {
data() {
return {
visible: false
}
}
}
</script>