Vue的MVVM详解

什么是MVVM?

MVVM = Model-View-ViewModel

Vue的MVVM严格来说更像是一个抽象概念,vue并不是MVVM架构实现,因为它不像Thinkphp这样的框架对于MVC有具象的表现,只是借鉴了MVVM的核心思想。

这是个老生常谈的问题了,社区里对Vue是否是MVVM架构的叫法问题经常会有不同的观点,其实作者本人也对表达了对这方面的解释

什么是Model和View?

这个其实很好理解,如果有MVC相关经验的话

Model总结下来其实就是对数据的操作管理,可能包含:

  • 数据持久化存储
  • 对数据的处理(格式化\时间戳处理\倒计时处理)
  • 与后端的交互
  • 封装与统一(例如使用vuex或pinia)
  • 对view的解耦,使得数据层是独立的

Model 示例:

//这个就是model,也就是数据层
const message = ref('Hello')

//也可以是reactive
const form = reactive({
  user: {
    name: '',
    age: 18
  },
  settings: {
    theme: 'dark',
    notifications: true
  },
  tags: ['vue', 'mvvm', 'example']
})
//可以是computed
const fullName = computed(() => `${firstName.value} ${lastName.value}`)

//甚至可以是Pinia或vuex管理的整个模块
import { defineStore } from 'pinia'
import { ref, reactive } from 'vue'

export const useProductStore = defineStore('product', () => {
  // Model: 商品列表
  const products = ref<Product[]>([])

  // Model: 分页信息
  const pagination = reactive({
    page: 1,
    pageSize: 10,
    total: 0
  })

  // Model: 搜索条件
  const searchKeyword = ref('')

  // Action: 从后端加载商品列表
  async function fetchProducts() {
    const res = await fetch(`/api/products?page=${pagination.page}&size=${pagination.pageSize}&keyword=${searchKeyword.value}`)
    const data = await res.json()
    products.value = data.items
    pagination.total = data.total
  }

  // Action: 新增商品
  async function addProduct(newProduct: Partial<Product>) {
    await fetch('/api/products', {
      method: 'POST',
      body: JSON.stringify(newProduct)
    })
    await fetchProducts() // 刷新列表
  }

  return {
    products, pagination, searchKeyword,
    fetchProducts, addProduct
  }
})

View相较于Model更容易理解一些,Model包含一些抽象概念,而View纯粹是具象的表现
可以这样理解,所有标记语言的部分基本都属于view
包括组件也是

//整个template部分都是view,视图层
<template>
  <input v-model="message" />
  <p>{{ message }}</p>
</template>

什么是ViewModel呢?

ViewModel相对来说比较难理解一些,因为单看这个View Model的单词会觉得这是个抽象概念,但实际上ViewModel确实就是一个抽象流程

ViewModel = 帮助 View 获取和操作 Model 的中介或“桥梁”,负责协调数据的读取与更新流程,实现 View 和 Model 之间的解耦与同步流程

//具体表现如下
ViewModel包含Action,与Model存在关系,与View也存在关系
<script setup>
import { ref } from 'vue'

const count = ref(0)      // 状态(Model)
function increment() {    // 操作(Action)
  count.value++
}
</script>
<template>
  <button @click="increment">+1</button>
  <p>{{ count }}</p>
</template>
Posted in Vue     

Leave a Reply

Your email address will not be published. Required fields are marked *