• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

【vue进阶之旅】如何自定义组件v-model,封装自己的组件库

武飞扬头像
juejin
帮助455

如何自定义组件v-model,我们首先要考虑的有2点:

一、在父组件中,如何直接使用v-model就可以和子组件进行双向绑定?

二、子组件改变,如何在父组件中获取到子组件的值?

今天我将使用的ViewUI进行二次封装一个名字为fdd-select(意为:方东东-选择器)的组件,所以今天我们封装一个叫fdd-select的选择器组件。

首先,我们新建一个名字为FddSelect的组件,想要在父组件中,直接使用v-model就可以和子组件进行双向绑定?在子组件中就不能再使用v-mode,子组件直接不能改变父组件传过来的数据,会报错,而是要使用:value="value"这种形式,如果你不是使用的value,而是其他命名如:value="city",则需要定义model,在model里面定义传过来的值。其次,当子组件改变,如何在父组件中获取到子组件的值,我们可以直接使用子传父,ViewUI的select的改变事件为on-change,我们直接使用它子传父即可。 image.png

image.png

image.png

子组件封装好了后,我们就可以在父组件中使用这个封装好的fdd-selec组件,我们写了一个延迟函数来模拟后端接口数据,把他从父组件通过v-model传给fdd-selec组件,子组件改变,会通过子传父selectChange再次传回父组件。

image.png

//父组件:

<template>
    <div>
<h1 style="margin-bottom:50px">自定义组件v-model</h1>

<fdd-select v-model="selectkey" @select-change="selectChange"></fdd-select>
<h3 style="margin-top:50px;margin-bottom: 50px;">在父组件获取子组件v-model的值:{{selectkey}}</h3>

    </div>
</template>

<script>
import FddSelect from "../../components/Common/FddSelect.vue";

export default {
  components: {
    FddSelect,
  },
  data() {
    return {
      selectkey: "",
    };
  },
  created() {
    this.getdata();
  },
  methods: {
    // 模拟后端异步获取数据
    getdata() {
      setTimeout(() => {
        this.selectkey = "London";
      }, 3000);
    },

    selectChange(e) {
      console.log("子组件改变时传给父组件的值", e);
      this.selectkey = e;
    },
  },
};
</script>

<style lang="scss" scoped>
</style>
//封装的select组件
<template>
    <div>
        <Select :value="value"   @on-change="selectChange"   style="width:200px">
        <Option v-for="item in cityList" :value="item.value"  :key="item.value">{{ item.label }}</Option>
    </Select>

    </div>
</template>

<script>
export default {
  model: {
    // prop: "city",   //如果props的字段不是value,而且其他字段,比如city,则需要定义model,不然父传子的值在selet上不会生效
    // event: "selectChange",
  },
  props: {
    value: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      cityList: [
        {
          value: "New York",
          label: "New York",
        },
        {
          value: "London",
          label: "London",
        },
        {
          value: "Sydney",
          label: "Sydney",
        },
        {
          value: "Ottawa",
          label: "Ottawa",
        },
        {
          value: "Paris",
          label: "Paris",
        },
        {
          value: "Canberra",
          label: "Canberra",
        },
      ],
    };
  },
  methods: {
    selectChange(e) {
        this.$emit("select-change", e);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>


2.如何封装一个组件?

其实当你实现了上面两个步骤,你就已经理解到封装组件的灵魂所在了,但是如何我们需要控制组件的下拉选项,是否禁用,提示语,怎么办呢?我们可以通过父传子的方法,在子组件里面进行定义,通过父组件传值就可以控制了。

image.png

image.png

fdd-select组件
<template>
    <div>
        <Select :value="value"  :placeholder="placeholder" :disabled="disabled"  @on-change="selectChange"  style="width:200px">
        <Option v-for="item in SeletOption" :value="item.value"  :key="item.value">{{ item.label }}</Option>
    </Select>

    </div>
</template>

<script>
export default {
  props: {
    value: {
      type: String,
      default: "",
    },
    SeletOption: {
      type: Array,
     default: []
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
    disabled: {
      type: Boolean,
      defalut: false,
    },
  },
  data() {
    return {};
  },
  methods: {
    selectChange(e) {
      this.$emit("select-change", e);
    },
  },
};
</script>

<style lang="scss" scoped>
</style>


当然,一个完整的组件属性并不止这些,比如要支持多选等等,大家可以去自己尝试,方式是类似的。

image.png

3.如何全局注册一个组件使用?

当组件封装完成之后,我们刚刚还是在局部注册使用的,这样的话,我们每次使用这个组件都要引入注册,而选择器这种组件一般都是比较常用的公共组件,每次都要引入,显得十分麻烦,所以我们需要在全局注册他,然后就可以在项目的任何组件使用了,无需再次引入注册。

//在main.js中全局注册

import FddSelect from '@/components/Common/FddSelect.vue'
Vue.component('fdd-select',FddSelect)

image.png

image.png

已上就是如何自定义组件v-model的全部内容,当大家封装的组件比较多和健壮的时候,就形成了属于自己的组件库,比如我自己的就可以起名为fdd-ui组件库

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanfbaci
系列文章
更多 icon
同类精品
更多 icon
继续加载