• 你真的知道组件中的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)
        },
    ...
    

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

  • 相关阅读:
    P1908 逆序对
    P3834 【模板】可持久化线段树 1(主席树)
    BZOJ 4300: 绝世好题
    Codevs 2185【模板】最长公共上升子序列
    P1439 【模板】最长公共子序列
    P3865 【模板】ST表
    【转】良心的可持久化线段树教程
    Codevs 1299 切水果
    P3388 【模板】割点(割顶)&& 桥
    P3805 【模板】manacher算法
  • 原文地址:https://www.cnblogs.com/zqzjs/p/6957310.html
Copyright © 2020-2023  润新知