Vue的响应式系统与设计模式
Vue的响应式系统核心原理
Vue的响应式系统基于ES5的Object.defineProperty
(Vue 2)或ES6的Proxy
(Vue 3)实现。当数据发生变化时,系统能自动更新依赖该数据的视图部分。这种机制通过观察者模式(Observer Pattern)实现,包含三个关键角色:
- Observer:递归地将数据对象转换为可观察对象
- Dep(Dependency):收集依赖(Watcher实例)
- Watcher:作为观察者,在数据变化时触发回调
// Vue 2响应式原理简化实现
function defineReactive(obj, key, val) {
const dep = new Dep()
Object.defineProperty(obj, key, {
get() {
if (Dep.target) {
dep.addSub(Dep.target)
}
return val
},
set(newVal) {
if (newVal === val) return
val = newVal
dep.notify()
}
})
}
class Dep {
constructor() {
this.subs = []
}
addSub(sub) {
this.subs.push(sub)
}
notify() {
this.subs.forEach(sub => sub.update())
}
}
发布-订阅模式在Vue中的应用
Vue的事件系统是典型的发布-订阅模式实现。$on
方法订阅事件,$emit
触发事件,$off
取消订阅。这种设计解耦了组件间的直接调用关系。
// 事件总线实现
class EventBus {
constructor() {
this.events = {}
}
$on(event, callback) {
if (!this.events[event]) {
this.events[event] = []
}
this.events[event].push(callback)
}
$emit(event, ...args) {
const callbacks = this.events[event]
if (callbacks) {
callbacks.forEach(cb => cb(...args))
}
}
$off(event, callback) {
if (!callback) {
delete this.events[event]
} else {
const callbacks = this.events[event]
if (callbacks) {
this.events[event] = callbacks.filter(cb => cb !== callback)
}
}
}
}
工厂模式与Vue组件
Vue组件系统采用工厂模式思想。通过Vue.component
注册的组件实际上是工厂函数,每次使用组件时都会创建新的实例。
// 组件工厂模式示例
Vue.component('smart-button', {
props: ['type'],
render(h) {
const buttonTypes = {
primary: 'btn-primary',
danger: 'btn-danger',
default: 'btn-default'
}
return h('button', {
class: ['btn', buttonTypes[this.type || 'default']]
}, this.$slots.default)
}
})
策略模式处理表单验证
Vue表单验证可以优雅地使用策略模式实现,将不同验证规则封装成独立策略。
// 验证策略对象
const validationStrategies = {
required(value) {
return value !== undefined && value !== null && value !== ''
},
minLength(value, length) {
return value.length >= length
},
email(value) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
}
}
// Vue验证指令
Vue.directive('validate', {
bind(el, binding, vnode) {
const rules = binding.value
const input = el.querySelector('input')
input.addEventListener('blur', () => {
const value = input.value
let isValid = true
for (const [rule, param] of Object.entries(rules)) {
if (!validationStrategies[rule](value, param)) {
isValid = false
break
}
}
if (!isValid) {
el.classList.add('error')
} else {
el.classList.remove('error')
}
})
}
})
代理模式实现数据校验
Vue 3的Composition API中,可以使用代理模式对响应式数据进行额外控制。
import { reactive } from 'vue'
function createValidatedReactiveObject(data, validators) {
return new Proxy(reactive(data), {
set(target, key, value) {
if (validators[key] && !validators[key](value)) {
console.warn(`Invalid value for ${key}: ${value}`)
return false
}
target[key] = value
return true
}
})
}
// 使用示例
const state = createValidatedReactiveObject(
{ age: 25 },
{
age: value => value >= 18 && value <= 120
}
)
装饰器模式增强Vue功能
通过高阶组件(HOC)形式,可以用装饰器模式扩展Vue组件功能。
function withLoading(WrappedComponent) {
return {
data() {
return { isLoading: false }
},
methods: {
async loadData() {
this.isLoading = true
try {
await WrappedComponent.methods.loadData.call(this)
} finally {
this.isLoading = false
}
}
},
render(h) {
return h('div', [
this.isLoading ? h('div', 'Loading...') : null,
h(WrappedComponent, {
props: this.$attrs,
on: this.$listeners,
scopedSlots: this.$scopedSlots
})
])
}
}
}
状态模式管理复杂组件状态
对于有多个状态的复杂组件,状态模式可以显著提高可维护性。
// 状态基类
class FormState {
constructor(context) {
this.context = context
}
next() {}
previous() {}
}
// 具体状态
class EditingState extends FormState {
next() {
this.context.setState(new ValidatingState(this.context))
}
render() {
return <EditForm />
}
}
class ValidatingState extends FormState {
async next() {
if (await validate(this.context.data)) {
this.context.setState(new SubmittingState(this.context))
}
}
previous() {
this.context.setState(new EditingState(this.context))
}
render() {
return <ValidatingIndicator />
}
}
// 在Vue组件中使用
export default {
data() {
return {
currentState: null
}
},
created() {
this.setState(new EditingState(this))
},
methods: {
setState(newState) {
this.currentState = newState
},
next() {
this.currentState.next()
},
previous() {
this.currentState.previous()
}
},
render() {
return this.currentState.render()
}
}
组合模式构建复杂UI结构
Vue的插槽机制天然支持组合模式,可以构建复杂的UI层次结构。
// 组合组件示例
Vue.component('tree-node', {
props: ['node'],
template: `
<li>
<div>{{ node.name }}</div>
<ul v-if="node.children && node.children.length">
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child"
/>
</ul>
</li>
`
})
Vue.component('tree-view', {
props: ['data'],
template: `
<ul class="tree">
<tree-node :node="data" />
</ul>
`
})
享元模式优化列表性能
大型列表渲染时,享元模式可以显著提升性能,Vue的v-for
配合key
已经内置了这种优化。
// 优化前
{
data() {
return {
items: Array(1000).fill().map((_, i) => ({ id: i, text: `Item ${i}` }))
}
},
template: `
<div>
<div v-for="item in items" :key="item.id">
{{ item.text }}
</div>
</div>
`
}
// 进一步优化使用虚拟滚动
import { RecycleScroller } from 'vue-virtual-scroller'
{
components: { RecycleScroller },
data() {
return {
items: Array(10000).fill().map((_, i) => ({ id: i, text: `Item ${i}` }))
}
},
template: `
<RecycleScroller
class="scroller"
:items="items"
:item-size="50"
key-field="id"
>
<template v-slot="{ item }">
<div class="item">
{{ item.text }}
</div>
</template>
</RecycleScroller>
`
}
职责链模式处理异步操作
Vue的插件系统和中间件机制可以使用职责链模式处理复杂流程。
// 异步操作处理链
class AsyncHandlerChain {
constructor() {
this.handlers = []
}
use(handler) {
this.handlers.push(handler)
return this
}
async execute(context) {
let index = 0
const next = async () => {
if (index < this.handlers.length) {
const handler = this.handlers[index++]
await handler(context, next)
}
}
await next()
return context
}
}
// 在Vue中使用
const apiChain = new AsyncHandlerChain()
.use(async (ctx, next) => {
ctx.startTime = Date.now()
await next()
ctx.duration = Date.now() - ctx.startTime
})
.use(async (ctx, next) => {
try {
await next()
} catch (err) {
console.error('API error:', err)
throw err
}
})
export default {
methods: {
async fetchData() {
const context = { vm: this }
return apiChain.execute(context)
}
}
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:React中的设计模式实践
下一篇:Angular中的依赖注入模式