100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Vue.js+ElementUI多选表格下拉框有默认值后不及时更新

Vue.js+ElementUI多选表格下拉框有默认值后不及时更新

时间:2024-04-16 14:36:12

相关推荐

Vue.js+ElementUI多选表格下拉框有默认值后不及时更新

目录

发现问题思考问题解决问题1. 问题原因分析,及解决思路 完整代码

title: Vue.js+ElementUI多选表格下拉框有默认值后不及时更新

date: -8-1 14:40:00

tags:

学习Vue.jsElementUI前端记录问题

categories:bug

Vue.js+ElementUI项目中多选表格下拉框有默认值后不及时更新

发现问题

最近几天项目中有个需求,Vue+elementUI实现的一个多选表格,然后表格中有一列需要自己加一个下拉框,且下拉框有一个默认选中的值,实现后,发现下拉框重新选择值后居然没有及时更新,需要点中表格前面的checkbox勾选框后才更新,让我百思不得其解。

思考问题

一开始我认为是因为我绑定了默认值,导致不能及时更新,但是默认值又是需要实现的一个功能,所以不得不写,后面我以为是我绑定的值不对导致没有及时更新,我将下拉框选项数组换成了如下格式的一个对象数组,仍然不能及时更新!!

[{label: '选项1',value: 1},{label: '选项2',value: 2},{label: '选项3',value: 3},{label: '选项4',value: 4},{label: '选项5',value: 5},]

我就想可能是因为vue视图没有及时相应,所以我添加了如下代码想让table表格的内容强制更新,但是遗憾的是仍然没能及时更新。

