vue给数组和对象进行增加删除字段不更新数据的解决方法 — Vue.set(object, key, value)

本文介绍Vue中使用Vue.set方法来手动触发数据变动后的视图更新。通过具体示例展示了如何为数组添加新元素和为对象添加新属性,确保视图能够响应这些变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于为什么数据变动不重新渲染, 官网已经介绍了, 这里就不再多说:

下面主要记录一下如何利用Vue.set方法手动的触发Vue的渲染:

具体的操作代码如下:
组件基本代码:

<style lang="sass">

</style>
<template>
<div>
    <div>
        <div>

        </div>
    </div>
</div>
</template>
<script>
    export default {
        data(){
            return {

            }
        },
        methods: {
            ceshi(){

            }
        }
    }
</script>

1.数组的增加,删除(数组的push等方法排除)

</style>
<template>
<div>
    <div>
        <div>
            <div v-for="item in items">
               <span>{{ item }}</span>
            </div>
            <button @click="ceshi">anniu</button>
        </div>
    </div>
</div>
</template>

<script>
    export default {
        data(){
            return {
                items: [11,22],
                obj: { a: 'aa', b: 'bb' }
            }
        },
        methods: {
            ceshi(){
                this.items[2] = 33; // 这样的写法数据是无法重新渲染的
            }
        }
    }
</script>

点击按钮操作ceshi事件前后,没发生变化

这里写图片描述

解决方法:

  1. 就是利用数据的push方法是可以实现的
  2. 利用Vue.set方法

具体实现如下:

methods: {
    ceshi(){
        this.$set(this.items, 2, 33)
    }
},

同理,如果items: [{a: ‘11’}] –> items: [{a: ‘11’, b: ‘22’}]

<div v-for="item in items">
  <span v-for="(i, j) in item">{{ i }}--{{ j }}</span>
</div>

this.items[0] = Object.assign({}, this.items[0], { b: '22' });
this.$set(this.items, 0, this.items[0]);

2.给对象增加新属性(同理)

<template>
    <div>
        <div v-for="item in obj">
          <span>{{ item }}</span>
        </div>
    </div>
</template>

data(){
    return {
        obj: { a: 'aa', b: 'bb' }
    }
}

