Vue3 二次封装 Element Plus Form 组件的疑问?

Vue3 二次封装 Element Plus Form 组件的疑问?

原因是这样的,因为项目中需要频繁的使用 form 表单,劳动力感觉非常重复,就决定还是对 element-plus 的 form 组件进行二次封装,尽量的做到配置化的开发。其中在开发 select 的 remote 模式的时候遇到了一些问题,自己调试了很久也没有找到解决办法。代码如下:

代码块 1 为二次封装的组件。核心思路就是根据 formItem 中的 type 字段,渲染不同类型的表单组件。

// 仅展示有问题的核心逻辑

<template>

<el-form class="table-search-form"

:model="props.model"

:rules="props.rules">

<el-row :gutter="32">

<el-col

v-for="(formItem, index) in props.formItems"

:key="index"

:span="formItem.span ? formItem.span : 6">

<el-form-item

:label="formItem.label"

:prop="formItem.prop">

<-- 隐藏其他类型 -->

<el-select

v-if="formItem.type === FORM_ITEM_TYPES.REMOTE_SELECT"

v-model="props.model[formItem.prop]"

:placeholder="formItem.placeholder ? formItem.placeholder : formItem.label"

clearable

filterable

remote

:remote-method="formItem.remoteMethod"

style="width: 100%;">

<el-option

v-for="(option, index) in formItem.options"

:key="index"

:label="option.label"

:value="option.value"/>

</el-select>

</el-form-item>

</el-col>

</el-row>

</el-form>

</template>

<script lang="ts" setup>

import {defineProps} from 'vue'

enum FORM_ITEM_TYPES {

INPUT = 'input',

SELECT = 'select',

REMOTE_SELECT = 'remoteSelect'

}

const props = defineProps({

formItems: {

type: Array,

default: () => []

},

model: {

type: Object,

default: () => ({})

},

rules: {

type: Object,

default: () => ({})

}

})

</script>

代码块 2 为使用模块。

<template>

<table-search-form

:form-items="formItems"

:model="model"

:rules="rules"/>

</template>

<script lang="ts" setup>

import {reactive, ref} from 'vue'

import TableSearchForm from '@/components/TableSearchForm/index.vue'

const roles = ref<any[]>([

{label: 'Role 1', value: 1}

])

const handleRemoteMethod = (query: string) => {

setTimeout(() => {

roles.value = [

{label: 'Role 2', value: 2},

{label: 'Role 3', value: 3}

]

// 打印点 1

console.log(roles.value)

}, 1000)

}

const formItems = [

// ...省略

{

label: '角色 ID',

prop: 'roleId',

type: 'remoteSelect',

remoteMethod: handleRemoteMethod,

options: roles.value

}

]

const model = reactive({

username: '张三',

gender: 0,

roleId: ''

})

const rules = {

username: [{required: true, message: '用户名未输入。', trigger: 'none'}]

}

</script>

问题

因为是 remote 模式的 select ,所以我会传入一个 handleRemoteMethod 函数,动态修改它的 options ,这里的 options 用了一个 ref 进行接受然后传递到组件内部。但是当我发现触发 handleRemoteMethod 之后,打印出来的值(即:打印点 1 )已经修改了,但是组件渲染依旧只有 “Role 1” 这 1 个选项。但是我使用 roles.value.push(...[]) 的方法,可以正常的改变其渲染。
请问各位大佬,这是为啥?我应该如何做,求答疑解惑。


回答:

因为远程获取数据之后,formItems.value[0].options !== roles.value, roles.value重新设置了,formItems.value[0].options还指向原对象,roles.value已经指向新对象了。

把formItems设置成computed就可以了

const formItems = computed(() => {

return [

// ...省略

{

label: '角色 ID',

prop: 'roleId',

type: 'remoteSelect',

remoteMethod: handleRemoteMethod,

options: roles.value

}

]

})

以上是 Vue3 二次封装 Element Plus Form 组件的疑问? 的全部内容, 来源链接: utcz.com/p/936490.html

回到顶部