zoukankan      html  css  js  c++  java
  • Vue进阶——解析V-MODEL

    最近重新过了一遍VUE官方文档,发现有些知识点官方解释的不是很清楚,所以在此深入解析一下,希望能帮到和我一样看文档遇到困惑的朋友们。

     

    这里关于v-model,官方说明篇幅甚少,留下了一些疑问,下面详细解析v-model知识点。

    一、v-model用在input上

    v-model虽然很像使用了双向数据绑定的 Angular 的 ng-model,但是 Vue 是单项数据流v-model 只是语法糖而已:

    // 最简形式,省略了value的显式绑定,省略了oninput的显式事件监听,是第二句代码的语法糖形式
    <
    input v-model="sth" />
    <input v-bind:value="sth" v-on:input="sth = $event.target.value" />

    //第二句代码的简写形式 <input :value="sth" @input="sth = $event.target.value" />

    首先你要知道 ,在HTML5新特性中,input 元素本身就有个 oninput 事件,类似 onchange ,每当输入框内容发生变化,就会触发 oninput ,把输入框最新的value值传递给 sth(第二句代码)。

    关于$event,懂的朋友请忽略,$event知识点传送门

    我们仔细观察语法糖和后两句完整版本代码,可以得出一个结论:

    在给 <input /> 元素添加 v-model 属性时,默认会把 value 作为v-model的属性,默认把 'input' 事件作为实时传递 value 的触发事件,这就是官方文档这句话的意思:

    二、v-model用在组件上

    明白了v-model只是语法糖,它的默认值是value,默认监听事件是oninput,我们来看一个稍复杂的例子,它是将v-model使用在组件上。

    类似于下图的效果,父组件的 price 的初始值是 100,更改子组件的值能实时更新父组件的 price

    <div id="demo">
      <currency-input v-model="price"></currentcy-input>
      // 实际上是下列代码
      //<currency-input v-bind:value="price" v-on:input=" price = arguments[0] "></currency-input>
     <span>{{price}}</span> </div> <script> Vue.component('currency-input', { template: ` <span> <input :value="value" <!--这里之所以把 'input' 作为事件名向父级传递,正是因为非语法糖形式中v-on:input监听的是input事件--> @input="$emit('input', $event.target.value)" > </span> `, props: ['value'],// 这里的value正是被简写掉的,所以语法糖形式你找不到这个value在哪里绑定的,而在非语法糖形式找得到 }) var demo = new Vue({ el: '#demo', data: { price: 100, } }) </script>

    现在你一定对于v-model是语法糖形式理解更深刻了,也对官方文档的困惑一点点明了了。

    三、v-model的不足与解决方案

    它的不足在官方文档也提出来了:

     我们来看看具体是什么意思。

    在创建类似复选框或者单选框的常见组件时,v-model就不好用了。

    <input type="checkbox" v-model="sth" />

    v-model 给我们默认提供了 value 属性和 oninput 事件,但是在这里我们需要的不是 value 属性,而是 checked 属性,并且当你点击这个单选框的时候不会触发 oninput 事件,它只会触发 onchange 事件。这就是问题所在。

    这是 v-model 只用在 input 上的情况,解决方案如下:

    <input type="checkbox" :checked="status" @change="status = $event.target.checked" />

    当v-model用在组件上时,解决方案如下:

    <my-checkbox v-model="foo"></my-checkbox>
    
    Vue.component('my-checkbox', {
      tempalte: `<input 
                   type="checkbox"
                   @change="$emit('input', $event.target.checked)"
                   :checked="value"
                 />`
      props: ['value'],
    })

    不明白的同学可以自己将语法糖形式写成完整的非语法糖形式,再结合前面的讲解进行分析。

    四、在 Vue 2.2 版本,你可以在定义组件时通过 model 选项的方式来定制 prop/event:

    //在这个组件中使用 v-model
    <base-checkbox v-model="lovingVue"></base-checkbox>
    
    Vue.component('base-checkbox', {
      model: {
        prop: 'checked',
        event: 'change'
      },
      props: {
        checked: Boolean
      },
      template: `
        <input
          type="checkbox"
          v-bind:checked="checked"
          v-on:change="$emit('change', $event.target.checked)"
        >
      `
    })

    lovingVue 的值就会传递给 checked prop。当 <base-checkbox> 内部触发一个 change 事件,并且传递一个新值,lovingVue 属性就会进行更新。

    注意,仍然需要在组件 props 选项中声明 checked prop 属性。

  • 相关阅读:
    MOSS2007图片库的幻灯片视图在IE8标准渲染模式下的bug及其修正
    分享一个WM上绘制饼图、柱形图、折线图的控件类
    C# 中启动进程的三种方法
    SSCLI 包含了微软的CLI ,C#,JScript....的源码,学习.Net的不看怎么行
    (2)继承关系中的多态性编译时与运行时
    .NET.性能:装箱与拆箱、string stringBuilder、struct class、Add AddRangle等影响性能分析
    .NET.GC学习总结
    .NET.GC 浅谈.net托管程序中的资源释放问题 (转帖)
    (1)通过IL来看构造函数
    conda的使用
  • 原文地址:https://www.cnblogs.com/Double-Zhang/p/9104283.html
Copyright © 2011-2022 走看看