赞
踩
一、先下载引入element-plus
//直接冲官网指南
https://element-plus.gitee.io/zh-CN/guide/installation.html
//我这边用的scss预处理,直接下载就好了
npm install sass
二、子组件实现代码
//html代码
<template>
<div>
<el-dialog v-model="dialogVisible" :show-close="false" :close-on-click-modal="false">
<div class="dialog">
<div class="fs-16 bold c-0">选择好友<span class="fs-12 c-80">{{ contactList.length }}/{{ contacts.length
}}</span><span style="margin-left: 200px;cursor:pointer" @click="chooses()">{{ choose == 1 ? '单选' : '多选'}}</span></div>
<el-input v-model="contact" placeholder="搜索" clearable :prefix-icon="Search" @input="search" />
<div class="list">
<el-scrollbar height="420px">
<div class="li" v-for="(item, index) in contacts" :key="index" @click="forwarding(item)">
<img :src="item.choose ? 'https://pic.imgdb.cn/item/6426503fa682492fcc5e327d.png' : 'https://pic.imgdb.cn/item/64265063a682492fcc5e65ad.png'"
alt="" class="li-left">
<div class="li-right">
<img src="https://pic.imgdb.cn/item/64265077a682492fcc5e7d6f.gif" alt="">
<!-- <img :src="item.img" alt=""> -->
<div class="fs-14 c-3">{{ item.name }}</div>
</div>
</div>
</el-scrollbar>
</div>
<div class="bottom">
<el-button type='primary' text @click="cancel">取消</el-button>
<el-button type='primary' text @click="determine">确认</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
//组件通过dialog控制和scrollbar滚动条实现,所以先引用这2个组件
import { ref, toRefs, watch } from 'vue'
import { ElScrollbar, ElMessage, } from 'element-plus';
import { Search } from '@element-plus/icons-vue'
//然后定义组件的初始值,组件状态以及组件接受的参数等
let props = defineProps({
dialogShow: {
type: Boolean,
default: false,
},
});
const refProps = toRefs(props)
const emit = defineEmits(['getContact', 'contactShow'])
let dialogVisible = ref(props.dialogShow)//本地组件状态
watch(refProps.dialogShow, (val, old) => {
dialogVisible.value = val
}, { deep: true })//监听修改本地
let contact = ref('')//联系人搜索
let contactList = ref([] as any)//选中转发的联系人
let choose = ref(2)//单选为1 多选为2
let contacts: any = ref([{
img: '',
name: 'Lingzi',
choose: false,
id: 1,
}, {
img: '',
name: 'zhangsan0',
choose: false,
id: 2,
}, {
img: '',
name: 'lisi',
choose: false,
id: 3,
}, {
img: '',
name: 'Wanger',
choose: false,
id: 4,
}, {
img: '',
name: 'yangyu',
choose: false,
id: 5,
}, {
img: '',
name: '007',
choose: false,
id: 6,
}, {
img: '',
name: 'YangyuS',
choose: false,
id: 7,
},])
let contactsCopy: any = ref(contacts.value)
//相关逻辑和方法
const chooses = () => {//单选多选切换
choose.value = choose.value == 1 ? 2 : 1
contacts.value.forEach((i:any)=>{
i.choose=false
})
contactList.value=[]
}
const forwarding = (item: any) => {//选择
if (choose.value == 1) {//单选
if (!item.choose) {
let y = contacts.value.some((i: any) => {
return i.choose
})
if (y) {//有选中的
contacts.value.forEach((item: any) => {
item.choose = false
contactList.value = []
})
}
}
item.choose = !item.choose
if (item.choose) {
contactList.value.push(item.name)
} else {
contactList.value = []
}
} else {//多选
item.choose = !item.choose
if (item.choose && contactList.value.indexOf(item.name) == -1) {
contactList.value.push(item.name)
} else if (!item.choose && contactList.value.indexOf(item.name) != -1) {
contactList.value.splice(contactList.value.indexOf(item.name), 1)
}
}
};
const cancel = () => {//取消操作
emit('contactShow', false)//通过emit传值给父组件
contactList.value = []
contacts.value.forEach((item: any) => {
item.choose = false
})
}
const determine = () => {//确定操作
if (contactList.value && contactList.value.length) {
emit('getContact', contactList.value)//把选中的信息传递给父组件
cancel()
} else {
ElMessage.error('请选择转发的对象')
}
}
const search = () => {//搜索
if (contact.value == '') {
contacts.value = contactsCopy.value
}
let arr = ref([] as any)
contactsCopy.value.map((item: any) => {
if (item.name.toLowerCase().indexOf(contact.value.toLowerCase()) != -1) {
return arr.value.push(item)
}
})
contacts.value = arr.value
}
三、父组件实现代码
//html代码
<el-button type="primary" @click="show()">打开弹框</el-button>
<Dialog :dialogShow="dialogShow" @contactShow="contactShow" @getContact="getContact"></Dialog>
//js代码
import {ref} from 'vue'
import Dialog from '../components/forwarding.vue';
let dialogShow=ref(false)
const show=()=>{//控制子组件状态
dialogShow.value=true
}
const contactShow = (e: boolean) => {//接受子组件传递过来的状态
dialogShow.value = e
}
const getContact = (e: object) => {//接受子组件传递过来的状态
console.log(e)
}
四、相关效果图
五、整体代码
- //父组件
- <template>
- <el-button type="primary" @click="show()">打开弹框</el-button>
- <Dialog :dialogShow="dialogShow" @contactShow="contactShow" @getContact="getContact"></Dialog>
- </template>
-
- <script setup lang="ts">
- import {ref} from 'vue'
- import Dialog from '../components/forwarding.vue';
- let dialogShow=ref(false)
- const show=()=>{//控制子组件显示
- dialogShow.value=true
- }
- const contactShow = (e: boolean) => {//接受子组件传递过来的状态
- dialogShow.value = e
- }
- const getContact = (e: object) => {//接受子组件传递过来的状态
- console.log(e)
- }
- </script>
- <style scoped lang="scss"></style>
-
- //子组件
- <template>
- <div>
- <el-dialog v-model="dialogVisible" :show-close="false" :close-on-click-modal="false">
- <div class="dialog">
- <div class="fs-16 bold c-0">选择好友<span class="fs-12 c-80">{{ contactList.length }}/{{ contacts.length
- }}</span><span style="margin-left: 200px;cursor:pointer" @click="chooses()">{{ choose == 1 ? '单选' : '多选'}}</span></div>
- <el-input v-model="contact" placeholder="搜索" clearable :prefix-icon="Search" @input="search" />
- <div class="list">
- <el-scrollbar height="420px">
- <div class="li" v-for="(item, index) in contacts" :key="index" @click="forwarding(item)">
- <img :src="item.choose ? 'https://pic.imgdb.cn/item/6426503fa682492fcc5e327d.png' : 'https://pic.imgdb.cn/item/64265063a682492fcc5e65ad.png'"
- alt="" class="li-left">
- <div class="li-right">
- <img src="https://pic.imgdb.cn/item/64265077a682492fcc5e7d6f.gif" alt="">
- <!-- <img :src="item.img" alt=""> -->
- <div class="fs-14 c-3">{{ item.name }}</div>
- </div>
- </div>
- </el-scrollbar>
- </div>
- <div class="bottom">
- <el-button type='primary' text @click="cancel">取消</el-button>
- <el-button type='primary' text @click="determine">确认</el-button>
- </div>
- </div>
- </el-dialog>
- </div>
- </template>
- <!-- 多选组件---------------- -->
- <script setup lang="ts">
- import { ref, toRefs, watch } from 'vue'
- import { ElScrollbar, ElMessage, } from 'element-plus';
- import { Search } from '@element-plus/icons-vue'
- let props = defineProps({
- dialogShow: {
- type: Boolean,
- default: false,
- },
- });
- const refProps = toRefs(props)
- const emit = defineEmits(['getContact', 'contactShow'])
- let dialogVisible = ref(props.dialogShow)//本地组件状态
- watch(refProps.dialogShow, (val, old) => {
- dialogVisible.value = val
- }, { deep: true })//监听修改本地
- let contact = ref('')//联系人搜索
- let contactList = ref([] as any)//选中转发的联系人
- let choose = ref(2)//单选为1 多选为2
- let contacts: any = ref([{
- img: '',
- name: 'Lingzi',
- choose: false,
- id: 1,
- }, {
- img: '',
- name: 'zhangsan0',
- choose: false,
- id: 2,
- }, {
- img: '',
- name: 'lisi',
- choose: false,
- id: 3,
- }, {
- img: '',
- name: 'Wanger',
- choose: false,
- id: 4,
- }, {
- img: '',
- name: 'yangyu',
- choose: false,
- id: 5,
- }, {
- img: '',
- name: '007',
- choose: false,
- id: 6,
- }, {
- img: '',
- name: 'YangyuS',
- choose: false,
- id: 7,
- },])
- let contactsCopy: any = ref(contacts.value)
- const chooses = () => {//单选多选切换
- choose.value = choose.value == 1 ? 2 : 1
- contacts.value.forEach((i:any)=>{
- i.choose=false
- })
- contactList.value=[]
- }
- const forwarding = (item: any) => {//选择
- if (choose.value == 1) {//单选
- if (!item.choose) {
- let y = contacts.value.some((i: any) => {
- return i.choose
- })
- if (y) {//有选中的
- contacts.value.forEach((item: any) => {
- item.choose = false
- contactList.value = []
- })
- }
- }
- item.choose = !item.choose
- if (item.choose) {
- contactList.value.push(item.name)
- } else {
- contactList.value = []
- }
- } else {//多选
- item.choose = !item.choose
- if (item.choose && contactList.value.indexOf(item.name) == -1) {
- contactList.value.push(item.name)
- } else if (!item.choose && contactList.value.indexOf(item.name) != -1) {
- contactList.value.splice(contactList.value.indexOf(item.name), 1)
- }
- }
- };
- const cancel = () => {//取消操作
- emit('contactShow', false)//通过emit传值给父组件
- contactList.value = []
- contacts.value.forEach((item: any) => {
- item.choose = false
- })
- }
- const determine = () => {//确定操作
- if (contactList.value && contactList.value.length) {
- emit('getContact', contactList.value)//把选中的信息传递给父组件
- cancel()
- } else {
- ElMessage.error('请选择转发的对象')
- }
- }
- const search = () => {//搜索
- if (contact.value == '') {
- contacts.value = contactsCopy.value
- }
- let arr = ref([] as any)
- contactsCopy.value.map((item: any) => {
- if (item.name.toLowerCase().indexOf(contact.value.toLowerCase()) != -1) {
- return arr.value.push(item)
- }
- })
- contacts.value = arr.value
- }
- </script>
- <style scoped lang="scss">
- .fs-16 {
- font-size: 16px;
- font-family: Source Han Sans CN;
- font-weight: 400;
- color: #333333;
- }
-
- .fs-12 {
- font-size: 12px;
- font-family: SourceHanSansSC;
- font-weight: 400;
- color: #999999;
- }
-
- .fs-14 {
- font-size: 14px;
- font-family: Source Han Sans CN;
- font-weight: 400;
- color: #FFFFFF;
- }
-
- .fs-20 {
- font-size: 20px;
- font-family: Source Han Sans CN;
- font-weight: 500;
- color: #333333;
- }
-
- .c-0 {
- color: #000000;
- }
-
- .c-3 {
- color: #333333;
- font-weight: 500;
- }
-
- .c-80 {
-
- color: #808080;
- }
-
- .bold {
- font-weight: bold;
- }
-
- :deep(.el-dialog) {
- width: 362px;
- height: 580px;
- background: #FFFFFF;
- border-radius: 6px;
- position: absolute;
- top: 2%;
- left: 40%;
-
- .el-dialog__header {
- padding: 0;
- }
-
- .el-dialog__body {
- padding: 0;
- }
-
- .dialog {
- padding: 20px;
- text-align: left;
-
- .el-input__wrapper {
- margin-top: 30px;
- padding: 0;
- border-bottom: 1px solid #f2f2f2;
- box-shadow: none
- }
-
- .list {
- margin-top: 2px;
-
- .li {
- display: flex;
- align-items: center;
- padding: 10px 0;
-
- // padding:0 20px;
- .li-left {
- width: 18px;
- height: 18px;
- margin-right: 10px;
- }
-
- .li-right {
- display: flex;
- align-items: center;
-
- img {
- width: 46px;
- height: 46px;
- border-radius: 50%;
- margin-right: 12px;
- }
- }
- }
-
- .li:hover {
- background: #e6eaf2;
- }
- }
-
- .bottom {
- display: flex;
- margin-top: 10px;
- justify-content: flex-end;
- }
- }
- }</style>
六、总结
一个简单的转发弹框,有相同业务逻辑的项目可以直接copy现用,代码写的有点渣,有相关代码优化的地方还望各位大佬能指点一二。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。