vue如何自定义组件v-model

 更新时间:2023年07月27日 09:23:37   作者:不努力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>

总结

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

相关文章

  • 关于IDEA中的.VUE文件报错 Export declarations are not supported by current JavaScript version

    关于IDEA中的.VUE文件报错 Export declarations are not supported by cu

    这篇文章主要介绍了关于IDEA中的.VUE文件报错 Export declarations are not supported by current JavaScript version的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • vue实例中data使用return包裹的方法

    vue实例中data使用return包裹的方法

    今天小编就为大家分享一篇vue实例中data使用return包裹的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • Vue中常见的几种传参方式小结

    Vue中常见的几种传参方式小结

    Vue组件的使用不管是在平常工作还是在面试面试中,都是频繁出现的,下面这篇文章主要给大家介绍了关于Vue中常见的几种传参方式的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • Vue.js组件高级特性实例详解

    Vue.js组件高级特性实例详解

    这篇文章主要介绍了Vue.js组件高级特性,结合实例形式详细分析了vue.js组件递归、模板、动态加载、渲染等相关操作技巧,需要的朋友可以参考下
    2018-12-12
  • 一文搞懂vue编译器(DSL)原理

    一文搞懂vue编译器(DSL)原理

    本文主要介绍了一文搞懂vue编译器(DSL)原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • vue-router如何实现history模式配置

    vue-router如何实现history模式配置

    这篇文章主要介绍了vue-router如何实现history模式配置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • vue中实现全屏以及对退出全屏的监听

    vue中实现全屏以及对退出全屏的监听

    本文主要介绍了vue中实现全屏以及对退出全屏的监听,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • vue手写<RouterLink/>组件实现demo详解

    vue手写<RouterLink/>组件实现demo详解

    这篇文章主要为大家介绍了vue手写<RouterLink/>组件实现demo详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Vue.js标签页组件使用方法详解

    Vue.js标签页组件使用方法详解

    这篇文章主要为大家详细介绍了Vue.js标签页组件的使用方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一
    2019-10-10
  • Vue Element前端应用开发之树列表组件

    Vue Element前端应用开发之树列表组件

    本篇随笔主要介绍树列表组件和下拉列表树组件在项目中的使用,以及一个SplitPanel的组件。
    2021-05-05

最新评论