vue3 reactive array push 值后 为什么还是会响应源值?
预览:https://stackblitz.com/edit/vitejs-vite-wnwsdn?embed=1&file=s...
<template> <div class="w-full">
<ul class="list-none w-full flex flex-col gap-2 mb-4 p-0">
<li v-for="(condition, index) of conditions" :key="index">
<ul
class="
list-none
w-full
rounded
border border-solid border-gray-200
@hover:border-gray-300
flex flex-row
justify-around
items-center
p-0
gap-2
"
>
<li class="flex-1 flex-inline items-center justify-center">
{{ resolveArray(condition.field, fields) }}
</li>
<li class="flex-1 flex-inline items-center justify-center">
{{ resolveArray(condition.symbol, symbols) }}
</li>
<li class="flex-1 flex-inline items-center justify-center">
{{ condition.value }}
</li>
<li class="flex-0 flex-inline items-center justify-center">
<el-button text bg @click.prevent="onCondDel(index)"> X </el-button>
</li>
</ul>
</li>
</ul>
<el-form
ref="condRef"
:model="cond"
label-position="top"
hide-required-asterisk
:rules="rules"
>
<el-row :gutter="10">
<el-col :span="6">
<el-form-item label="字段" prop="field">
<el-select v-model="cond.field" class="w-full">
<el-option
v-for="item of fields"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="运算符" prop="symbol">
<el-select v-model="cond.symbol">
<el-option
v-for="item of symbols"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="值" prop="value">
<el-input v-model="cond.value" placeholder="输入值" clearable />
</el-form-item>
</el-col>
<el-col :span="2">
<el-form-item label="操作">
<el-button plain @click="onCondAdd()"> + </el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted, watch } from 'vue';
const props = defineProps({
modelValue: {},
});
const emit = defineEmits(['update:modelValue']);
const rules = reactive({
field: [{ required: true, message: '字段必须选择' }],
symbol: [{ required: true, message: '运算符必须选择' }],
value: [{ required: true, message: '值不能为空' }],
});
const initialCond = reactive({
field: '',
symbol: '',
value: '',
});
const cond = reactive({ ...initialCond });
const conditions = reactive([]);
const condRef = ref(null);
const symbols = reactive([
{ label: '等于', value: 'eq' },
{ label: '不等于', value: 'ne' },
{ label: '包含', value: 'in' },
{ label: '不包含', value: 'ni' },
{ label: '大于', value: 'gt' },
{ label: '小于', value: 'lt' },
{ label: '大于等于', value: 'gte' },
{ label: '小于等于', value: 'lte' },
]);
const fields = reactive([
{ label: '姓名', value: 'fullname' },
{ label: '性别', value: 'gender' },
{ label: '手机', value: 'phone' },
{ label: '生日', value: 'birthday' },
{ label: '身份证', value: 'idcard' },
{ label: '年龄', value: 'age' },
]);
const onCondAdd = () => {
if (!condRef.value) return;
condRef.value.validate((valid) => {
if (valid) {
conditions.push(cond);
} else {
return;
}
});
};
const onCondDel = (index) => {
if (index !== -1) {
return conditions.splice(index, 1);
}
};
const resolveArray = (value, array) => {
if (!value) return;
const element = array.find((element) => element.value == value);
return `${element.label} ( ${element.value} )`;
};
</script>
<style scoped lang="scss">
.el-form--inline .el-form-item {
margin-right: 0;
}
</style>
回答:
cond
是一个对象,push 进去了,两边还是同一个对象,所以会同步更新。
切断引用关系就好了
内部是非引用类型,可以浅拷贝一下
- 比如上面的解构
{...cond}
- 还有 assign
也可以深拷贝,借用一些库
- JSON.parse(JSON.stringify)
- lodash.cloneDeep
本文参与了SegmentFault 思否面试闯关挑战赛,欢迎正在阅读的你也加入。
回答:
这里应改这样写
...const onCondAdd = () => {
if (!condRef.value) return;
condRef.value.validate((valid) => {
if (valid) {
conditions.push({...cond});
} else {
return;
}
});
};
...
以上是 vue3 reactive array push 值后 为什么还是会响应源值? 的全部内容, 来源链接: utcz.com/p/933936.html