vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue自定义组件v-model

vue如何自定义组件v-model

作者:不努力code

这篇文章主要介绍了vue如何自定义组件v-model问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

vue自定义组件v-model

官网的话

允许一个自定义组件在使用 v-model 时定制 prop 和 event。

默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。

使用 model 选项可以回避这些情况产生的冲突。

效果

父组件:

<template>
  <view class="index">
      我是父级组件{{msg}}
      <!-- 相当于:  <node :value="msg" @input="v=>msg=v"></node>-->
      <node v-model="msg"></node>
  </view>
</template>
<script lang="ts">
import Vue from "vue";
import node from"./node.vue"
export default Vue.extend({
  components:{
    node
  },
  data() {
    return {
      msg:"abc",
    };
  },
  mounted() {
    // uni.navigateTo({
    //   url: "/pages/login/login",
    // });
  },
});
</script>
<style scoped>
.index{
  border: solid 1px orange;
}
</style>

 子组件

<template>
  <view class="node">
    <text>我是子级组件</text>
    <el-input v-model="result" placeholder="请输入内容"></el-input>
  </view>
</template>
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
  props: {
    value: {
      type: [String, Number],
    },
  },
  data() {
    return {};
  },
  computed: {
    result: {
      get(): string | number {
        return this.value;
      },
      set(v: string | number) {
        console.log("我执行了");
        this.$emit("input", v);
      },
    },
  },
});
</script>
<style scoped>
.node {
  margin: 50px 0;
  width: 500px;
  border: solid black 2px;
}
</style>

如果要想自定义value的名字和事件名,修改一下字组件即可,如:

<template>
  <view class="node">
    <text>我是子级组件</text>
    <el-input v-model="result" placeholder="请输入内容"></el-input>
  </view>
</template>
<script lang="ts">
import Vue from "vue";
export default Vue.extend({
    model: {
    prop: 'modelValue',
    event: 'change'
  },
  props: {
    modelValue: {
      type: [String, Number],
    },
  },
  data() {
    return {};
  },
  computed: {
    result: {
      get(): string | number {
        return this.modelValue;
      },
      set(v: string | number) {
        console.log("我执行了");
        this.$emit("change", v);
      },
    },
  },
});
</script>
<style scoped>
.node {
  margin: 50px 0;
  width: 500px;
  border: solid black 2px;
}
</style>

vue2与vue3在自定义组件v-model上的区别

在vue开发中,通常会对一个自定义的组件进行封装,并实现v-model双向绑定功能

在 Vue 2 中,通常这样实现

父组件

<template>
  <Child v-model="number"></Child>    
</template>
<script>
  export default {
    data() {
      return {
        number: 0
      }
    },
    components: {
      Child: () => import("./Child.vue")
    }
  }
</script>

子组件

<template>
  <button @click="handleClick">{{ value }}</button>
</template>
<script>
  export default {
    props: {
      value: Number
    },
    methods: {
      handleClick() {
        // 通过emit一个input事件出去,实现 v-model
        this.$emit('input', this.value + 1)
      }
    }
  }
</script>

在 vue 3 中,通过这样实现

父组件

<template>
  <Child v-model="number"></Child>    
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
  setup() {
    const number = ref(0);
    return {
      number
    };
  },
});
</script>

子组件

<template>
  <button @click="handleClick">{{ value }}</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
  props: {
    // 更换成了 modelValue
    modelValue: Number
  },
  setup(props, { emit }) {
    // 关闭弹出层
    const handleClick = () => emit('update:modelValue', props.modelValue + 1);
    return { handleClick };
  },
});
</script>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文