methods: {
    ceshi(){
       this.obj['c'] = '000'; // 不起作用
       this.$set(this.obj, 'c', '000'); //起作用 
    }
},
<think>我们讨论的是在Vue中如何将查询到的数组数据赋值给data中的对象数组字段,并寻求最佳实践。根据引用[3]中的示例,我们看到一个Vue实例的data中有一个数组字段(例如items),然后通过方法(如getList)获取数据并赋值给这个数组。引用[2]中提到,Vue能够高效地处理数组替换,因为Vue实现了启发式的方法来重用DOM元素。最佳实践:1.直接替换整个数组(使用Vue.set或直接赋值)以确保Vue能够检测到变化。2.避免直接通过索引修改数组元素,因为Vue能检测这种变化(除非使用Vue.set数组的splice方法)。步骤:a.在data中定义数组字段(如:items:[])b.方法中通过API获取数据(假设是一个数组)c.将获取到的数组赋值给data中的数组字段注意:由于Vue的响应式系统限制,直接通过索引设置项(例如:this.items[index]=newValue会触发视图更新。因此,对于数组,最佳的方式是创建一个新数组(或直接替换整个数组)。示例代码:```javascriptexportdefault{data(){return{items:[]//初始化为空数组}},methods:{asyncfetchData(){try{//假设调用API获取数据,返回一个数组constresponse=awaitaxios.get('/api/items');//最佳实践:将返回的数组直接赋值给itemsthis.items=response.data;//直接替换整个数组Vue可以检测到变化并更新视图//如果需要对返回的数据进行一些处理,可以先处理再赋值//例如:this.items=response.data.map(item=>({...item,someProperty:...}));}catch(error){console.error('获取数据失败:',error);}}},mounted(){this.fetchData();}}```为什么直接赋值可以触发更新?因为Vue数组的变异方法(如push,pop,shift,unshift,splice,sort,reverse)进行了重写,这些方法会触发视图更新。而直接替换整个数组Vue会智能地重新渲染列表,并且尽可能重用已有的DOM元素(引用[2])。特殊情况:如果你需要修改数组中的某个元素,应该使用Vue.set或者数组的splice方法:```javascript//修改数组中的第index个元素Vue.set(this.items,index,newValue);//或者this.items.splice(index,1,newValue);```总结最佳实践:1.对于整个数组的赋值,直接使用等号赋值(this.items=newArray)即可。2.对于数组中单个元素的修改,使用Vue.set或splice。这样就能确保Vue的响应式系统能够追踪变化并更新视图。引用说明:[^1]提到了在表单中赋值数组的问题,但我们的解决方案是直接替换整个数组。[^2]解释了Vue处理数组替换的高效性,这支持了我们的做法。[^3]给出了一个具体的例子,展示了如何将数据赋值给数组。相关问题:1.Vue中如何监听数组的变化?2.Vue中修改数组元素有哪些注意事项?3.Vuex中如何管理数组状态并保持响应式?</think>### Vue数组数据赋值的最佳实践 在 Vue 中将查询到的数组数据赋值给 data 中的对象数组字段时,遵循响应式原则至关重要。以下是三种最佳实践方案: --- #### 方案 1:直接替换整个数组(推荐⭐) ```javascript export default { data() { return { items: [] // 初始化为空数组 } }, methods: { async fetchData() { // 模拟 API 请求 const response = await axios.get('/api/items'); // 最佳实践:直接替换整个数组 this.items = response.data; } } } ``` **优点**: - Vue 能高效处理整个数组替换(引用[2]) - 100% 触发响应式更新 - 代码简洁清晰 --- #### 方案 2:使用 Vue.set$set(修改特定项时) ```javascript methods: { updateItem(index, newValue) { // 修改数组中特定项 this.$set(this.items, index, newValue); // 或使用 Vue.set // Vue.set(this.items, index, newValue); } } ``` **适用场景**: - 需要修改数组中特定元素时 - 动态添加新属性到数组元素中 --- #### 方案 3:数组变异方法(需注意响应性) ```javascript methods: { addNewItem(newItem) { // 使用 Vue 重写的变异方法 this.items.push(newItem); }, removeItem(index) { this.items.splice(index, 1); } } ``` **注意事项**: - 只能使用 Vue 重写的 7 种变异方法: `push(), pop(), shift(), unshift(), splice(), sort(), reverse()` - 直接通过索引修改会触发更新: `this.items[0] = newValue` ❌(无效) --- ### 表单数组赋值实践(解决引用[1]问题) ```vue <template> <el-form :model="form"> <el-select v-model="form.projectsR" multiple> <el-option v-for="item in relationData" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form> </template> <script> export default { data() { return { form: { projectsR: [] // 表单中的数组字段 }, relationData: [] // 从 API 获取的关系数据 } }, async mounted() { // 从 API 获取关系数据 const res = await axios.get('/api/relations'); // 最佳赋值方式 this.relationData = res.data; // 如果需初始化表单值 this.form.projectsR = res.data.map(item => item.id); } } </script> ``` ### 关键原则总结 1. **响应式规则**: - 数组替换使用 `=` 直接赋值 - 元素修改使用 `Vue.set/$set` - 增删使用变异方法 2. **常见陷阱**: ```javascript // 错误:会触发更新 this.items[0] = newValue; // 错误:Vue 无法检测属性添加 this.items.forEach(item => { item.newProp = value; // ❌ }); ``` 3. **深层对象处理**: ```javascript // 需要嵌套响应式时 this.items = res.data.map(item => ({ ...item, details: this.$set({}, item.details) })); ``` 4. **性能优化**: - 大数据集使用 `Object.freeze()` 避免必要响应 ```javascript this.items = Object.freeze(largeDataArray); ``` > 直接替换整个数组是最可靠的方式,既符合 Vue 响应式原理(引用[2]),又能避免常见陷阱(引用[3])。对于表单绑定场景(引用[1]),确保初始化时正确映射数据结构即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值