實戰技巧,Vue原來還可以這樣寫
hookEvent,原來可以這樣監聽組件生命周期
1. 內部監聽生命周期函數
<template>
<div class="echarts"></div>
</template>
<script>
export default {
mounted() {
this.chart = echarts.init(this.$el)
// 請求數據,賦值數據 等等一系列操作...
// 監聽窗口發生變化,resize組件
window.addEventListener('resize', this.$_handleResizeChart)
},
updated() {
// 幹了一堆活
},
created() {
// 幹了一堆活
},
beforeDestroy() {
// 組件銷毀時,銷毀監聽事件
window.removeEventListener('resize', this.$_handleResizeChart)
},
methods: {
$_handleResizeChart() {
this.chart.resize()
},
// 其他一堆方法
}
}
</script>
這樣寫不是很好,應該將監聽resize事件與銷毀resize事件放到一起,現在兩段程式碼分開而且相隔幾百行程式碼,可讀性比較差
export default {
mounted() {
this.chart = echarts.init(this.$el)
// 請求數據,賦值數據 等等一系列操作...
// 監聽窗口發生變化,resize組件
window.addEventListener('resize', this.$_handleResizeChart)
// 通過hook監聽組件銷毀鉤子函數,並取消監聽事件
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('resize', this.$_handleResizeChart)
})
},
updated() {},
created() {},
methods: {
$_handleResizeChart() {
// this.chart.resize()
}
}
}
在Vue組件中,可以用過$on,$once去監聽所有的生命周期鉤子函數,如監聽組件的updated鉤子函數可以寫成 this.$on('hook:updated', () => {})
2. 外部監聽生命周期函數
<template>
<!--通過@hook:updated監聽組件的updated生命鉤子函數-->
<!--組件的所有生命周期鉤子都可以通過@hook:鉤子函數名 來監聽觸發-->
<custom-select @hook:updated="$_handleSelectUpdated" />
</template>
<script>
import CustomSelect from '../components/custom-select'
export default {
components: {
CustomSelect
},
methods: {
$_handleSelectUpdated() {
console.log('custom-select組件的updated鉤子函數被觸發')
}
}
}
</script>
小項目還用Vuex?用Vue.observable手寫一個狀態管理吧
在前端項目中,有許多數據需要在各個組件之間進行傳遞共享,這時候就需要有一個狀態管理工具,一般情況下,我們都會使用Vuex,但對於小型項目來說,就像Vuex官網所說:「如果您不打算開發大型單頁應用,使用 Vuex 可能是繁瑣冗餘的。確實是如此——如果您的應用夠簡單,您最好不要使用 Vuex」。這時候我們就可以使用Vue2.6提供的新API Vue.observable手動打造一個Vuex
創建 store
import Vue from 'vue'
// 通過Vue.observable創建一個可響應的對象
export const store = Vue.observable({
userInfo: {},
roleIds: []
})
// 定義 mutations, 修改屬性
export const mutations = {
setUserInfo(userInfo) {
store.userInfo = userInfo
},
setRoleIds(roleIds) {
store.roleIds = roleIds
}
}
在組件中引用
<template>
<div>
{{ userInfo.name }}
</div>
</template>
<script>
import { store, mutations } from '../store'
export default {
computed: {
userInfo() {
return store.userInfo
}
},
created() {
mutations.setUserInfo({
name: '逐夢'
})
}
}
</script>
深度watch與watch立即觸發回調,我可以監聽到你的一舉一動
Vue.extend是一個全局Api,平時我們在開發業務的時候很少會用到它,但有時候我們希望可以開發一些全局組件比如Loading,Notify,Message等組件時,這時候就可以使用Vue.extend。
基礎用法
比如一個列表頁,我們希望用戶在搜索框輸入搜索關鍵字的時候,可以自動觸發搜索,此時除了監聽搜索框的change事件之外,我們也可以通過watch監聽搜索關鍵字的變化
<template>
<!--此處示例使用了element-ui-->
<div>
<div>
<span>搜索</span>
<input v-model="searchValue" />
</div>
<!--列表,程式碼省略-->
</div>
</template>
<script>
export default {
data() {
return {
searchValue: ''
}
},
watch: {
// 在值發生變化之後,重新載入數據
searchValue(newValue, oldValue) {
// 判斷搜索
if (newValue !== oldValue) {
this.$_loadData()
}
}
},
methods: {
$_loadData() {
// 重新載入數據,此處需要通過函數防抖
}
}
}
</script>
立即觸發
通過上面的程式碼,現在已經可以在值發生變化的時候觸發載入數據了,但是如果要在頁面初始化時候載入數據,我們還需要在created或者mounted生命周期鉤子裡面再次調用$_loadData方法。不過,現在可以不用這樣寫了,通過配置watch的立即觸發屬性,就可以滿足需求了
// 改造watch
export default {
watch: {
// 在值發生變化之後,重新載入數據
searchValue: {
// 通過handler來監聽屬性變化, 初次調用 newValue為""空字元串, oldValue為 undefined
handler(newValue, oldValue) {
if (newValue !== oldValue) {
this.$_loadData()
}
},
// 配置立即執行屬性
immediate: true
}
}
}
深度監聽(我可以看到你內心的一舉一動)
一個表單頁面,需求希望用戶在修改表單的任意一項之後,表單頁面就需要變更為被修改狀態。如果按照上例中watch的寫法,那麼我們就需要去監聽表單每一個屬性,太麻煩了,這時候就需要用到watch的深度監聽deep
export default {
data() {
return {
formData: {
name: '',
sex: '',
age: 0,
deptId: ''
}
}
},
watch: {
// 在值發生變化之後,重新載入數據
formData: {
// 需要注意,因為對象引用的原因, newValue和oldValue的值一直相等
handler(newValue, oldValue) {
// 在這裡標記頁面編輯狀態
},
// 通過指定deep屬性為true, watch會監聽對象裡面每一個值的變化
deep: true
}
}
}
隨時監聽,隨時取消,了解一下$watch
有這樣一個需求,有一個表單,在編輯的時候需要監聽表單的變化,如果發生變化則保存按鈕啟用,否則保存按鈕禁用。這時候對於新增表單來說,可以直接通過watch去監聽表單數據(假設是formData),如上例所述,但對於編輯表單來說,表單需要回填數據,這時候會修改formData的值,會觸發watch,無法準確的判斷是否啟用保存按鈕。現在你就需要了解一下$watch
export default {
data() {
return {
formData: {
name: '',
age: 0
}
}
},
created() {
this.$_loadData()
},
methods: {
// 模擬非同步請求數據
$_loadData() {
setTimeout(() => {
// 先賦值
this.formData = {
name: '子君',
age: 18
}
// 等表單數據回填之後,監聽數據是否發生變化
const unwatch = this.$watch(
'formData',
() => {
console.log('數據發生了變化')
},
{
deep: true
}
)
// 模擬數據發生了變化
setTimeout(() => {
this.formData.name = '張三'
}, 1000)
}, 1000)
}
}
}
根據上例可以看到,我們可以在需要的時候通過this.$watch來監聽數據變化。那麼如何取消監聽呢,上例中this.$watch返回了一個值unwatch,是一個函數,在需要取消的時候,執行 unwatch()即可取消

