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

......待更新

相关推荐
拾荒的小海螺2 分钟前
JAVA:探索 PDF 文字提取的技术指南
java·开发语言·pdf
是Dream呀6 分钟前
Python从0到100(七十三):Python OpenCV-OpenCV实现手势虚拟拖拽
开发语言·python·opencv
村东头老张6 分钟前
Java 实现PDF添加水印
java·开发语言·pdf
吃葡萄不吐葡萄皮嘻嘻12 分钟前
el-table实现最后一行合计功能并合并指定单元格
前端·vue.js·elementui
胜天半子_王二_王半仙1 小时前
c++源码阅读__ThreadPool__正文阅读
开发语言·c++·开源
gz94561 小时前
windows下,用CMake编译qt项目,出现错误By not providing “FindQt5.cmake“...
开发语言·qt
zxg_神说要有光1 小时前
快速入门 AI:调用 AI 接口生成 React 组件
前端·javascript·node.js
sukalot1 小时前
windows C#-异步编程模型(下)
开发语言·windows·c#
佚名程序员1 小时前
【Node.js】深入理解 V8 JavaScript 引擎
前端·javascript·node.js
水w1 小时前
Node.js windows版本 下载和安装(详细步骤)
开发语言·前端·windows·npm·node