如何将点分隔字符串作为对象路径应用于Vue的v-model指令
解决方案
该需求完全可以实现,以下是两种常用落地方案:
方案1:拆分v-model语法糖,配合路径读写工具函数(兼容Vue2/Vue3)
v-model本质是值绑定 + 变更事件监听的语法糖,你可以拆分写法,配合自定义的嵌套属性读写工具函数实现绑定:
- 先实现嵌套属性读写工具函数
// 读取嵌套对象属性值 function getNestedValue(obj, path) { return path.split('.').reduce((current, key) => current?.[key], obj) } // 写入嵌套对象属性值 function setNestedValue(obj, path, value) { const keys = path.split('.') const lastKey = keys.pop() const target = keys.reduce((current, key) => current[key], obj) target[lastKey] = value }
- 模板部分修改为拆分写法
<b-field v-for="field in fields" :key="field.name" :label="field.label" > <b-input :value="getNestedValue(record, field.name)" @input="val => setNestedValue(record, field.name, val)" /> </b-field>
方案2:Vue3 组合式API封装计算属性,写法更简洁
如果使用Vue3,可以封装计算属性直接给v-model绑定,代码更简洁:
- 封装字段绑定工具
import { computed } from 'vue' function useFieldBind(record, path) { return computed({ get() { return path.split('.').reduce((current, key) => current?.[key], record) }, set(val) { const keys = path.split('.') const lastKey = keys.pop() const target = keys.reduce((current, key) => current[key], record) target[lastKey] = val } }) } // 预处理fields数组,给每个字段增加绑定用的计算属性 const processedFields = fields.map(field => ({ ...field, bindRef: useFieldBind(record, field.name) }))
- 模板直接绑定计算属性
<b-field v-for="field in processedFields" :key="field.name" :label="field.label" > <b-input v-model="field.bindRef" /> </b-field>
注意事项
如果业务场景中可能出现嵌套路径中间层级未初始化的情况,可以修改set函数自动创建中间层级,避免报错:
function setNestedValue(obj, path, value) { const keys = path.split('.') const lastKey = keys.pop() const target = keys.reduce((current, key) => { // 中间层级不存在则自动创建空对象 if (!current[key]) current[key] = {} return current[key] }, obj) target[lastKey] = value }
内容的提问来源于stack exchange,提问作者Pu5her
相关产品推荐
相关产品推荐

