美文网首页
关于 v-model 学习二

关于 v-model 学习二

作者: 人话博客 | 来源:发表于2019-07-18 22:58 被阅读0次

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

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

    • 使用在 input 表单元素上.
    • 使用在组件上.

    但是使用在 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>
    
    • 将 data 以 props 的形式传递到子组件内.
    • 父组件将默认监听子组件发布出来的 input 事件.并同步更新子组件传递回来的数据,以更新 v-model 对应的值.

    很大的区别在于:

    由于子组件,是一个组件,我 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 默认传进去正好好.

    • value 就是它们需要显示的内容.
    • input 正好也是它们的 value 在改变时触发的事件...(虽然也要子组件自己监听 dom 再 $emit 一次).

    关键在于,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']
      }
      
    
    • model.prop = 'getDataFromParentByVModel' 修改默认的 v-model 传递的属性绑定是 :value
    • event = 'change' 让提供了 v-model 的父组件默认的监听子组件发布出去的 change 事件.
    • props: ['getDataFromParentByVModel'] v-model 传递过来的是 getDataFromParentByVModel,在子组件内部还是得定义一下对应的 props (就想默认定义 props:['value']) 一样.

    然后在子组件的内部:

    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 的作用所在).

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

    • 父向子 使用 props .
    • 子向父 使用 $emit ..

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

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

    相关文章

      网友评论

          本文标题:关于 v-model 学习二

          本文链接:https://www.haomeiwen.com/subject/lrcdlctx.html