当前位置:蜗牛素材网>综合资讯>科技>正文

vue3创建一个自定义组件代码:Vue3,封装第三方组件一

人气:458 ℃/2024-01-20 06:58:20

各种UI库的功能都是非常强大的,尤其对于我这种不会 css 的人来说,就更是帮了大忙了。

只是嘛,如果再封装一下的话,那么用起来就会更方便了。

那么如何封装呢?

封装三要素 —— 属性、插槽、事件、方法

可以封装,但是原生UI库提供的强大功能不能给封装没了吧,吃了回扣可是不好滴。

那么如何做到不遗漏呢?先做一个合格的传声筒。

传递属性

先看看 el-input 提供的属性:

太长了,这里只截了一半。

这么多的属性,如果一个一个都弄到 props 里面,然后再一个一个绑定上去,这就太麻烦了。

我们可以分成两部分,重要的属性做到 props 里面,其他的可以放到 $attrs 里面。

定义一个简单的组件

模板

<template> <div> <el-input v-model="value" // 不能直接帮的属性 v-bind="$attrs" // 绑定其他属性。 > </el-input> </div></template>

代码

export default { name: 'test-text', inheritAttrs: false, props: { modelValue: [String, Number] }, setup(props, ctx) { const value = debounceRef(props, ctx.emit) return { value } }}

父组件的调用代码:

模板

<inputtext v-model="value" v-bind="attrs" > </inputtext>

代码

const value = ref('222')const attrs = reactive({ maxlength: 10, 'show-word-limit': true, clearable: true})

这里 modelValue 就是 props ,maxlength、show-word-limit、clearable 就变成了 $attrs 。

然后要看 el-input 是否是根元素,如果是跟元素的话,那么会自动绑定上,不需要我们手动写 v-bind="$attrs"。

如果像上面的例子不是根元素的话,需要手动写 v-bind="$attrs"。

inheritAttrs

这个是指定组件是否自动绑定 $attrs 。

默认是 true,会自动把 $attrs 绑定到根元素上面,不管根元素是啥。

这里设置为 false,那么$attrs 就不会自动绑定到 div 上面了。

插槽

这个稍微复杂一点,插槽本来就有一点绕,官网的介绍又比较含混。

我们可以找到 $slots 这个东东,但是官网的介绍(https://www.vue3js.cn/docs/zh/api/instance-properties.html#slots )却是 使用 h,这个就……

不过想要传递插槽,还是需要这个。

我们先看看 el-input 的插槽的使用。

<el-input placeholder="请输入内容" v-model="input3" class="input-with-select" > <template #prepend> <el-select v-model="select" placeholder="请选择"> <el-option label="餐厅名" value="1"></el-option> <el-option label="订单号" value="2"></el-option> <el-option label="用户电话" value="3"></el-option> </el-select> </template> <template #append> <el-button icon="el-icon-search"></el-button> </template> </el-input>

那么想要传递插槽的话,是不是可以这样?

<!--传递插槽--> <template v-slot:prepend> // 给递给el-input 的插槽 <slot name="prepend"></slot> // 接收父组件传递进来的插槽 </template>

测试可以。

那么总不会一个一个写吧,这也太麻烦了。如果能够for就好了。

等等, for?那么我们是不是可以这样。

<!--传递插槽--> <template v-for="(item, key, index) in $slots" :key="index" v-slot:[key] > <slot :name="key"></slot> </template>

测试可以。

完整代码

<el-input ref="refInput" v-model="value" v-bind="$attrs" > <!--传递插槽--> <template v-for="(item, key, index) in $slots" :key="index" v-slot:[key] > <slot :name="key"></slot> </template> </el-input> 传递事件

这个就简单了,啥都不用做,自动就传递出去了。el-input 是否是跟元素都可以。

测试一下:

<inputtext ref="refInput" v-model="value" v-bind="props" @clear="clear" @my-change="myChange" >

  • clear 是 el-input 提供的事件,外部可以直接得到这个事件,组件内部不用做操作。
  • my-change 是自定义的事件。
方法

一直都忽略了,还有方法这个事,因为基本没用过。

使用方法嘛,就需要使用 ref,这个词 ref 非彼 ref,说不清了,还是写代码吧。

直接使用的方法

直接使用UI库组件的方法,比如 el-input 的 提供的 select:

<el-input ref="refInput" // 注意这里的 ref v-model="value" v-bind="$attrs" ></el-input>

ref 的写法,不要加冒号。

const refInput = ref(null) // 先放一个nullonMounted(() => { // 然后在 onMounted 里面才能得到值。 console.log('refinput', refInput) // 看看啥样。 refInput.value.select() // 调用方法,文本框的内容会被选中})

先定义一个 ref,然后交给模板里的 ref,好像有点绕,这里必须使用 ref,reactive是不行滴。

在渲染后才能生效,也就是说必须在 onMounted 里面才能得到值,我们看看打印结果:(太长只能截取一部分)

很长吧。

父组件里面怎么用方法

<inputtext ref="refInput" v-model="value"></el-input>

// 测试方法const refInput = ref(null)onMounted(() => { console.log('refinput', refInput) // refInput.value.$refs.refInput.select() refInput.value.refInput.select()})

父组件里面的用法是一样的,只是需要再套一层,才能拿到自定义组件内部的UI库组件。

看看结构:

太长了,还在下面。

这个就比较近了。

话说为啥弄得这么多属性和方法事件呀?

父组件调用子组件内部的方法

上面那种方式,还可以让父组件调用子组件内部定义的方法,比如内部定义一个

const setInput = () => { value.value = new Date() }

父组件可以这样调用

refInput.value.setInput()总结

其实事件和方法,并没有封装,而是直接就可以使用的。

这是 element-plus 测试的结果,其他UI库没有测试。

插槽需要写一个 v-for 就可以实现传递,而且是通用的代码。

属性 就需要规划一下了,看设计要求,哪些放在 props里面,哪些放在attrs 里面。

搜索更多有关“vue3创建一个自定义组件代码:Vue3,封装第三方组件一”的信息 [百度搜索] [SoGou搜索] [头条搜索] [360搜索]
本网站部分内容、图文来自于网络,如有侵犯您的合法权益,请及时与我们联系,我们将第一时间安排核实及删除!
CopyRight © 2008-2024 蜗牛素材网 All Rights Reserved. 手机版