BindChange(rowdata){console.log(rowdata);// 获取当前行的数据对象// const rowData = this.tableData[rowIndex];// 将新选择的值更新到表格数据中// this.tableData[rowIndex].value = rowData.value;rowdata.value = rowdata.value;console.log(this.tableData);this.$forceUpdate();//强制更新,不起作用!Vue官网不推荐使用}

解决问题

后来正在我头疼之际,找到了一个看似可行的方法,然后我试了一下果然就起作用啦!

1. 问题原因分析,及解决思路

(1)v-model绑定与this.$set触发视图更新

在Vue中,当使用v-model绑定一个属性时,Vue会根据绑定的值自动处理更新。但在这个问题的情况下,v-model绑定的是scoped.row.value,而不是rowData中的value属性。

所以,更新rowData中的value并不会直接触发视图的更新。

为了解决这个问题,我们需要手动更新scoped.row.value。这可以通过给scoped.row对象重新赋值的方式来实现,强制触发Vue的响应式系统。

我们在BindChange方法中重新给scoped.row赋值,使用this.$set来触发视图的更新。这样应该能解决下拉框选择值后表格数据没有及时更新的问题。

(2)详细方法

BindChange(rowData, rowIndex) {// 通过方法参数直接获取当前行的数据对象和索引-------07-30// 直接更新rowData中的value属性console.log('row数据',rowData);console.log('rowIndex',rowIndex);this.tableData[rowIndex].value = rowData.value;// 重新赋值scoped.row触发视图更新this.$set(this.tableData, rowIndex, Object.assign({}, rowData));console.log('更新后的tableData',this.tableData);}

(3)说明与总结

当使用Vue进行数据绑定时,通常情况下,Vue能够自动追踪数据的变化并更新视图,这被称为"响应式系统"。但在某些情况下,直接赋值一个新值给对象属性可能无法触发响应式更新,特别是对于在Vue实例创建时不存在的属性。

this.$set方法是Vue提供的一种手动触发响应式更新的方式,用于更新对象或数组中的某个元素或属性。

语法

this.$set(target, propertyName/index, value);

参数说明

target: 要更新的目标对象或数组。

propertyName/index: 要更新的属性名或数组索引。

value: 要设置的新值。

使用this.$set方法,Vue会监听新设置的值并将其添加到响应式系统中,从而确保更新可以正确地触发视图更新。

在提供的代码中,this.$set(this.tableData, rowIndex, Object.assign({}, rowData))用于更新this.tableData数组中的第rowIndex个元素。

让我们分解一下这个代码的含义:

Object.assign({}, rowData): 这里使用Object.assign方法,通过浅拷贝的方式创建了一个新对象。这样做的目的是为了确保rowData的变化不会影响到this.tableData中的数据。因为直接赋值一个对象引用的话,两个变量会指向同一个内存地址,导致变化不会触发响应式更新。

this.$set(this.tableData, rowIndex, ...):这里使用this.$set来更新this.tableData数组中的第rowIndex个元素。将新的对象赋值给这个索引处,从而触发响应式更新。

总结

this.$set方法的作用是确保更新的数据能够正确地触发Vue的响应式更新机制。它在更新对象或数组中的某个元素或属性时,可以让Vue监听新值并正确地进行视图更新。这在需要手动更新数据时,

特别是处理动态添加或删除属性的情况下非常有用。🎉🍭🍓🍬🎉

完整代码

//multipleTable.vue<template><div><el-tableref="multipleTable":data="tableData"tooltip-effect="dark"style="width: 100%"@selection-change="handleSelectionChange"><el-table-columntype="selection"width="55"></el-table-column><el-table-columnlabel="日期"width="120"><template v-slot="scope">{{ scope.row.date }}</template></el-table-column><el-table-columnprop="name"label="姓名"width="120"></el-table-column><el-table-columnprop="address"label="地址"show-overflow-tooltip></el-table-column><el-table-columnlabel="选项"><template v-slot="scoped"><el-select v-model="scoped.row.value" @change="BindChange(scoped.row, scoped.$index)"><el-optionv-for="item in scoped.row.choice":key="item.label":value="item.value":label="item.label"></el-option></el-select></template></el-table-column></el-table><div style="margin-top: 20px"><el-button @click="toggleSelection([tableData[1], tableData[2]])">切换第二、第三行的选中状态</el-button><el-button @click="toggleSelection()">取消选择</el-button></div></div></template><script>export default {name: 'MultipleTable',data() {return {tableData: [{date: '-05-03',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'}, {date: '-05-02',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'}, {date: '-05-04',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'}, {date: '-05-01',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'}, {date: '-05-08',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'}, {date: '-05-06',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'}, {date: '-05-07',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄'}],multipleSelection: []}},mounted() {this.initTabledata();},methods: {BindChange(rowData, rowIndex) {// 通过方法参数直接获取当前行的数据对象和索引-------07-30// 直接更新rowData中的value属性console.log('row数据',rowData);console.log('rowIndex',rowIndex);this.tableData[rowIndex].value = rowData.value;// 重新赋值scoped.row触发视图更新this.$set(this.tableData, rowIndex, Object.assign({}, rowData));console.log('更新后的tableData',this.tableData);},// BindChange(rowdata){//// 获取当前行的索引//// console.log(select);//// const rowIndex = this.tableData.indexOf(select.$attrs.row);//// // 将新选择的值更新到表格数据中//// this.tableData[rowIndex].value = select;////console.log(rowdata);//// 获取当前行的数据对象//// const rowData = this.tableData[rowIndex];//// 将新选择的值更新到表格数据中//// this.tableData[rowIndex].value = rowData.value;//rowdata.value = rowdata.value;//console.log(this.tableData);//// this.$forceUpdate();// },initTabledata(){this.tableData.forEach(item => {item.value = 3;item.choice = [{label: '选项1',value: 1},{label: '选项2',value: 2},{label: '选项3',value: 3},{label: '选项4',value: 4},{label: '选项5',value: 5},]})},toggleSelection(rows) {if (rows) {rows.forEach(row => {this.$refs.multipleTable.toggleRowSelection(row);});} else {this.$refs.multipleTable.clearSelection();}},handleSelectionChange(val) {this.multipleSelection = val;console.log('当前选中的行的值',this.multipleSelection);}}}</script>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。