Vue3踩坑记录

目录

一、定义常变量

1.1、ref和reactive到底用谁?

二、双向绑定

2.1、直接改变表格该行数据

2.1、在弹窗改变表格该行数据

一、定义常变量

1.1、ref和reactive到底用谁?

已知:使用ref定义基础类型数据;使用reactive定义复杂对象或数组;

javascript 复制代码
const items = reactive<string[]>([]);

const updateItems= () => {
  //以下都会报错 'items' is constant
  items = []
  items = res.data.items
};

报错原因:

reactive的常量不能直接重新赋值,可以通过修改数组内容来更新数据。

解决方法:

(1)、替换数组中的所有元素

javascript 复制代码
  items.length = 0; // 清空数组
  items.splice(0, items.length); // 清空数组
  Object.assign(items, []); //创建一个新的数组并赋值给 items

  items.push(...res.data.items)

(2)、ref 支持重新赋值

javascript 复制代码
const items = ref<string[]>([]);

const updateItems= () => {
  items.value = []; // 重新赋值整个数组
}

备注:

如果是对象:除非用ref,否则只能这样逐个赋值,且用 let 进行定义。

javascript 复制代码
     for (let key in res.data) {
        editForm[key] = res.data[key];
      }

二、双向绑定

2.1、直接改变表格该行数据

html 复制代码
<el-table height="100%" border class="mt20" size="large" v-loading="pager.loading" :data="tableData">
            <el-table-column label="工厂" prop="factoryCode" header-align="center" align="center" show-overflow-tooltip />
            <el-table-column label="设计记录sku" prop="sku" width="200" header-align="center" align="center"
              show-overflow-tooltip />
            <el-table-column label="格式" prop="sc_img_type" show-overflow-tooltip header-align="center" align="center">
              <template #default="{ row }">
                <el-tag v-if="row.sc_img_type == 1">JPG</el-tag>
                <el-tag v-if="row.sc_img_type == 2">SVG</el-tag>
                <el-tag v-if="row.sc_img_type == 3">TIFF</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="创建时间" width="180" prop="create_time" show-overflow-tooltip header-align="center"
              align="center"></el-table-column>
            <el-table-column label="操作" show-overflow-tooltip header-align="center" align="center">
              <template #default="{ row }">
                <el-button type="primary" @click="updateRow(row)">编辑</el-button>
              </template>
            </el-table-column>
</el-table>
<script lang="ts" setup>
const updateRow = (row) => {
  row.factoryCode = "改变工厂名称";
};
</script>
javascript 复制代码
updateRow(row) {
      row.name = '改变后的名称'; // 修改传入的 row 对象
}

总结:

因为 tableData 是响应式的,Vue3 会把它内部的每一项(即 row)都变成响应式对象。当你修改其中的属性时,Vue3 会通过代理(Proxy)检测到这个属性的变化,并更新 DOM。

因为row 是响应式对象,访问/修改 row.name,Vue2 会触发getter或setter,从而通知视图更新。Vue 2 的响应式系统是基于 Object.defineProperty 实现的,它会使得对象的每个属性都变成 getter 和 setter,从而实现双向绑定。

2.1、在弹窗改变表格该行数据

表格数据显示在弹窗内时要注意:

javascript 复制代码
<script lang="ts" setup>
  // =======================用reactive定义
let form = reactive({
  factoryCode: "",
  sku: "",
});
const updateRow = (row) => {
  form= row;
  form = JSON.parse(JSON.stringify(row));
  // 逐个赋值【数据过多用for...in...】,上面两种都不对
  form.factoryCode = row.factoryCode;
  form.sku = row.sku;
  form.factoryCode ="改变它";//弹窗里会变,表格不会
  dialogFormVisible.value = true;
};
  // =======================用ref定义
let form = ref({
  factoryCode: "",
  sku: "",
});
const updateRow = (row) => {
  form.value= row;
  dialogFormVisible.value = true;
};
</script>

通过 form.factoryCode 修改数据时,它并没有直接修改 tableData中的对应数据项,而只是更新了 form 中的数据。如果你希望 tableData中的某个项随着 form 的改变而自动反映更新,需要做显式的修改【后端接口更新/自己改变tableData】。

但是在vue2里,却是可以直接改变的。

javascript 复制代码
  methods: {
    handleSelectionChange(val) {
      this.multipleSelection = val
      this.multipleSelection[0].name = '改变后的名称002' //这里一变,tableData也会变
    },
    updateRow(row) {
      this.form = row
      this.form.name = '改变后的名称' //这里一变,row就会变,tableData也会变
      this.dialogFormVisible = true
    }
  }

如果你不想修改 row 对象本身,而只想在 this.form 上进行修改:

this.form = { ...row } // 使用展开运算符创建 row 的浅拷贝

this.form = Object.assign({}, row) // 使用 Object.assign 创建 row 的浅拷贝
总结:

vue2:this.form = row 这样的赋值操作,让它俩指向的是同一个内存地址,所以一变全都变;

vue3:form.value = row这里的form 是一个响应式引用 ,而row只是一个普通的对象,formrow是不同的引用 ,修改form.value并不会直接影响 row;非要一起变,只能Object.assign(form, tableData[index]);

......待更新

相关推荐
red润3 分钟前
使用 HTML5 Canvas 实现动态蜈蚣动画
前端·html·html5
sg_knight11 分钟前
VSCode如何修改默认扩展路径和用户文件夹目录到D盘
前端·ide·vscode·编辑器·web
云空12 分钟前
《解锁 Python 数据挖掘的奥秘》
开发语言·python·数据挖掘
一个处女座的程序猿O(∩_∩)O21 分钟前
完成第一个 Vue3.2 项目后,这是我的技术总结
前端·vue.js
mubeibeinv21 分钟前
项目搭建+图片(添加+图片)
java·服务器·前端
青莳吖23 分钟前
Java通过Map实现与SQL中的group by相同的逻辑
java·开发语言·sql
逆旅行天涯28 分钟前
【Threejs】从零开始(六)--GUI调试开发3D效果
前端·javascript·3d
Buleall30 分钟前
期末考学C
java·开发语言
重生之绝世牛码32 分钟前
Java设计模式 —— 【结构型模式】外观模式详解
java·大数据·开发语言·设计模式·设计原则·外观模式
小蜗牛慢慢爬行38 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试