element模态框dialog中的select组件中选中无反应

1、问题描述

准确说,是在dialogel-from组件中的el-select组件,打开模态框时,对select绑定的数据重新赋值value1,select视图层状态会变成value1,但之后变更option选项,select视图层*不再更新。

一般是在新建或编辑数据,弹出dialog模态框,在弹窗的表单里对该条数据进行编辑修改。

<el-dialog :visible.sync="dialogEdit">
    <el-form ref="editValidateForm" :model="editValidateForm">
    	...
        <el-form-item prop="workType" label="类型:">
            <el-select v-model="editValidateForm.workType" 
                       placeholder="请选择类型" 
                       @change="handleChange">
                <el-option v-for="(item,index) in types" 
                           :key="index" 
                           :label="item.name" 
                           :value="item.value">
                    {{item.name}}
                </el-option>
            </el-select>
        </el-form-item>
    </el-form>
</el-dialog>

editValidateForm在data里会有一组初始数据:

export default {
   name: "test",
   data(){
       return{
           editValidateForm:{
           	...
               workType:'',
           }
       }
   },
   methods:{
   		open(){},
   		handleChange(){}
   }
}

2、问题情况1

如果是单纯地dialogEdit = true打开模态框,不对表单数据进行重新赋值,是不会出现问题的。

如果有问题,可能是vue或者element的版本bug,我用的elemnt2.4.6,没有这个bug,这里也不针对这种情况说明。

3、问题情况2

如果在打开dialog的同时,对这个数据进行赋值:

this.editValidateForm.worktType = 1

会看到select的选中项变为1,但是之后再选其他option无法选中。
其实这里只是视图层没有更新,在select的change方法里监听,this.editValidateForm.worktType的值是改变了的。

出现这个问题好像是因为下拉框数据是循环掉别的接口得来的,因为数据层次太多,render函数没有自动更新,需手动强制刷新

3.1 尝试1

由此,我想到vue文档里说过,利用索引直接设置数组一个原本不存在的项时
this.items[index] = newValue
不会使视图更新,为了针对这种情况,vue提供了set方法vm.$set(target,propertyName/index,value),以此赋值并更新视图。和这里的问题有些像,我尝试了用set方法赋值:

this.$set(this.editValidateForm,'workType','1');

问题解决了,这种方法应该是属于强制刷新,针对我的这种情况是有效的

3.2 尝试2

强制刷新这个点出发,还有一个解决方法,也是vue API文档提供了vm.$forceUpdate()方法:

迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

我们赋值照旧,但是在select的change函数里加上这个方法:

open(){
	..
	this.editValidateForm.worktType = 1
}
handleChange(){
	this.$forceUpdate();
}

同样解决了这个问题。

3.3 尝试3

在编辑时,因为这条数据已存在,点击数据请求数据信息,在success回调里这样对数据进行赋值:

requestApi(params).then(function(res) {
	this.editValidateForm =  res.data;
})

在这种情况下,是没有这类bug的。由此联想即使目标只是给workType这一项重新赋值,也要给整个this.editValidateForm对象赋值:

this.editValidateForm = {
	...
	workType:"1"
}

问题解决。但这样比较繁琐,为了一个属性,就要重新赋值整个对象。

3.4 尝试4

由尝试3,同样是在dialog里,但是给表单中的select组件绑定一个data子属性级的数据,也就是说将绑定的workType移到与editValidateForm同级,也能解决这个问题:

<el-form-item label="类型:">
    <el-select v-model="workType" 
               placeholder="请选择类型">
        <el-option v-for="(item,index) in types" 
                   :key="index" 
                   :label="item.name" 
                   :value="item.value">
            {{item.name}}
        </el-option>
    </el-select>
</el-form-item>
data(){
       return{
      	   workType:'',
           editValidateForm:{
           	... 
           }
       }
   },

3.5 尝试5

因为这是改别人的代码,后来发现虽然上面的方法确实能解决我的问题,但我这里视图不更新真正的原因是上面这行代码,去掉后就不存在这个问题了:

 methods:{
	open(){
		 this.editValidateForm = {};	//问题所在
		 this.editValidateForm.worktType = 1
	},
}

思考了下,觉得应该是这样:先将表单对象editValidateForm置为空对象,那这个对象之前所有的属性包括worktType 都不存在了,之后再通过“.”这样的方式对一个不存在的对象属性进行赋值。这样一来就不是尝试1里说的情况相似,而是就是同样的问题:
https://cn.vuejs.org/v2/guide/list.html

数组更新检测
注意事项
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue

对象更改检测注意事项
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性

所以尝试3能解决问题的根源也在于它是对已存在的editValidateForm对象赋值

在vue里,当你对一个不存在的属性或对象直接“.”进行赋值,或者对数组不存在的索引项直接用索引赋值,从控制台打印可以看到数据变更,但无法使视图更新

所以,即使这个form不在dialog里,这样赋值也会不更新视图。遇到这种情况都可以用上面的方法试试

好的,针对你的问题,我进行如下回答: 1. 新增模态框功能实现: (1)首先,在你的vue组件中,需要定义一个状态变量,用来判断是否显示新增模态框: ``` // 定义状态变量 data() { return { showAddModal: false // 是否显示新增模态框 } } ``` (2)在模板中,使用element-ui的el-dialog组件来展示新增模态框: ``` <template> <div> <!-- 展示新增按钮 --> <el-button @click="showAddModal = true">新增</el-button> <!-- 定义新增模态框 --> <el-dialog title="新增数据" :visible.sync="showAddModal" width="30%"> <!-- 在这里放置新增表单 --> <!-- 定义确认按钮 --> <span slot="footer" class="dialog-footer"> <el-button @click="showAddModal = false">取消</el-button> <el-button type="primary" @click="onAdd">确认</el-button> </span> </el-dialog> </div> </template> ``` (3)在onAdd方法中处理新增逻辑,并在成功后关闭新增模态框: ``` methods: { onAdd() { // 处理新增逻辑 // ... // 关闭新增模态框 this.showAddModal = false; } } ``` 2. 删除功能实现: (1)在vue组件中定义一个列表数据: ``` // 定义状态变量 data() { return { listData: [ { id: 1, name: '张三' }, { id: 2, name: '李四' }, { id: 3, name: '王五' } ] } } ``` (2)在模板中,使用element-ui的el-table组件来展示列表,并添加删除按钮: ``` <template> <div> <!-- 定义数据表格 --> <el-table :data="listData"> <!-- 定义列 --> <el-table-column prop="id" label="ID"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column label="操作"> <!-- 定义删除按钮 --> <template slot-scope="scope"> <el-button type="danger" @click="onDelete(scope.$index)">删除</el-button> </template> </el-table-column> </el-table> </div> </template> ``` (3)在onDelete方法中处理删除逻辑: ``` methods: { onDelete(index) { // 获取待删除数据的id const id = this.listData[index].id; // 处理删除逻辑 // ... // 从列表中删除该数据 this.listData.splice(index, 1); } } ``` 以上是vue+element模态框中新增模态框和删除功能的实现方法,希望对你有所帮助。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值