1. 利用 v-bind="attrs"和 v−on="listeners" 简化组件通信
在开发复杂组件时,我们经常需要传递大量属性和事件。使用 v-bind=" <math xmlns="http://www.w3.org/1998/Math/MathML"> a t t r s " 和 v − o n = " attrs" 和 v-on=" </math>attrs"和v−on="listeners" 可以避免繁琐的逐个声明:
html
<!-- 父组件 -->
<template>
<child-component :name="name" :age="age" @update="handleUpdate" @delete="handleDelete" />
</template>
<!-- 子组件 -->
<template>
<grandchild-component v-bind="$attrs" v-on="$listeners" />
</template>
这样,所有属性和事件都会自动传递给孙组件,无需在中间组件中重复声明。
2. 使用 computed 的 setter 实现双向绑定
computed 不仅可以用于计算属性,还可以通过 setter 实现双向绑定:
JavaScript
export default {
data() {
return {
firstName: '张',
lastName: '三'
}
},
computed: {
fullName: {
get() {
return this.firstName + ' ' + this.lastName
},
set(value) {
const [first, last] = value.split(' ')
this.firstName = first
this.lastName = last
}
}
}
}
3. 使用 provide/inject 实现跨级组件通信
对于深层嵌套的组件通信,provide/inject 比 props 和事件更优雅:
JavaScript
// 祖先组件
export default {
provide() {
return {
theme: this.theme,
user: this.user
}
}
}
// 深层子组件
export default {
inject: ['theme', 'user'],
mounted() {
console.log(this.theme, this.user)
}
}
4. 使用 v-once 和 v-memo 优化性能
对于静态内容或不需要频繁更新的内容,使用 v-once 可以避免不必要的重新渲染:
xml
<!-- 只渲染一次 -->
<div v-once>{{ staticContent }}</div>
<!-- Vue 3 中的 v-memo -->
<div v-memo="[value]">{{ expensiveOperation(value) }}</div>
5. 使用自定义指令封装 DOM 操作
将常用的 DOM 操作封装成自定义指令,提高代码复用性:
JavaScript
// 注册全局指令
Vue.directive('focus', {
inserted(el) {
el.focus()
}
})
// 注册局部指令
export default {
directives: {
color: {
bind(el, binding) {
el.style.color = binding.value
},
update(el, binding) {
el.style.color = binding.value
}
}
}
}
6. 使用函数式组件优化无状态组件
对于没有状态、没有实例的组件,使用函数式组件可以减少性能开销:
html
<template functional>
<div class="list-item">
<span>{{ props.item.name }}</span>
<span>{{ props.item.value }}</span>
</div>
</template>
7. 使用 watch 的 deep 和 immediate 选项
watch 不仅可以监听数据变化,还可以通过选项实现更复杂的监听:
JavaScript
export default {
watch: {
// 深度监听对象变化
user: {
handler(newVal, oldVal) {
console.log('用户数据发生变化')
},
deep: true,
immediate: true // 立即执行一次
}
}
}
8. 使用 mixin 提取公共逻辑
将多个组件共用的逻辑提取到 mixin 中,避免代码重复:
JavaScript
// commonMixin.js
export default {
data() {
return {
loading: false
}
},
methods: {
async fetchData(api) {
this.loading = true
try {
const res = await this.$http.get(api)
return res.data
} finally {
this.loading = false
}
}
}
}
// 组件中使用
export default {
mixins: [commonMixin],
mounted() {
this.fetchData('/api/users')
}
}