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

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

相关推荐
mldong2 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排3 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60613 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角4 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!4 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰5 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi6 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen7 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马8 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu8 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss