Vue 3结合element plus(问题总结一)之 table数据更新而视图不更新
- 前言
- Table组件
- 问题原因及解决
- 小案例
前言
应为做项目用到vue3,就结合element plus来做,但是碰到一些问题,上网搜几乎是vue2 结合element ui的相似问题。所以自己也是搞了蛮久的,如果有相同的问题希望能帮助到各位,希望可以点赞加搜藏一下。
Table组件
讲一下Table组件,先看下官网给的基础代码和效果。
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</template>
<script lang="ts" setup>
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
</script>
可以很清楚的明白其中的组件的使用。
问题原因及解决
当我更新数组绑定的tableData的时候,视图却没有更新。后面上网搜索问题,找了很多方法都不行。后来才发现犯了一个很低级的错误。错误原因
- tableData不是代理对象,使用直接将新的值赋给tableData,视图不会更新
- 后来将table定义为代理对象,还是失败的原因是数组的改变有些情况vue3响应监测不到
如何将接口请求到的列表数据赋值给响应数据 呢?
失败案例
const arr = reactive([]);
const load = () => {
const res = [2, 3, 4, 5];//要更新的数据
// 方法1 失败,直接赋值丢失了响应性
// arr = res;
// 方法2 这样也是失败
// arr.concat(res);
// 方法3 可以,但是很麻烦
res.forEach(e => {
arr.push(e);
});
};
vue3 使用proxy,对于对象和数组都不能直接整个赋值。
成功案例
// 方案1:创建一个响应式对象,对象的属性是数组
const data = reactive({
arr: []
});
data.arr = [1, 2, 3]
// 方案2: 使用ref函数
const data = ref([])
data.value = [1, 2, 3]
// 方案3: 使用数组的push方法
const arr = reactive([])
arr.push(...[1, 2, 3])
小案例
通过一个小案例来验证一下。
<template >
<el-button @click="updateView()">更新视图</el-button>
<div id="shoplist">
<el-table
ref="multipleTableRef"
:data="data.arr"
style="width: 100%"
height="90%"
stripe
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="40" />
<el-table-column property="shopname" label="店名" width="120" show-overflow-tooltip/>
<el-table-column property="score" label="评分" sortable width="80" />
<el-table-column property="sales" label="销量" sortable width="80" />
<el-table-column property="type" label="类型" width="70" />
</el-table>
</div>
</template>
<script>
import { ref } from 'vue' ;
import {ElTable} from 'element-plus'
import { reactive } from '@vue/reactivity';
export default {
setup () {
const multipleTableRef = ref(null);
const multipleSelection = ref([]);
var handleSelectionChange =(val)=>{
multipleSelection.value = val;
}
//刚开始没有数据
var data = reactive({
arr:[]
})
//更新数据
var updateView = () =>{
data.arr = [
{
id:1,
shopname:"沙县小吃",
score:5.5,
sales:1200,
hh:12,
type:"快餐"
},
{
id:2,
shopname:"法式牛排餐厅",
score:7.5,
sales:2400,
hh:12,
type:"西餐"
},
{
id:3,
shopname:"沙县大吃",
score:6.5,
sales:200,
hh:12,
type:"快餐"
},
{
id:4,
shopname:"南昌瓦罐汤",
score:6.9,
sales:2400,
hh:12,
type:"快餐"
},
]
}
return {
data,
updateView
}
},
}
</script>
<style>
#shoplist{
position: fixed;
z-index: 1001;
width: 390px;
height: 100%;
min-height: 100vh;
right: 0px;
bottom: 0px;
padding-top: 5px;
background-color: #f2f2f2;
transition: 1s;
/* overflow: hidden; */
border: 1px solid #333;
}
</style>
刚开始没有数据,右侧就显示No Data,当我点击更新视图按钮时。就可以看到列表了(数据是瞎编的,不要注重细节。)
同样的第二种和第三种方式也可以。
...
<el-table
ref="multipleTableRef"
:data="data" 这里改成了data哦
style="width: 100%"
height="90%"
stripe
@selection-change="handleSelectionChange"
>
...
var data = ref([])
//更新数据
var updateView = () =>{
data.value = [
...