zoukankan      html  css  js  c++  java
  • 你真的知道组件中的v-model吗?

    v-model的神奇


    html

    <div id="app">
     <input v-model="poin">
      {{ poin }}
    </div>
    

    js

    new Vue({
      el:'#app',
      data:{
        poin:'zqz'
      }
    })
    

    一旦我们输入的值发生变化,data中的poin值也会发生变化。

    理论上data中的值发生变化是会出发事件的,但是我们没看见?

    其实在vue的文档中有说明:

    <input v-model="something">
    

    是下面的语法糖

    <input v-bind:value="something" v-on:input="something = $event.target.value">
    

    每次我们输入的时候触发了input事件,input绑定了内联函数,从而改变了something的值。

    你好奇input事件是什么?

    <input><textarea> 元素的值更改时,DOM input 事件会同步触发。(对于 type = checkbox 或 type = radio 的输入元素,当用户单击控件时,输入事件不会触发,因为value属性不会更改。) 此外,当内容更改时,它会在 contenteditable 的编辑器上触发。在这种情况下,事件目标是编辑主机元素。如果有两个或多个具有 contenteditable 的元素为真,“编辑主机”是其父级不可编辑的最近的祖先元素。同样,它也会在 designMode 编辑器的根元素上触发。

    具体见:MDN的input事件

    组件中的v-model


    组件的v-model 生效原则

    • 接受一个value 属性
    • 在有新的value 时触发 input 事件

    我们先看一下代码

    el-input.vue

    <template>
    
        <div>
          <p>input的封装</p>
          <input type="text"
                 ref="input"
                 :value="value"
                 @input="updateValue($event.target.value)"
                 @focus="selectAll"
                 >
        </div>
    
    </template>
    <script>
    
    export default {
      name: 'el-input',
      props: {
        value: {
          type: Number,
          default: 0
        },
      },
      methods: {
        // 每次都会加一
        updateValue (value) {
          this.$refs.input.value = value + 1;
        },
        selectAll(event) {
          setTimeout(function () {
            event.target.select()
          }, 0)
        }
      }
    }
    
    </script>
    <style>
    </style>
    

    将这个组件在Tom.vue中使用

    <style>
    </style>
    <template>
        <!-- 在父组件中使用 -->
        <div>
          <v-el-input></v-el-input>
        </div>
    
    </template>
    <script>
    import vElInput from './el-input.vue'
    
    export default {
      name: 'tom',
      components: {
        vElInput
      }
    }
    
    </script>
    

    每次使用的时候都会在后面加个1

    但是问题来了,我们要如何在Tom.vue中取到这个值呢?

    • 方法一:使用事件 但是感觉有点曲线救国

    • 方法二:使用v-model

    这里就体现出了v-model的强大了,因为上面的语法糖,自动的绑定了input事件。所以我们可以利用这个特性去做些事情。

    给组件绑定v-model

    将Tom.vue的代码修改一下

    <template>
        <!-- 在父组件中使用 -->
        <div>
          <v-el-input v-model="eleValue"></v-el-input>
          eleValue的值:{{ this.eleValue }}
        </div>
    
    </template>
    <script>
    import vElInput from './el-input.vue'
    
    export default {
      name: 'tom',
      components: {
        vElInput
      },
      data () {
        return {
          eleValue: 666 //设置一个默认值
        }
      }
    }
    
    </script>
    

    初始状态

    输入后的状态

    然后当我们输入的值发生变化的时,我们预想的eleValue依旧没有发生变化,而el-input.vue中的value确发生了变化

    也是就是说value发生变化后没有传递(同步)到父组件中,这也就是vue1中的.sync的用处,而在vue2中已经废弃了。

    修改el-input.vue代码,增加this.$emit('input', value*1)

    ...
    updateValue (value) {
          this.$refs.input.value = value + 1;
          // 触发组件上绑定的input事件,以实现value同步
          this.$emit('input', value*1)
        },
    ...
    

    这下就实现了值的同步问题。

  • 相关阅读:
    UVA 408 (13.07.28)
    linux概念之用户,组及权限
    Java实现 蓝桥杯 历届试题 网络寻路
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 九宫重排
    Java实现 蓝桥杯 历届试题 九宫重排
  • 原文地址:https://www.cnblogs.com/zqzjs/p/6957310.html
Copyright © 2011-2022 走看看