基于vue3+ts实现二次封装element-ui的el-select下拉选项框和el-radio-group单选框

1. 项目安装element3版本组件库和lodash-es工具库

# NPM
$ npm install element-plus --save
 
# Yarn
$ yarn add element-plus
 
# pnpm
$ pnpm install element-plus

#安装lodash-es工具库
$ npm install lodash-es --save

2.根据文档中的方法引入main.ts

// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
 
const app = createApp(App)
 
app.use(ElementPlus)
app.mount('#app')

3. 在公共工具包中创建dict.ts文件来定义可使用的工具对象库

dict.ts内容举例:


export const delState = { 1: '正常', 0: '异常' }

export const state = { 1: '是', 0: '否' }

export const gender = { 1: '男', 2: '女' }

export const stateunit = { 0: '冻结', 1: '正常', 2: '到期' }

export const fundDirect = { 1: '收入', 2: '支出',}

4. 在公共组件中创建SelectDict文件中创建index.vue 进行封装下拉框组件完整代码

<script setup lang="ts">
import { merge } from 'lodash-es'
import { useDisabled } from 'element-plus'
import * as _DICT from '@/utils/dict'

const props = withDefaults(
  defineProps<{
    type?: 'select' | 'radio'
    name: string
    all?: boolean
    border?: boolean
    dict?: any
    disabled?: boolean
    button?: boolean
  }>(),
  {
    all: false,
    type: 'select',
    border: true,
    button: false,
    dict: {},
  },
)

const dict = computed(() => {
  const DICT: Record<string, any> = _DICT
  if (DICT[props.name]) return merge(DICT[props.name], props.dict)

  console.warn(`找不到字典 ${props.name}`)
})

const disabled = useDisabled(props.disabled)
</script>

<template>
  <!-- select -->
  <el-select v-if="props.type === 'select'" :disabled="disabled" class="w-full" v-bind="$attrs" placeholder="请选择">
    <el-option v-if="props.all" label="全部" :value="-1" />
    <el-option v-for="(label, value) in dict" :key="value" :label="label" :value="+value" />
  </el-select>
</template>

5.进一步封装el-radio-group单选框完整代码是将组件变的公用更加灵活,同时兼容下拉框和单选框

<script setup lang="ts">
import { merge } from 'lodash-es'
import { useDisabled } from 'element-plus'
import * as _DICT from '@/utils/dict'

const props = withDefaults(
  defineProps<{
    type?: 'select' | 'radio'
    name: string
    all?: boolean
    border?: boolean
    dict?: any
    disabled?: boolean
    button?: boolean
  }>(),
  {
    all: false,
    type: 'select',
    border: true,
    button: false,
    dict: {},
  },
)

const dict = computed(() => {
  const DICT: Record<string, any> = _DICT
  if (DICT[props.name]) return merge(DICT[props.name], props.dict)

  console.warn(`找不到字典 ${props.name}`)
})

const disabled = useDisabled(props.disabled)
</script>

<template>
  <!-- select -->
  <el-select v-if="props.type === 'select'" :disabled="disabled" class="w-full" v-bind="$attrs" placeholder="请选择">
    <el-option v-if="props.all" label="全部" :value="-1" />
    <el-option v-for="(label, value) in dict" :key="value" :label="label" :value="+value" />
  </el-select>

  <!-- radio -->
  <el-radio-group v-if="props.type === 'radio'" :disabled="disabled" v-bind="$attrs">
    <template v-if="props.button">
      <el-radio-button v-for="(text, label) in dict" :key="label">
        {{ text }}
      </el-radio-button>
    </template>

    <div v-else class="space-x-3 flex">
      <div v-for="(text, label) in dict" :key="label" class="flex">
        <el-radio :label="+label" :border="props.border">
          {{ text }}
        </el-radio>
      </div>
    </div>
  </el-radio-group>
</template>

使用步骤

<script setup>

import SelectDict from '@/components/SelectDict/index.vue'

const ordState = ref(-1)
const state = ref(1)


</script>

<template>
  <SelectDict v-model="ordState" name="ordState" all />

  <SelectDict v-model="state" name="stateunit" type="radio" :border="false" />

</template>

效果:

 

  • 18
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以为你提供一个基本的ElDialog封装,供你参考: ```vue <template> <el-dialog :title="title" :visible.sync="dialogVisible" :before-close="handleClose" :close-on-click-modal="false" :custom-class="customClass" :width="width" :lock-scroll="lockScroll" :modal-append-to-body="modalAppendToBody" :destroy-on-close="destroyOnClose" :center="center" @opened="handleOpen" @closed="handleClosed" v-bind="$attrs" v-on="$listeners" > <slot></slot> </el-dialog> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { ElDialog } from 'element-plus'; export default defineComponent({ name: 'MyDialog', props: { title: { type: String, default: '', }, dialogVisible: { type: Boolean, default: false, }, customClass: { type: String, default: '', }, width: { type: String, default: '50%', }, lockScroll: { type: Boolean, default: true, }, modalAppendToBody: { type: Boolean, default: true, }, destroyOnClose: { type: Boolean, default: false, }, center: { type: Boolean, default: true, }, }, emits: ['update:dialogVisible', 'opened', 'closed'], methods: { handleClose(done: () => void) { // 自定义关闭操作 done(); }, handleOpen() { this.$emit('opened'); }, handleClosed() { this.$emit('closed'); }, }, components: { ElDialog, }, }); </script> ``` 这里我们使用了Vue3的Composition API,使用`defineComponent`定义了一个组件,并引入了Element Plus的ElDialog组件。 我们将ElDialog组件的属性和事件通过props和emits暴露出来,并在组件内部进行了一些自定义操作,如自定义关闭操作和自定义事件触发。 你可以根据自己的需求对组件进行进一步封装和定制化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值