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]);

......待更新

相关推荐
Coding小公仔1 小时前
C++ bitset 模板类
开发语言·c++
小白变怪兽1 小时前
一、react18+项目初始化(vite)
前端·react.js
ai小鬼头1 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
小赖同学啊1 小时前
物联网数据安全区块链服务
开发语言·python·区块链
shimly1234561 小时前
bash 脚本比较 100 个程序运行时间,精确到毫秒,脚本
开发语言·chrome·bash
IT_10242 小时前
Spring Boot项目开发实战销售管理系统——数据库设计!
java·开发语言·数据库·spring boot·后端·oracle
墨菲安全2 小时前
NPM组件 betsson 等窃取主机敏感信息
前端·npm·node.js·软件供应链安全·主机信息窃取·npm组件投毒
GISer_Jing2 小时前
Monorepo+Pnpm+Turborepo
前端·javascript·ecmascript
天涯学馆2 小时前
前端开发也能用 WebAssembly?这些场景超实用!
前端·javascript·面试