Skip to content

MVVM架构模式

1. 基本概念

1.1 什么是MVVM

MVVM(Model-View-ViewModel)是一种软件架构模式,由Model(数据模型)、View(视图)和ViewModel(视图模型)三部分组成。

1.2 各层职责

  • Model:数据模型,处理数据和业务逻辑
  • View:视图层,负责页面展示
  • ViewModel:视图模型,连接Model和View

2. Vue中的MVVM实现

2.1 基本结构

vue
<!-- View -->
<template>
  <div>
    <input v-model="message">
    <p>{{ message }}</p>
  </div>
</template>

<!-- ViewModel -->
<script>
export default {
  data() {
    return {
      // Model
      message: 'Hello MVVM'
    }
  }
}
</script>

2.2 数据绑定

js
// 双向数据绑定
const vm = new Vue({
  data: {
    message: ''
  },
  computed: {
    reversedMessage() {
      return this.message.split('').reverse().join('')
    }
  }
})

3. 核心原理

3.1 响应式系统

js
// Vue2响应式实现
function defineReactive(obj, key, val) {
  const dep = new Dep()
  
  Object.defineProperty(obj, key, {
    get() {
      dep.depend()
      return val
    },
    set(newVal) {
      if (val === newVal) return
      val = newVal
      dep.notify()
    }
  })
}

// Vue3响应式实现
const state = reactive({
  count: 0
})

3.2 依赖收集

js
class Dep {
  constructor() {
    this.subscribers = new Set()
  }
  
  depend() {
    if (activeEffect) {
      this.subscribers.add(activeEffect)
    }
  }
  
  notify() {
    this.subscribers.forEach(effect => effect())
  }
}

4. 实际应用

4.1 组件设计

vue
<!-- UserProfile.vue -->
<template>
  <div class="user-profile">
    <h2>{{ user.name }}</h2>
    <input v-model="user.email">
    <button @click="updateProfile">更新</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        name: '',
        email: ''
      }
    }
  },
  methods: {
    async updateProfile() {
      await api.updateUser(this.user)
    }
  }
}
</script>

4.2 状态管理

js
// Vuex/Pinia中的MVVM
const store = createStore({
  state: {
    // Model
    count: 0
  },
  getters: {
    // ViewModel
    doubleCount: state => state.count * 2
  },
  mutations: {
    increment(state) {
      state.count++
    }
  }
})

5. 最佳实践

5.1 数据流管理

js
// 单向数据流
export default {
  props: {
    initialData: Object
  },
  data() {
    return {
      localData: { ...this.initialData }
    }
  },
  methods: {
    updateData() {
      this.$emit('update', this.localData)
    }
  }
}

5.2 组件通信

vue
<!-- 父子组件通信 -->
<template>
  <child-component
    :data="parentData"
    @update="handleUpdate"
  />
</template>

6. 性能优化

6.1 避免过度响应

js
// 使用Object.freeze()
data() {
  return {
    staticData: Object.freeze({
      title: 'Static Title',
      items: ['A', 'B', 'C']
    })
  }
}

6.2 计算属性缓存

js
export default {
  computed: {
    expensiveComputation: {
      cache: true,
      get() {
        return this.items.filter(/* complex logic */)
      }
    }
  }
}

7. 调试与测试

7.1 Vue Devtools

  • 组件树检查
  • 数据追踪
  • 性能分析

7.2 单元测试

js
import { mount } from '@vue/test-utils'

describe('MyComponent', () => {
  test('updates model when view changes', async () => {
    const wrapper = mount(MyComponent)
    await wrapper.find('input').setValue('new value')
    expect(wrapper.vm.message).toBe('new value')
  })
})

8. 注意事项

  1. 避免View和Model直接通信
  2. 保持ViewModel的纯粹性
  3. 合理划分组件职责
  4. 注意数据流向
  5. 性能优化考虑