vue3.x + elementPlus 之 初步js文件处理,用于管理封装组件之单选多选封装篇

1.在components文件夹下面创建index.js

//在同一层级下面创建radio-check文件夹里面包括下面两个vue文件用于封装组件
import LZRadio from './radio-check/radio.vue' 
import LZCheckbox from './radio-check/checkbox.vue'

export default {
  install: (Vue) => {
    Vue.component('LZRadio', LZRadio)
    Vue.component('LZCheckbox', LZCheckbox)
  }
}

2.封装单选组件radio.vue

<template>
  <div>
    <el-radio-group v-if="!isRadioBtn" v-model="radioV" :class="!isRadioBtn?'el-radio-group-nobtn':''" @change="change">
      <el-radio v-for="(item, i) in radioList" :key="i" :label="item.label" :disabled="item.disabled">{{ item.title }}</el-radio>
    </el-radio-group>

    <el-radio-group v-model="radioV" :size="radioSize" class="radio-btn-all" @change="change">
      <el-radio-button v-for="(item, i) in radioList" :key="i" :label="item.label" :disabled="item.disabled">{{ item.title }}</el-radio-button>
    </el-radio-group>
  </div>
</template>
<script>
import { ref, reactive } from 'vue'
export default {
  name: 'RadioCheck',
  props: {
    // 点选列表
    radioList: {
      default() {
        return []
      },
      type: Array
    },
    radioSize: {
      default() {
        return 'small' // large / default /small
      },
      type: String
    },
    // 单选的默认值
    radio: {
      default() {
        return '1'
      },
      type: String
    },
    // 是否以按钮的形式展示
    isRadioBtn: {
      default() {
        return false
      },
      type: Boolean
    }
  },
  emits: ['change'],
  setup(props, ctx) {
    const radioV = ref(1)
    // const radioSize = props.radioSize
    const init = () => {
      props.radioList.forEach((e) => {
        if (e.label === props.radio) {
          radioV.value = e.label
        }
      })
    }
    init()
    const change = (label) => {
      ctx.emit('change', label)
    }
    return { radioV, change }
  }

}
</script>
<style lang="scss" scope>
.el-radio__inner {
  border-radius: 50%;
}
.el-radio__input.is-checked .el-radio__inner {
  border-radius: 50%;
}
/* // radio选中改为勾勾 */
.el-radio__input.is-checked .el-radio__inner::after {
  content: "";
  width: 6px;
  height: 6px;
  position: absolute;
  top: 6px;
  left: 6px;
  vertical-align: middle;
  /* -webkit-transform: rotate(-45deg); */
  /* transform: rotate(-45deg); */
  border-radius: 50%;
  background: #fff;
}
.radio-btn-all{
  background: #fff !important;
}
</style>

3.封装多选选组件checkbox.vue

<template>
  <div class="flex">
    <el-checkbox v-model="checkData.checkAll" class="check-all" :indeterminate="checkData.isIndeterminate" @change="handleCheckAllChange">全选</el-checkbox>
    <el-checkbox-group v-model="checkData.checkedCities" @change="handleCheckedCitiesChange">
      <el-checkbox v-for="(item,j) in checkData.listAll" :key="j" :disabled="item.disabled" :label="item.title">{{ item.title }}</el-checkbox>
    </el-checkbox-group>
  </div>
</template>

<script>
import { ref, reactive } from 'vue'
const checkData = reactive({
  checkAll: false,
  checkedCities: [],
  listAll: [],
  isIndeterminate: true
})
// 全选
const checkallEffect = (ctx) => {
  const handleCheckAllChange = (val) => {
    let arr = []
    let all = []
    if (val) {
      all = checkData.listAll
      checkData.listAll.forEach((e) => {
        arr.push(e.title)
      })
    } else {
      arr = []
      all = []
    }
    checkData.checkedCities = arr
    checkData.isIndeterminate = false
    ctx.emit('checkBoxAll', all)
  }
  return { handleCheckAllChange }
}
// 多选的数据回调
const checkEffect = (ctx) => {
  const handleCheckedCitiesChange = (value) => {
    // console.log(value);
    const checkedCount = value.length
    checkData.checkAll = checkedCount === checkData.listAll.length
    checkData.isIndeterminate = checkedCount > 0 && checkedCount < checkData.listAll.length
    const arr = []
    for (let i = 0; i < checkData.listAll.length; i++) {
      const e = checkData.listAll[i]
      for (let j = 0; j < value.length; j++) {
        const ele = value[j]
        if (e.title === ele) {
          arr.push(e)
        }
      }
    }
    ctx.emit('checkBoxChange', arr)
  }
  return { handleCheckedCitiesChange }
}
export default {
  props: {
    // 多选数据
    checkList: {
      default() {
        return []
      },
      type: Array
    },
    // 多选的默认展示
    checkedDefList: {
      default() {
        return []
      },
      type: Array
    }
  },
  emits: ['checkBoxAll', 'checkBoxChange'],
  setup(props, ctx) {
    checkData.listAll = props.checkList.slice()
    checkData.checkedCities = props.checkedDefList.slice()
    const { handleCheckAllChange } = checkallEffect(ctx)
    const { handleCheckedCitiesChange } = checkEffect(ctx)
    return { checkData, handleCheckAllChange, handleCheckedCitiesChange }
  }
}
</script>
<style lang="scss">
.check-all {
  margin-right: 15px !important;
}
</style>

4.使用方式

<template>
  <div>
    <LZRadio
      :radio-list="radioData.radioList"
      :radio="radioData.radio"
      class="check-box"
      @change="change"
    ></LZRadio>
    <LZRadio
      :radio-list="radioData.radioList"
      :radio="radioData.radio"
      :is-radio-btn="true"
      :radio-size="radioData.radioSize"
      class="check-box"
      @change="change"
    ></LZRadio>

    <LZCheckbox
      :check-list="checkData.checkList"
      :checked-def-list="checkData.checkedDefList"
      class="check-box"
      @checkBoxAll="checkBoxAll"
      @checkBoxChange="checkBoxChange"
    ></LZCheckbox>
  </div>
</template>

<script>
import { reactive, toRefs, ref, onMounted, toRef } from 'vue'
const radioData = reactive({
//   isRadioBtn: ref(true), // 是否是按钮形式
  radioSize: 'small', // medium mini 按钮大小
  radioList: [
    {
      title: '选项1',
      label: '1',
      disabled: false
    },
    {
      title: '选项2',
      label: '2',
      disabled: false
    },
    {
      title: '选项3',
      label: '3',
      disabled: false
    },
    {
      title: '选项4',
      label: '4',
      disabled: false
    },
    {
      title: '选项5',
      label: '5',
      disabled: false
    }
  ],
  radio: ref('1') // 默认选中第几个
})
const checkData = reactive({
// 全部选择的数据
  checkList: [
    {
      title: '上海',
      id: 1
    },
    {
      title: '北京',
      id: 2
    },
    {
      title: '广州',
      id: 3
    }
  ],
  checkedDefList: ['上海', '北京'] // 默认勾选的数据  这里的数据要用title对应上
})
export default {
  name: 'EleRadio',
  setup() {
    // 单选回调  返回值是对应的label
    const change = (label) => {
      console.log(label)
    }
    // 多选单选的回调
    const checkBoxChange = (arr) => {
      console.log(arr)
    }
    // 全选回调
    const checkBoxAll = (arr) => {
      console.log(arr)
    }
    return { change, radioData, checkData, checkBoxChange, checkBoxAll }
  }
}
</script>
<style lang="scss" scope>
.check-box {
  margin: 20px;
}
</style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值