关于 v-model 学习二

2019-07-18  本文已影响0人  人话博客

[上一篇 v-model] 的学习过程中,

我们知道了,一般在两种场景下,我们会使用到 v-model.

但是使用在 input 元素上和使用在组件上在某种程度上来说,还是有很大的区别的.

在 v-mode 使用在 input 元素上时, v-model 帮我们做了两件事情.


<input type='text' v-model="data" />
  1. 将 data 的值使用 :value 属性绑定的形式绑定到了 input 元素的 value 属性上.
  2. 在父组件内,监听 input 元素的 @input 事件,并同步更新 data.

在组件上使用 v-model 时

<test-comp v-model="data"></test-comp>

很大的区别在于:

由于子组件,是一个组件,我 v-model 能做的事情,仅仅只是默认传个 props.value 给你,以及在我父组件内部默认监听你子组件内部不知道是谁发布的 input 事件.

但是在子组件中,或者说在子组件中,可能有很多 input 元素需要用到这个 v-model 传递过来的值.

比如 里面有 2 个 input(一个用户名,一个密码),一个 checkbox 等等等.

那么父组件通过 props 传递过来的数据给谁用的?(用户名,密码,还是 checkbox?)

监听谁的事件?((用户名和密码框都是 input ,checkbox 则是 change)

所以,在组件上使用 v-model,我们需要在被接受 v-model 的子组件内进行更细致的配置.

因为默认在使用 v-model 往子组件传递数据时,父组件只负责传递 :value="data" & 在自己内部监听子组件发布出来的 input 事件.


如何配置 v-model 传递的 props 名字以及父组件监听的事件呢?

为什么要会 v-model的 prop 和 event 配置呢?

prop 呢 ? 不就是把数据以 :value 的方式传递进去吗?而且应该是给 input 元素使用不是吗?

event 呢? 默认是父组件监听 input 事件. 这有什么不好吗? 传给输入框使用,本身就应该监听 input 事件呀?为什么要改默认监听的事件呢?

道理也很简单:

在表单元素中,咱们用到的最多的可能就是 input 文本框输入.

对于输入框(比如 text textarea) 来说,:value 默认传进去正好好.

关键在于,input 表单元素,不只有输入框,还有 checkbox select 等.

首先 ,它们的 value 和 input 一样,不是给用户看的(虽然都是往后台提交的)
并且, 它们作为 input 元素来说,自己状态变动也不是 input,而是 change.

所以, 如果一直使用 组件的 v-model 的默认配置(value & input)显然是不合适的.

比如,我有一个组件,内部是一个 <select></select>.

所以,默认的 props.value 和 input 事件就不合适.

因为 value 不需要我传,内部的 <select></select> 本身就定义了 options . 而 options 里包含了 value.

input 事件也不合适, 因为 <select></select> 事件是 change.

于是,我们需要在包含了 <select></select> 组件的内部重新定义 v-model 的两个默认配置.

const TestComp = {
    model: {
      prop: 'getDataFromParentByVModel', // 将默认的 value props 改成 getDataFromParentByVModel
      event: 'change' // 让父组件默认监听 change 事件.
    },
    props: ['getDataFromParentByVModel']
  }
  

然后在子组件的内部:

let ChildComp = {
    template: `
        <div>
        //....other html and components
         <select :value="getDataFromParentByVModel" @change="hanlderSelectChange">
            <option disabled value="">请选择</option>
            <option>A</option>
            <option>B</option>
            <option>C</option>
         </select>
        </div>
    `,
    
    method: {
      hanlderSelectChange (e) {
        // 在这就要触发 change 事件了.
        this.$emit('change',e.target.value)
      }
    }
}


查看效果:

image.png image.png image.png

两边修改可以互相影响(这也就是 v-model 的作用所在).

其实传统的像什么父子组件间传值.

但是上述两种常规做法,都是单向的.

组件上使用 v-model 也可以作为一个非常好用的父和子之间相[互传递数]据的一种方式.(双向的.)

上一篇下一篇

猜你喜欢

热点阅读