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>