使用computed拦截v-model
# 子组件不直接修改父组件数据,使用computed拦截处理
现有方案
vue-use 中的 useVModel (opens new window)
<!---子组件-->
<template>
<el-input v-model="model.keyword" />
</template>
<script setup>
import { useVModel } from "./hook.js";
const props = defineProps({
modelValue: {
type: Object,
required: true,
},
});
const emit = defineEmits(["update:modelValue"]);
const model = useVModel(props, "modelValue", emit);
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// hook.js
import { computed } from "vue";
const cacheMap = new WeakMap();
export function useVModel(props, propName, emit) {
return computed({
get() {
if (cacheMap.has(props[propName])) {
return cacheMap.get(props[propName]);
}
const proxy = new Proxy(props.modelValue, {
get(target, key) {
return Reflect.get(target, key);
},
set(target, key, value) {
emit("update:" + propName, {
...target,
[key]: value,
});
return true;
},
});
cacheMap.set(props[propName], proxy);
return proxy;
},
set(val) {
emit("update:" + propName, val);
},
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
上次更新: 2023/08/30, 10:27:46