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

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

相关推荐
曹牧1 小时前
C#:空合并运算符
java·前端·数据库
小羊没烦恼!2 小时前
铁道部新客票系统设计(二)
开发语言·前端·数据库·python·oracle·c#·php
智能直播5 小时前
RK3518:1.5G 内存 + 8G 存储,如何跑起硬件编解码、Web、AI 识别、绿幕特效
前端·人工智能·5g
掘金酱6 小时前
【10.24 特别活动】AI 时代,程序员的新饭碗在哪里?
前端·人工智能·后端
excel6 小时前
多进程环境下使用 PM2 部署 Socket.IO:需要注意什么
前端
IT_陈寒6 小时前
Redis的原子性竟然失效了?记一次分布式锁翻车实录
前端·人工智能·后端
_菜鸟果果8 小时前
高德地图 JS API 2.0 在国产 Linux/ARM 电脑上渲染失败 的排查与解决
linux·开发语言·javascript
时间的情敌8 小时前
《回顾 2018 前端:Vue2 成熟期,Webpack4 发布,PWA 大火》
前端
Java后端的Ai之路8 小时前
前端技术Vue-09-webpack-vuejs-实战
前端·vue.js·webpack