前端框架之封装Vue第三方组件三个技巧

 更新时间:2022年07月11日 16:03:14   作者:红尘炼心  
这篇文章主要为大家介绍了前端框架封装Vue第三方组件的三个技巧示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

在封装第三方组件中,经常会遇到一个问题,如何通过封装的组件去使用第三方组件的Attributes(属性)、Events(自定义事件)、Methods(方法)、Slots(插槽)。

当然这个问题并不是难以解决,用普通方法解决难免陷入繁琐重复的工作中,而且封装的组件代码可读性也不高。

本专栏将介绍三种技巧来使用第三方组件的Attributes(属性)、Events(自定义事件)、Slots(插槽),至于使用第三方组件的Methods(方法)的技巧还待优化。

一、使用第三方组件的属性

封装一个elementUI的el-input输入框组件称为myInput,若要在myInput组件上添加一个disabled属性来禁用输入框,要如何实现呢?一般同学会这么做

//myInput.vue
<template>
  <div>
    <el-input v-model="inputVal" :disabled="disabled"></el-input>
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: String,
      default: '',
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    inputVal: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      }
    }
  }
}
</script>

过一段时间后又要在myInput组件上添加el-input组件的其它属性,el-input组件总共有27个多属性,那该怎么呢,难道一个个用prop传进去,这样不仅繁琐而且可读性差,可以用$attrs一步到位,先来看一下attrs的官方定义。

$attrs: 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件

//myInput.vue
<template>
  <div>
    <el-input v-model="input" v-bind="$attrs"></el-input>
  </div>
</template>

这还不够,还得把inheritAttrs选项设置为false,为什么呢,来看一下inheritAttrs选项的官方定义就明白了。

默认情况下父作用域的不被认作 props 的 attribute 绑定 (attribute bindings) 将会“回退”且作为普通的 HTML attribute 应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。

通过设置 inheritAttrsfalse,这些默认行为将会被去掉。而通过 $attrs 可以让这些 attribute 生效,且可以通过 v-bind 显性的绑定到非根元素上。注意:这个选项不影响 class 和 style 绑定。

简单来说,把inheritAttrs设置为false,避免给myInput组件设置的属性被添加到myInput组件的根元素div上。

//myInput.vue
<template>
  <div>
    <el-input v-model="input" v-bind="$attrs"></el-input>
  </div>
</template>
<script>
export default {
  inheritAttrs: false,
  props: {
    value: {
      type: String,
      default: '',
    },
  },
  computed: {
    inputVal: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      }
    }
  }
}
</script>

这样设置后,在myInput组件上就可以直接使用el-input组件的属性,不管后续el-input组件再增加了多少个属性。

二、使用第三方组件的自定义事件

若在myIpput组件上使用el-input组件上自定义的事件呢,可能你的第一反应是this.$emit

//myInput.vue
<template>
  <div>
    <el-input v-model="input" v-bind="$attrs" @blur="blur"></el-input>
  </div>
</template>
<script>
export default {
  inheritAttrs: false,
  props: {
    value: {
      type: String,
      default: '',
    },
  },
  computed: {
    inputVal: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      }
    }
  },
  methods: {
    blur() {
      this.$emit('blur')
    }
  }
}
</script>
<myInput v-model="value" @blur="handleBlur"></myInput>

el-input组件有4个自定义事件,还不算多,假如遇到自定义事件更多的第三方组件,要怎么办,难道一个一个添加进去,这样会增加一堆非必要的methods,其实可以用$listeners一步到位,先来看一下$listeners的官方定义。

$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件。

//myInput.vue
<template>
  <div>
    <el-input v-model="input" v-bind="$attrs" v-on="$listeners"></el-input>
  </div>
</template>

那么在myInput组件中给el-input组件添加上v-on="$listeners",就可以在myInput组件上使用el-input组件自定义的事件。

三、使用第三方组件的插槽

若在myIpput组件上使用el-input组件上定义的插槽呢?这个没有多少取巧的方法,第三方组件定义多少个插槽,在封装的时候都得用slot标签暴露出去。比如暴露el-input组件中的prefix插槽,代码如下所示:

//myInput.vue
<template>
  <div>
    <el-input v-model="input" v-bind="$attrs" @blur="blur">
      <template #prepend>
        <slot name="prepend"></slot>
      </template>
    </el-input>
  </div>
