[Vue] how to encapsulate second time of ui components
how to encapsulate second time of ui components
For example we have follow code, with one UI component MyInput
// App.vue
<template>
<div>
<MyInput></MyInput>
</div>
</template>
<script setup>
import MyInput from './components/MyInput.vue'
</script>
// MyInput.vue
<template>
<di class="my-input">
<el-input></el-input>
</div>
</template>
<style scoped>
.my-input {
transition: 0.3s;
}
.my-input:hover,
.my-input:focus-within {
filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.45))
}
</style>
1. binding the attributes
For example, <MyInput v-model="data" placeholder="Address"></MyInput>
, input
has lots of attributes, therefore we don't want to add everything into props
;
In vue, we can use v-bind="$attrs"
// App.vue
<template>
<div>
<MyInput v-model="data" placeholder="Address"></MyInput>
</div>
</template>
<script setup>
import {ref} from "vue"
import MyInput from './components/MyInput.vue'
const data = ref("")
</script>
// MyInput.vue
<template>
<di class="my-input">
<el-input v-bind="$attrs"></el-input>
</div>
</template>
<script>
export default {}
</script>
<style scoped>
.my-input {
transition: 0.3s;
}
.my-input:hover,
.my-input:focus-within {
filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.45))
}
</style>
2. Slots
input
elements has many slots as well. We need to support slots as well in our component.
// App.vue
<template>
<div>
<MyInput>
<template #prepend>
<el-select placeholder="Select" style="width: 115px">
<el-option label="Restaurant" value="1" />
<el-option label="Order No." value="2" />
<el-option label="Tel" value="3" />
</el-select>
</template>
<template #append>
<el-button :icon="Search" />
</template>
</MyInput>
</div>
</template>
// MyInput.vue
<template>
<div class="my-input">
<el-input v-bind="$attrs">
<template v-for="(value, name) in $slots" #[name]="slotData">
<slot :name="name" v-bind="slotData || {}"></slot>
</template>
</el-input>
</div>
</template>
<script>
export default {
}
</script>
3. ref
From MyInput
, you might want to add a ref
which should be able to access the methods of input
element.
We can expose those mothods in MyInput
component.
// App.vue
<template>
<div>
<MyInput ref="inputRef" v-model="data" placeholder="Address">
<template #prepend>
<el-select placeholder="Select" style="width: 115px">
<el-option label="Restaurant" value="1" />
<el-option label="Order No." value="2" />
<el-option label="Tel" value="3" />
</el-select>
</template>
<template #append>
<el-button :icon="Search" />
</template>
</MyInput>
</div>
</template>
<script setup>
import {ref, onMounted} from "vue"
import MyInput from './components/MyInput.vue'
import {Search} from "@element-plus/icons-vue"
const data = ref("")
const inputRef = ref(null)
onMounted(() => {
console.log(inputRef.value)
inputRef.focus()
})
</script>
// MyInput.vue
<template>
<div class="my-input">
<el-input ref="inp" v-bind="$attrs">
<template v-for="(value, name) in $slots" #[name]="slotData">
<slot :name="name" v-bind="slotData || {}"></slot>
</template>
</el-input>
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$refs.inp)
const entries = Object.entries(this.$refs.inp)
for (const [key, value] of entries) {
this[key] = value
}
}
}
</script>
分类:
Vue
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2023-10-06 [Signal] 2- Cleanup subscriptions
2023-10-06 [OpenAI] Few short example
2022-10-06 [Typescript] 43. Medium - Percentage Parser
2021-10-06 [Angular] State provider solutions
2020-10-06 [Typescript] Function Overloads
2020-10-06 [Typescript] Function Generics
2020-10-06 [Typescript] Discriminated (Tagged) Unions