请教一下非原生组件的v-model传值问题?

<template>

<ElTag

v-for="(item,i) in modelValue"

:key="item"

closable

@close="handleDelete(i)"

>

{{ item }}

</ElTag>

</template>

<script setup lang="ts">

import { ElInput, ElTag } from "element-plus";

const props = withDefaults(defineProps<{

modelValue?: string[];

}>(),{

modelValue: () => [],

});

const emits = defineEmits(["update:modelValue"]);

// 通过索引删除元素

function handleDelete(index: number) {

const data = props.modelValue.slice();

data.splice(index, 1);

emits('update:modelValue', data);

}

</script>

在上面的代码中,handlerDelete是将props.modelValue的原数组通过slice进行浅克隆,最后将浅克隆的值传回父组件,通过父组件修改原值,之所以使用这种传值方式,是因为我采用了react的更新机制。

然而由于vue本身是响应式数据,因此直接修改props.modelValue也能实现:

function handleDelete(index: number) {

// 这里甚至都不用emit事件

props.modelValue.splice(index, 1);

}

问题

因此这引发了我的一个思考:

  • 第二种直接修改props的方法虽然方便,但是带来了许多的隐患,组件内部随意更改外部值,会导致数据流紊乱,会导致许多的后期问题,因此不可取。
  • 但是第一种浅克隆的方式又丢掉了vue响应式的优势。

所以:我想问下有没有更优雅的方式实现v-model修改值呢?


回答:

emits('update:modelValue', data);的意思是触发update:modelValue事件通知父组件更新modelValue的值。所以按照同样的思路,我们可以在子组件中仅触发删除按钮的点击事件,在父组件中处理删除逻辑。

function handleDelete(index: number) {

emits('delete', index);

}

在实际业务中,数组内容的修改、删除、添加一般也会涉及到其他逻辑,比如请求接口等。所以这样看来,子组件仅负责数据的展示,父组件负责相关的数据修改、业务功能等,也是合理的。


回答:

虽然你在做双向绑定,但是最好还是遵循单向数据流,数据修改后通知父组件这个数据修改了,子组件不要去直接改props.modelValue

// 通过索引删除元素

function handleDelete(index: number) {

const data = props.modelValue.slice();

data.splice(index, 1);

emits('update:modelValue', data);

}

你这一段代码生效纯粹是因为数组是引用类型,传入之后 props.modelValue 和 data 都是引用地址而已,所以你改了 data,父组件的数据也改了

一般来说数据的双向绑定,会先将元数据深拷贝保存

const value = ref([])

watch(

() => props.modelValue,

(newVal) => {

value.value = cloneDeep(newValue)

}

)

function handleDelete(index: number) {

value.value.splice(index, 1)

emits('update:modelValue', value.value)

}


回答:

  1. 组件里很忌讳直接修改公共数据,基本上是万恶之源
  2. 所以第二种做法就不好
  3. vue 的优势不应该这么理解,Vue 的优势主要在于:只要你改了数据,就能改变视图。但是什么时候、该怎么改数据,仍然是我们要深思熟虑的。

故而这里通常应该是:

  • props.modelValue 克隆到本地,成为 localValue
  • 日常操作 localValue
  • 确认后,再提交给父组件

以上是 请教一下非原生组件的v-model传值问题? 的全部内容, 来源链接: utcz.com/p/934409.html

回到顶部