</template>

四、使用第三方组件的方法

利用ref来实现,首先在myInput组件中的el-input组件上添加一个ref="elInput"属性,

//myInput.vue
<template>
  <div>
    <el-input ref="elInput></el-input>
  </div>
</template>
<script>
export default {
  mounted(){
     this.elInput = this.$refs.elInput;
  }
}
</script>

这里要注意父子组件的mounted的执行时机,因为一般el-input组件是全局引入的,相当同步引入组件,此时el-input组件的mounted会比myInput组件的mounted先执行,所以可以在myInput组件的mounted中把this.$refs.elInput赋值到myInput组件的this的一个属性上。

myInput组件如何使用el-input组件的方法分两种情况,跟myInput组件的引入有关系。

假如myInput组件是同步引入的

<template>
  <div>
    <myInput ref="myInput"></myInput>
  </div>
</template>
<script>
import myInput from './myInput.vue';
export default {
  data() {
    return {
    }
  },
  components: {
    myInput,
  },
  mounted() {
    //调用el-input组件的focus方法
    this.$refs.myInput.elInput.focus();
  }
}
</script>

假如myInput组件是异步引入的

<template>
  <div>
    <myInput ref="myInput"></myInput>
  </div>
</template>
<script>
export default {
  data() {
    return {
    }
  },
  components: {
    myInput: () => import('./myInput.vue')
  },
  mounted() {
    //调用el-input组件的focus方法
    setTimeout(() => {
       this.$refs.myInput.elInput.focus();
    })
  }
}
</script>

以上就是前端框架封装Vue第三方组件三个技巧的详细内容,更多关于封装Vue第三方组件的资料请关注脚本之家其它相关文章!

相关文章

  • vue前端开发层次嵌套组件的通信详解

    vue前端开发层次嵌套组件的通信详解

    vue通过provide & inject两个关键字完成父组件向子孙组件直接传值,很像子类能够使用父类的属性一样方便。provide & inject一般用于多层之间的传值,两层之间还是使用props进行
    2021-10-10
  • 浅谈vue中computed属性对data属性赋值为undefined的原因

    浅谈vue中computed属性对data属性赋值为undefined的原因

    本文主要介绍了浅谈vue中computed属性对data属性赋值为undefined的原因,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Vue生产和开发环境如何切换及过滤器的使用

    Vue生产和开发环境如何切换及过滤器的使用

    本文主要介绍了Vue生产、开发环境如何切换及过滤器的使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • vue整合百度地图显示指定地点信息

    vue整合百度地图显示指定地点信息

    本文主要介绍了vue整合百度地图显示指定地点信息,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • vue下拉列表的两种实现方式比较

    vue下拉列表的两种实现方式比较

    这篇文章主要介绍了vue下拉列表的两种实现方式比较,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Vue Element UI自定义描述列表组件

    Vue Element UI自定义描述列表组件

    这篇文章主要为大家详细介绍了Vue Element UI自定义描述列表组件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • vue打包后显示空白正确处理方法

    vue打包后显示空白正确处理方法

    很多朋友遇到这样的问题当vue打包后显示空白问题,遇到这样的问题怎么处理呢?下面脚本之家小编给大家分享下vue打包后显示空白正确处理方法,感兴趣的朋友一起看看吧
    2017-11-11
  • Vue3 响应式高阶用法之triggerRef()的使用

    Vue3 响应式高阶用法之triggerRef()的使用

    在Vue3响应式系统中,shallowRef仅追踪顶层属性的变化,当需要对内层属性作出反应时,可使用triggerRef()方法手动触发更新,本文介绍了triggerRef()的应用场景、基本用法、功能和最佳实践,感兴趣的可以了解一下
    2024-09-09
  • Vue虚拟Dom到真实Dom的转换

    Vue虚拟Dom到真实Dom的转换

    本文主要介绍了Vue虚拟Dom到真实Dom的转换,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2021-07-07
  • vue2左侧菜单栏收缩展开功能实现

    vue2左侧菜单栏收缩展开功能实现

    vue2左侧菜单栏收缩展开目前是非常常见的,我们在日常开发过程中经常会碰到,这篇文章给大家介绍vue2左侧菜单栏收缩展开功能,感兴趣的朋友跟随小编一起看看吧
    2024-04-04

最新评论