本次對
el-input
進(jìn)行簡單封裝進(jìn)行演示
- 封裝很簡單,就給激活樣式的邊框(主要是功能)
本次封裝主要使用到vue自帶的幾個對象
- $attrs:獲取綁定在組件上的所有屬性
- $listeners: 獲取綁定在組件上的所有函數(shù)方法
- $slots: 獲取應(yīng)用在組件內(nèi)的所有插槽
1、屬性傳遞
element 的input組件有很多屬性,
- 想要實現(xiàn)在封裝好后的組件上使用
el-input
組件的屬性,會直接傳遞到el-input
組件上,包括v-model
。- 在組件中,可以使用
this.$attrs
獲取所有綁定在組件上的屬性(不包括方法)- 這樣,我們就可以在封裝的組件內(nèi),使用
v-bind="$attrs"
,直接把屬性傳遞到內(nèi)部組件上。- 在下列案例中,由于
v-model
是:value 和 @input
兩個組合的語法糖,$attrs
只能獲取屬性,所以只能傳遞:value
屬性
1.1、父組件
<template>
<div class="wrapper">
<my-input v-model="val">
</my-input>
</div>
</template>
<script>
import MyInput from '@/components/MyInput'
export default {
components: {
MyInput,
},
data() {
return {
val: '111',
}
},
methods: {
inputChange(val){
console.log(val);
}
}
}
</script>
<style lang="scss" scoped>
.wrapper {
padding: 10vh;
}
</style>
1.2、子組件
<template>
<el-input v-bind="$attrs"></el-input>
</template>
<script>
export default {
created() {
console.log("attrs:",this.$attrs);
}
}
</script>
<style lang="scss" scoped>
::v-deep {
.el-input__inner:focus {
border-color: red;
}
}
</style>
1.3、效果
- 這時候給輸入框輸入值是無效的,因為目前只能把
value
屬性綁定到el-input
上,并沒有把input
函數(shù)綁定上去,所以不能修改父組件傳過來的value
的值。
2、方法傳遞
element的組件,也有很多方法,比如:change等函數(shù)
- 想要實現(xiàn)在封裝好后的組件上使用
el-input
組件的方法,會直接傳遞到el-input
組件上。- 在組件中,可以使用
this.$listeners
獲取所有綁定在組件上的屬性(不包括屬性)- 這樣,我們就可以在封裝的組件內(nèi),使用
v-on="$listeners"
,直接把方法傳遞到內(nèi)部組件上。- 在下列案例中,由于
v-model
是:value 和 @input
兩個組合的語法糖,$listeners
只能獲取屬性,所以結(jié)合上面$attrs
jiu可以完整的實現(xiàn)v-model
的效果了
2.1、父組件
<template>
<div class="wrapper">
<my-input v-model="val" @change="inputChange">
</my-input>
</div>
</template>
<script>
import MyInput from '@/components/MyInput'
export default {
components: {
MyInput,
},
data() {
return {
val: '111',
}
},
methods: {
inputChange(val){
console.log("inputChange:", val);
}
}
}
</script>
2.2、子組件
<template>
<el-input v-bind="$attrs" v-on="$listeners"></el-input>
</template>
<script>
export default {
created() {
console.log("attrs:",this.$attrs);
console.log("listeners:",this.$listeners);
}
}
</script>
<style lang="scss" scoped>
::v-deep {
.el-input__inner:focus {
border-color: red;
}
}
</style>
2.3、效果
這時候搭配
$attrs
就可以實現(xiàn)v-model
的完整效果了,以及@change
函數(shù)也會傳遞過去
3、插槽傳遞
element的組件,也包括了很多的插槽文章來源:http://www.zghlxwxcb.cn/news/detail-629824.html
- 想要給封裝好后的組件,使用的插槽,傳遞到
el-input
中- 在組件中,可以使用
this.$slots
獲取所有綁定在組件上的插槽- 這樣,我們就可以在封裝的組件內(nèi),使用
v-for="(val, key) in $slots"
,所有插槽,遍歷放到組件中,當(dāng)作組件的插槽- 注意插槽傳參也要處理(我這里沒處理)
3.1、父組件
<template>
<div class="wrapper">
<my-input v-model="val" @change="inputChange">
<template slot="prepend">Http://</template>
<el-button slot="append" icon="el-icon-search"></el-button>
</my-input>
</div>
</template>
<script>
import MyInput from '@/components/MyInput'
export default {
components: {
MyInput,
},
data() {
return {
val: '111',
}
},
methods: {
inputChange(val){
console.log("inputChange:", val);
}
}
}
</script>
<style lang="scss" scoped>
.wrapper {
padding: 10vh;
}
</style>
3.2、子組件
<template>
<el-input v-bind="$attrs" v-on="$listeners">
<template v-for="(val, key) in $slots">
<slot :name="key"></slot>
</template>
</el-input>
</template>
<script>
export default {
created() {
console.log("attrs:",this.$attrs);
console.log("listeners:",this.$listeners);
console.log("slots",this.$slots);
}
}
</script>
<style lang="scss" scoped>
::v-deep {
.el-input__inner:focus {
border-color: red;
}
}
</style>
3.3、效果
文章來源地址http://www.zghlxwxcb.cn/news/detail-629824.html
4、ref偽傳遞(適用于vue3)
- 為什么說偽傳遞呢,因為在vue中,根本就拿不到外層組件的
ref
屬性,所以只能另換思路- 你要用ref,無非就是想調(diào)用組件里面的函數(shù)。那我封裝的組件里面,可以把被封裝的組件的函數(shù),直接提取出來,當(dāng)作我封裝組件的函數(shù)即可實現(xiàn)
- 適用于Vue3,vue2會卡死
4.1、父組件
<template>
<div class="wrapper">
<my-input ref="muInput" v-model="val" @change="inputChange">
<template slot="prepend">Http://</template>
<el-button slot="append" icon="el-icon-search"></el-button>
</my-input>
</div>
</template>
<script>
import MyInput from '@/components/MyInput'
export default {
components: {
MyInput,
},
data() {
return {
val: '111',
}
},
mounted() {
this.$refs.muInput.focus()
},
methods: {
inputChange(val){
console.log("inputChange:", val);
}
}
}
</script>
<style lang="scss" scoped>
.wrapper {
padding: 10vh;
}
</style>
4.2、子組件
<template>
<el-input ref="input" v-bind="$attrs" v-on="$listeners">
<template v-for="(val, key) in $slots" #[key]>
<slot :name="key"></slot>
</template>
</el-input>
</template>
<script>
export default {
mounted() {
console.log("attrs:",this.$attrs);
console.log("listeners:",this.$listeners);
console.log("slots",this.$slots);
for (const [key, value] of Object.entries(this.$refs.input)) {
this[key] = value
}
}
}
</script>
<style lang="scss" scoped>
::v-deep {
.el-input__inner:focus {
border-color: red;
}
}
</style>
5、插槽傳遞補(bǔ)充22
- $slots可以獲取所有應(yīng)用在子組件上的插槽。但是僅限于子組件不使用插槽進(jìn)行傳參(作用域插槽)只能捕獲到具名插槽。
- 當(dāng)需要使用作用域插槽時,就會發(fā)現(xiàn),
$solts
捕獲不到這個插槽了。- 這時候,就需要使用
$scopedSlots
,它就等于具名插槽 + 作用域插槽,捕獲的更加全面。- 上面我們只是使用
$slots
傳遞具名插槽,如果插槽需要傳參,則無法使用,我們要換成更加全面的$scopedSlots
5.1、子組件
<template>
<el-input v-bind="$attrs" v-on="$listeners">
<template v-for="(val, key) in $scopedSlots" :scope="scope">
<slot :name="key" :data="scope"></slot>
</template>
</el-input>
</template>
<script>
export default {
created() {
console.log("attrs:",this.$attrs);
console.log("listeners:",this.$listeners);
console.log("slots",this.$slots);
console.log("scopedSlots",this.$scopedSlots);
}
}
</script>
<style lang="scss" scoped>
::v-deep {
.el-input__inner:focus {
border-color: red;
}
}
</style>
到了這里,關(guān)于Vue-組件二次封裝的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!