vue3中v-model里小众但很好用的语法

2,496 阅读4分钟
本文原创,创作不易,引用请注明来源作者,谢谢各位看官老爷

前言

今天又是一个美好的周五 在我的上片文章《这次我们要说点不一样的Vue中h5移动端开发知识点》中有说到多层组件嵌套传值修改问题,只怪我学艺不精,用了一个很复杂的方法去解决当时的问题😵,在测试小姐姐的无微不至的测试下,终究是暴露了新的问题哈哈哈🙌

接下来我们就说说出现问题的原因以及解决方案

1.vue中常见的几种传值方式以及修改数据的方法

1.1 props和$emit

父组件在data中定义好我们要传递的数据,然后在引用的子组件上绑定该数据,然后通过$emit去触发父组件中的方法来改变数据达到伪双向绑定的效果,当组件层级较多的时候该方法依然适用,不过写起来会比较复杂,我相信大家也很少会遇见层级太深的组件,毕竟不方便其它人维护,这种方法就不贴代码了哈

1.2 $attrs和$listeners(在vue3中$listeners不再支持)

在类似作者的代码中,有父组件和一级子组件还有二级子组件,在父组件中定义好data中的变量后将变量绑定在引入的一级子组件中,然后在一级子组件中引入的二级子组件上绑定$attrs,这样二级子组件就可以直接通过$attrs.xxx访问到传入的变量

在vue2中将方法绑定在一级子组件上后,一级子组件引入二级子组件在子组件上通过v-on绑定$listeners,这样二级子组件就可以直接调用父组件的方法。注意注意!!在vue3中移出了$listeners,但是并不代表调用方法消失了,在官方文档中,调用绑定方法被合并到了$attrs中。

1.3 eventBus事件总线(vue3不再支持)

此处不做介绍

1.4 provide和inject

在父级中定义provide,provide用法和data一样,然后在二级子组件中定义inject接受 举个栗子:

父组件:provide:{
	test:"aaa"
},
二级子组件:inject:["test"]

{{test}}

1.5 $parent和$children

子调用父this.$parent.xxx,父调用子,在引入子组件的地方绑定一个方法调用this.$children.xxx

1.6 vuex

这个东西此处不做讲解

vue3中v-model新用法

我们往往在父子通信的时候会用this.$emit("方法名",要传递的值)去调用父的方法改动传递过来的值,这么做的目的是为了不破坏Vue中的单向数据流。那我们就会想到每一次都要在父调用子的时候绑定一个方法去触发,那引用的组件过多的时候挨个绑定就会比较复杂,这个时候vue3的新版v-model就提供了更好的解决方法,我们先看代码:

<Name v-model:nameValue="formData.nameValue" />
    <input
      type="text"
      placeholder="请输入真实姓名"
      class="nameInput"
      :value="nameValue"
      @input="handleInput"
      @compositionend="end"
      @compositionstart="start"
    />
    
    this.$emit("update:nameValue", e.target.value);

大家可以看到我并没有在父调用子组件的时候绑定方法,而是通过v-model:xxx=""向子组件传递数据,子组件正常在props中接受数据,这里要明确的是xxx要和子组件中接受的名字一致,这样在子组件更新数据的时候直接告诉父组件我要你改变的是哪一个数据,这样可以节省了很多不必要的代码量。俗话说的好:懒惰推动发展。

解决输入框闪烁问题

大家在看完我上一篇文章应该会发现我有一步置空的操作,这是为了保证每一次数据都发生了改变,在经过传值方式的改变后,我不走父组件修改而是直接在一级子组件中修改数据,那我因为每一次都置空再显示数据就会导致闪烁出现placeholder中的内容,那我就想如何保证每一次数据都发生变化又不用置空呢?这时候我想到了watch监听,我将判断输入内容长度写在了watch中,这样当我触发input事件的时候先向一级子组件发送一次改变告诉他我希望你改成这个数据,这样props接受的值就发生了改变,这个时候触发wacth,发现新数据超过一定长度,过滤掉多余的数据再次this.$emit("update:nameValue", nameValue);这样就可以保证每一次数据都发生了变化也不会出现闪烁啦。

##单向数据流问题 细心的小伙伴可能发现我父组件传递给一级子组件中的是一个对象,一级子组件给二级子组件传递的是字符串,那有人就会问,我直接改变一级子组件的数据不就会破坏了单向数据流吗?这也曾经困惑了我一下,后来按照我的理解来说,因为类似数组,对象这种复杂类型,我们其实传递的是空间地址,我们直接在一级子组件中修改数据改的是对象里面的数据,并没有修改对象的空间地址,自然也不会破坏单向数据流了啊,但是如果我们传递的是普通类型的数据就不能这么写了。自此,问题全部解决了。

感谢各位看官老爷抽空看完我的文章,大家觉得哪里不对的欢迎指出,也希望可以多多点赞关注支持嘿嘿喝。

--wy白菜 2021/3/5