资讯专栏INFORMATION COLUMN

在前端框架中封装Vue第三方组件的三个小技巧

3403771864 / 501人阅读

  这篇就是带大家一起学习下在封装第三方组件中,通过封装的组件去使用第三方组件的Attributes(属性)、Events(自定义事件)、Methods(方法)、Slots(插槽)以及优化技巧。

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

1.jpg

  封装一个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>

  现在有一个bug就是在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 应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。

  通过设置inheritAttrs为false,这些默认行为将会被去掉。而通过$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组件再增加了多少个属性。

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

2.jpg

  若在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个自定义事件,这是小tips,要是遇到更多的会怎么样那?一个字“难”,这样会增加一堆非必要的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组件自定义的事件。

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

3.jpg

  若在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>

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

4.jpg

  利用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第三方组件三个技巧的详细内容已说完,希望大家都好好学习实践。


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/128232.html

相关文章

  • 关于Vue2一些值得推荐文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    sutaking 评论0 收藏0
  • 关于Vue2一些值得推荐文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    khs1994 评论0 收藏0
  • 个人分享--web前端学习资源分享

    摘要:前言月份开始出没社区,现在差不多月了,按照工作的说法,就是差不多过了三个月的试用期,准备转正了一般来说,差不多到了转正的时候,会进行总结或者分享会议那么今天我就把看过的一些学习资源主要是博客,博文推荐分享给大家。 1.前言 6月份开始出没社区,现在差不多9月了,按照工作的说法,就是差不多过了三个月的试用期,准备转正了!一般来说,差不多到了转正的时候,会进行总结或者分享会议!那么今天我就...

    sherlock221 评论0 收藏0

发表评论

0条评论

3403771864

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<