自定义v-model用法

在vue中,v-model是用来进行数据双向绑定的一个语法糖,比如说用在input上,输入框数据变化,v-model绑定的对应的值也会跟着变化,无需单独获取。

其实v-model还可以在自定义组件中使用,可以被拆解为props:value和event:input,也就是说组件必须接收一个value值以及名为input的自定义事件,就可以在自定义组件上使用v-model了。

新建一个组件Input.vue

<template>
    <div class="input">
        <button @click="changeNum(-1)">-</button>
        <span>{{currentVal}}</span>
        <button @click="changeNum(1)">+</button>
    </div>
</template>

<script>
export default {
    props: {
      value: {
        type: Number,
        default: 0

    }},
    data() {
        return {
           currentVal: this.value
        };
    },
    watch: {
      value(val) {
        this.currentVal = val;
      }
    },

    methods: {
      changeNum(val) {
        this.currentVal += val;
        this.$emit('input',this.currentVal);
      }
    }
};
</script>
<style>
.input{
  display: flex;
}
</style>

在使用组件时:

<template>
    <div class="wrap">
        <input-model v-model="valueInput"></input-model>
    </div>
</template>

<script>
import InputModel from "./Input";
export default {
    components: {
        InputModel
    },
    data() {
        return {
          valueInput: 1
        };
    },
    watch: {
      valueInput(val) {
        console.log(val) // 在这里可以监听到值的变化
      }
    },

    methods: {
      changeArr
    }
};
</script>
<style>
</style>

可以看到,用了v-model后,无需在组件上显示的声明@input事件去监听、改变组件内部的数据变化,同样实现了数据的双向绑定。

这种一般会用在组件内部想要修改props传入的值的时候,因为组件内部是不允许直接修改props值,类似于这样的修改是会抛出错误的:

<template>
    <div class="input">
        <button @click="changeNum(-1)">-</button>
        <span>{{value}}</span>
        <button @click="changeNum(1)">+</button>
    </div>
</template>

<script>
export default {
    props: {
      value: {
        type: Number,
        default: 0

    }},
    data() {
        return {
        };
    },

    methods: {
      changeNum(val) {
        this.value += val; // 抛出错误
      }
    }
};
</script>
<style>
.input{
  display: flex;
}
</style>

意思就是不能直接修改

还可以用computed计算属性接收一下这个数据,重新赋值,然后就可以修改了

平时我们用得比较多的都只是这样的:

<template>
    <div class="input">
        <span>{{currentVal}}</span>
    </div>
</template>

<script>
export default {
    props: {
      value: {
        type: Number,
        default: 0

    }},
    data() {
        return {
        };
    },
    computed: {
      currentVal() {
        return this.value
      }
    },
    methods: {
    }
};
</script>
<style>
.input{
  display: flex;
}
</style>

直接使用就行,但是要利用computed进行修改就还需要加上computed的另一个属性set,上面默认是使用了get函数,即:

computed: {
      currentVal: {
        get() {
          return this.value
        }
      }
    }

加上set方法后就可以对其进行设置,并向上触发input事件:

<template>
    <div class="input">
        <button @click="changeNum(-1)">-</button>
        <span>{{currentVal}}</span>
        <button @click="changeNum(1)">+</button>
    </div>
</template>

<script>
export default {
    props: {
      value: {
        type: Number,
        default: 0

    }},
    data() {
        return {
        };
    },
    computed: {
      currentVal: {
        get() {
          return this.value
        },
        set(val) {
          this.$emit("input",val);
        }
      }
    },
    methods: {
      changeNum(val) {
        this.currentVal += val;
      }
    }
};
</script>
<style>
.input{
  display: flex;
}
</style>
发布了59 篇原创文章 · 获赞 29 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/dongguan_123/article/details/88934241