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:既要计算展示,又要能修改并同步回源头

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

相关推荐
行者-全栈开发9 分钟前
【前端/JS框架】CVE-2026-3854:GitHub Enterprise Server X-Stat注入XSS漏洞深度剖析与紧急修复指南
前端·javascript·github
计算机魔术师1 小时前
AMD砸82亿买下李飞飞,这次不卖芯片卖什么?
前端
hzxpaipai2 小时前
杭州企业官网怎么建设?从策划到上线的5步建站方法
运维·服务器·前端·网络
怕浪猫2 小时前
2026年金九银十,我面了22个前端
前端·javascript·面试
IT_陈寒2 小时前
Vue 这个响应式陷阱,我的头发都掉没了
前端·人工智能·后端
FYKJ_20102 小时前
django电影推荐系统55066-计算机课程设计、毕业设计
vue.js·spring boot·python·mysql·typescript·spark·django
前端的日常2 小时前
一个人+AI做情侣食谱小程序,30天纯赚
前端·javascript·后端
qq_316837752 小时前
阿里云百炼 fun-asr-realtime uniapp vue3 调用
javascript·vue.js·uni-app
庄园特聘拆椅狂魔3 小时前
Java 后端转全栈的第一课:从前端项目搭建到技术选
java·开发语言·前端
triumph_passion3 小时前
前端路由策略:Memory、Hash 与 History
前端