Vue.js ElementUI 切换下拉框控件显示时显示了错误的文字
页面共有三个下拉框,后面两个根据第一个下拉框的值来切换显示,具体代码如下:
xml
<template>
<el-dialog :title="isEdit ? '编辑': '新增'" width="45%"
:visible.sync="visible" :before-close="close" label-position="right"
:modal-append-to-body="false"
:close-on-press-escape="false"
:close-on-click-modal="false">
<el-form ref="ent" :model="ent" :rules="rules" label-width="120px">
<el-form-item label="类型" prop="type">
<el-select v-model="ent.type" placeholder="请选择" style="width: 100%">
<el-option :key="1" label="链接" :value="1" />
<el-option :key="2" label="应用" :value="2" />
</el-select>
</el-form-item>
<el-form-item v-if="ent.type == 1" label="链接" prop="link">
<el-select v-model="ent.link" placeholder="请选择链接" :disabled="ent.type != 1" style="width: 100%">
<el-option :key="1" label="链接1" :value="1" />
<el-option :key="2" label="链接2" :value="2" />
</el-select>
</el-form-item>
<el-form-item v-if="ent.type == 2" label="应用" prop="appletIds">
<el-select v-model="ent.appletIds" multiple clearable placeholder="请选择应用" :disabled="ent.type != 2" style="width: 100%">
<el-option :key="1" label="应用1" :value="1" />
<el-option :key="2" label="应用2" :value="2" />
</el-select>
</el-form-item>
</el-form>
</el-dialog>
</template>
类型选择为 链接 后,链接下拉框显示,选择 链接 1。
之后切换类型为 应用 ,此时应用的下拉框值应该为空,但是却显示为 链接 1 。
此时控件的 value
值为 链接 1 。
之后尝试了如下几种方法:
- 调整控件位置
切换第二个和第三个下拉框时仍然还是有这个问题。只有将第三个下拉框调整到第一个下拉框之前时,才能正常显示。 - 改变第一个下拉框选项的同时,重置其它两个下拉框的值
不能正常显示。 - 删除第三个下拉框的 multiple 属性
可以正常显示,但是这个不符合需求。 - 在第三个下拉框前面加一个
display: none
的下拉框
可以正常显示,就是代码有点丑陋。
最后在同事的帮助下,才发现对这两个控件分别指定一个 key
就可以了。
代码如下:
xml
<template>
<el-dialog :title="isEdit ? '编辑': '新增'" width="45%"
:visible.sync="visible" :before-close="close" label-position="right"
:modal-append-to-body="false"
:close-on-press-escape="false"
:close-on-click-modal="false">
<el-form ref="ent" :model="ent" :rules="rules" label-width="120px">
<el-form-item label="类型" prop="type">
<el-select v-model="ent.type" placeholder="请选择" style="width: 100%">
<el-option :key="1" label="链接" :value="1" />
<el-option :key="2" label="应用" :value="2" />
</el-select>
</el-form-item>
<el-form-item v-if="ent.type == 1" label="链接" prop="link">
<el-select key="link" v-model="ent.link" placeholder="请选择链接" :disabled="ent.type != 1" style="width: 100%">
<el-option :key="1" label="链接1" :value="1" />
<el-option :key="2" label="链接2" :value="2" />
</el-select>
</el-form-item>
<el-form-item v-if="ent.type == 2" label="应用" prop="appletIds">
<el-select key="appletIds" v-model="ent.appletIds" multiple clearable placeholder="请选择应用" :disabled="ent.type != 2" style="width: 100%">
<el-option :key="1" label="应用1" :value="1" />
<el-option :key="2" label="应用2" :value="2" />
</el-select>
</el-form-item>
</el-form>
</el-dialog>
</template>
那么这个 key
属性是用来做什么的呢?
下面的说明摘自官方文档。
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:
xml<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template>
那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,
<input>
不会被替换掉——仅仅是替换了它的 placeholder。自己动手试一试,在输入框中输入一些文本,然后按下切换按钮:
这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key attribute 即可:
xml<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email-input"> </template>
现在,每次切换时,输入框都将被重新渲染。请看:
注意,
<label>
元素仍然会被高效地复用,因为它们没有添加 key attribute。
上面的说明完美的解释了遇到的问题,这一切都是元素复用导致的。
个人觉得这仍然是 ElementUI 的一个 bug,毕竟这两个下拉框跟官方文档中的场景并不完全一样,都是绑定了属性的,应该保证页面的展示和绑定的属性值一致。