computed 同时写 get() 和 set()

在 Vue 实际项目里,computed 同时写 get()set()核心场景就是:把一个值 "加工后使用",同时又能 "修改后自动同步回源头"

最典型、最实用的场景:

  1. 表单绑定一个计算后的变量(比如全选 / 反选、格式化输入)
  2. 对 props 进行双向绑定(Vue 不建议直接改 props,用 computed 中转)
  3. Vuex / Pinia 状态的双向绑定

1. 最常用:Pinia/Vuex 状态双向绑定

直接用 v-model 绑定 store 里的数据,又不想写一堆 $patch

复制代码
<template>
  <input v-model="searchText" placeholder="搜索" />
</template>

<script setup>
import { computed } from 'vue'
import { useSearchStore } from '@/stores/search'

const searchStore = useSearchStore()

// 既能读,又能写
const searchText = computed({
  // get:从 store 取值
  get() {
    return searchStore.keyword
  },
  // set:输入框修改时,自动提交到 store
  set(val) {
    searchStore.setKeyword(val)
  }
})
</script>

作用 :页面里直接 v-model,逻辑层统一交给 store。


2. 对 props 做双向绑定(避免直接修改 props)

Vue 规则:子组件不能直接改 props ,但表单又要 v-model

父组件

复制代码
<template>
  <Child v-model:username="name" />
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const name = ref('')
</script>

子组件 Child.vue

复制代码
<template>
  <input v-model="localUsername" />
</template>

<script setup>
import { computed } from 'vue'
const props = defineProps(['username'])
const emit = defineEmits(['update:username'])

const localUsername = computed({
  get() {
    return props.username
  },
  set(val) {
    // 不直接改 props,而是 emit 出去
    emit('update:username', val)
  }
})
</script>

作用:安全实现双向绑定,符合 Vue 单向数据流规范。


3. 全选 / 反选(业务最常见)

列表多选 + 全选按钮,必须用 get + set

复制代码
<template>
  <div>
    <label><input type="checkbox" v-model="allChecked" /> 全选</label>
    <div v-for="item in list" :key="item.id">
      <input type="checkbox" v-model="item.checked" /> {{ item.name }}
    </div>
  </div>
</template>

<script setup>
import { computed, reactive } from 'vue'

const list = reactive([
  { id: 1, name: '苹果', checked: false },
  { id: 2, name: '香蕉', checked: false },
  { id: 3, name: '橘子', checked: false }
])

const allChecked = computed({
  // get:判断是否全部选中
  get() {
    return list.every(item => item.checked)
  },
  // set:点击全选,批量修改
  set(val) {
    list.forEach(item => {
      item.checked = val
    })
  }
})
</script>

4. 表单数据格式化(手机号、金额、去空格)

输入时自动处理格式,又能正常绑定。

复制代码
<template>
  <input v-model="phone" placeholder="请输入手机号" />
</template>

<script setup>
import { computed, ref } from 'vue'
const rawPhone = ref('')

const phone = computed({
  get() {
    // 显示时去掉空格
    return rawPhone.value.replace(/\s/g, '')
  },
  set(val) {
    // 输入时只保留数字,自动格式化
    const numbers = val.replace(/\D/g, '')
    rawPhone.value = numbers
  }
})
</script>

一句话总结

  • 只有 get依赖其他值做计算展示
  • get + set既要计算展示,又要能修改并同步回源头

适合:双向绑定 + 状态中转 + 表单格式化 + 全选反选

相关推荐
mCell15 分钟前
【锐评】桌面端技术营销:别拿跑分当工程判断
前端·rust·electron
柒和远方27 分钟前
从一次工程审查看 AI 学习产品的边界兜底:RAG 资料链路一致性实战
前端·后端·架构
疯狂的魔鬼36 分钟前
一个"懂分寸"的文本省略组件是怎样炼成的
前端·vue.js·设计
angerdream40 分钟前
手把手编写儿童手机远程监控App之vue3 AI Gent
前端
李明卫杭州44 分钟前
CSS BFC 完全指南:从原理到实战,彻底搞懂这个"结界"
前端
裕波1 小时前
AI 正在重写应用开发。Vue 与 Vite,给出新的答案。
javascript·vue.js
Momo__1 小时前
MDN MCP Server——Mozilla 把 Web 文档接进 AI Agent,从此 LLM 不再瞎编 API
前端·ai编程·mcp
妙码生花1 小时前
现代前端的极致性能 icon 加载方案(死磕成功版)
前端·vue.js·typescript
掘金者阿豪2 小时前
把业务数据变成共享仪表盘:Metabase可视化与远程访问实践
前端·后端
kyriewen2 小时前
折腾了半年 AI 编程工作流,最后发现效率瓶颈是桌上那块屏幕
前端·javascript·ai编程