Vue input文本框v-model与ref.value不能同时使用赋值,如何实现操作节点方式赋值?
我们开发时有是会遇到这样一个场景,点击某一个文本框,蹦出弹窗,里面是一系列的表格,勾选表格项,将其指定的内容赋值到对应的我们点击的那个文本框上。如下 需求现在有两个文本框,当我们点击时让其蹦出弹窗,内容123变成abc。我们可以看到,两个对应的v-model值已经绑定到了对应的文本框上面。methods: {proup(dom) {let vm = this// Dialog是vant的弹窗Dia
我们开发时有是会遇到这样一个场景,点击某一个文本框,蹦出弹窗,里面是一系列的表格,勾选表格项,将其指定的内容赋值到对应的我们点击的那个文本框上。
如下 需求
现在有两个文本框,当我们点击时让其蹦出弹窗,内容123变成abc。
我们可以看到,两个对应的v-model值已经绑定到了对应的文本框上面。
methods: {
proup(dom) {
let vm = this
// Dialog是vant的弹窗
Dialog.alert({
title: '我是一个弹窗',
message: '我要给其对应的内容进行赋值',
}).then(() => {
vm.form.inp = 'abc'
console.log('我完成了赋值')
})
},
},
此时我们可以看到,当我们勾选确定时对应的123也就随机变成了abc,我们此时可以看到对应的值是写死的
vm.form.inp1=‘abc’
并不是说我们想要去点击哪一个,哪一个的值就会变
那么如何实现对应的功能呢?
其实我们在@click点击事件时就已经传递了对应的值,我们可以根据对应的值去进行判断
methods: {
proup(dom) {
let vm = this
// Dialog是vant的弹窗
Dialog.alert({
title: '我是一个弹窗',
message: '我要给其对应的内容进行赋值',
}).then(() => {
if (dom == 'inp1') {
// 给inp1进行赋值
vm.form.inp1 = 'abc'
} else if (dom == 'inp2') {
vm.form.obj.inp2 = 'abc'
}
})
},
},
当然这样好吗?如果我们只有一个或者两个文本框的话可以采用这种方式,但注意如果后续我们新增需求,新增条件的话,肯定会造成代码的高度耦合,并且繁琐不好维护,我们能不能就是用另一种方法实现此功能呢?
思路1、ref方式,操作dom,变更dom的value实现功能
首先一定会有人问了为什么要用ref呢?用ref的需求是什么,我直接给那个对应点击的设置一下不行吗?event?事件对象?其实我们可以尝试一下。
proup(e,dom) {let vm = this
Dialog.alert({
title: '我是一个弹窗',
message: '我要给其对应的内容进行赋值',
}).then(() => {
// vm.form.inp = 'abc'
// console.log('我完成了赋值')
// 如果现在的需求是,点击哪一个给哪一个赋值,我想给form.obj.inp2进行赋值呢?
// 其实第一想到的就是if else进行判断,我们在事件触发时来进行判断当前点击的是哪一个,点击的是哪一个,我们给哪一个进行赋值
if (dom == 'inp1') {
// 给inp1进行赋值
// vm.form.inp1 = 'abc'
e.path[0].value ='abc' // 当然e.target.value 也同样是可以的
console.log(vm.form.inp1)
} else if (dom == 'inp2') {
vm.form.obj.inp2 = 'abc'
}
})
},
我们可以看到在上方我调用了事件对象,获取到了当前点击的节点,并且我们可以获取到当前点击的文本框,但是我们需要注意的一点是什么,值可以更改,但是v-model对应绑定的值是不可以更改的,
其实很简单的一个逻辑
v-model是双向绑定,学过vue的同学大家对其都会有一个简单的概念,但是大家要记住,他底层是如何实现的呢?
简单的来说 他是 :value与 @input事件的结合体
我们可以看一下oninput事件是如何触发的
input:当文本框的值发生改变、存在焦点时(实时更新),会触发 input事件。
回过头来我们就可以顺通这个逻辑 为什么节点的value值已经变了,但是v-model的值却没有变更,因为这个事件本身是没有进行触发的
如果想要让其值进行变更的话那么怎么样实现呢,其实顺着这个input事件,那么我们让其获取焦点不就完了吗?
看结果
其实我们可以看到,对应的焦点是在的,value的值也同样变更了的,但是form中对应v-model绑定的inp1值并没有改变
所以从逻辑上来说 文本变更+获取焦点 /= Input事件
那么如何实现功能呢?
回到我们上面说的ref,其实转过来说ref其实也就事件对象的方式
我们可以看到这个时候控制台已经报错,虽然v-model值已经变更,但是会报子组件更改prop的错误,爆红,那当然是行不通的。
那么现在我们需不需要另辟途径呢?注意,我们上方说到的,v-model的原理是什么 :value和@input事件,那么我们手动的使用js调用一次input事件不就可以了吗?
我们可以这样 使用事件对象
Dialog.alert({
title: '我是一个弹窗',
message: '我要给其对应的内容进行赋值',
}).then(() => {
// vm.form.inp = 'abc'
// console.log('我完成了赋值')
// 如果现在的需求是,点击哪一个给哪一个赋值,我想给form.obj.inp2进行赋值呢?
// 其实第一想到的就是if else进行判断,我们在事件触发时来进行判断当前点击的是哪一个,点击的是哪一个,我们给哪一个进行赋值
if (dom == 'inp1') {
// 给inp1进行赋值
// 让其获取焦点是不是就可以实现了呢?
e.target.value = 'abc'
// 手动调用input事件
e.target.dispatchEvent(new Event('input'))
} else if (dom == 'inp2') {
vm.form.obj.inp2 = 'abc'
}
})
我们可以看到对应的文本框就已经变成对应的值,并且v-model的值也已经进行了改变
另一种解题思路
通过参数传递,来实现功能
js代码
proup(e, dom) {
// 定义获取对应的对象,forEach进行循环遍历
let ele = this.form
dom.forEach((element,index) => {
// 判断当前的index索引是不是参数的最后一项
if(index == dom.length -1){
// 如果是最后一项相当于是对象之前了,最后一个了,对象赋值
ele[element] = 'aaa'
}else{
// 否则向下递归 接着让其等于对象,就像inp2一样
ele = ele[element]
}
})
}
此时功能即实现。
更多推荐
所有评论(0)