vue +element 封装一个选人弹窗

一:需求:

1.要有部门分类

2.能选人(同时可以选择整个部门)

3.保留原选中的人的不去除

4.能搜索,显示搜索结果的时候 不显示部门名称

5.点击部门展开收起,只有本部门时默认展开

二:

知识点(1):获取数据


知识点(2):渲染


知识点(3):点击部门展开收起,只有本部门时默认展开


控制点击展开

点击展开的时候要改变左侧箭头的样式

<i class="bg-icon bg-icon-f10 is-close"   :style="{transform:team.is_open?'rotate(90deg)':'rotate(0deg)'}"></i>

在此之前我们的数据里是没有is_open这个属性的,所以需要自己传进去

let search_persons = res.data;

              search_persons.forEach(person=>{

                            person.is_open = this.isOpenAll;

                   })

           _this.search_persons = [...search_persons];

再通过 team.is_open = !team.is_open;控制点击展开与收起

但是只有本部门的时候默认展开我们需要通过传参的方式控制

在子组件内定义:

props:{

            isOpenAll:{

                type:Boolean,

                default:false,

            }

        },

之后去父组件(调用的地方)使用:

<rp-link-person v-model="admin_users" :is-team="1" :is-open-all="true" />

三:

选择部门的时候:

<div class="group-name" @click="isOpenClick(team)">

                            <i class="bg-icon bg-icon-f10 is-close"

                            :style="{transform:team.is_open?'rotate(90deg)':'rotate(0deg)'}"></i>

                            <span>{{team.name}}</span>

                            <i class="bg-icon bg-icon-tianjia is-select" @click.stop="selectGroup(team)"></i>

                        </div>

//选择整个项目组

            selectGroup(team) {

                for(let i = 0;i<team.children.length;i++){

                    let index = this.selected.findIndex(item=> item && item.uid == team.children[i].uid);

                    if(index<0){

                        this.selected.push({...team.children[i]});

                    }

                }

                this.change();

            },

选择人的时候:

<div class="group-person" v-if="team.is_open">

                            <template v-for="person in team.children">

                                <p :key="person.uid" @click="selectPerson(person)" :class="{on:isSelected(person.uid)}">

                                <span class="hdpic">

                                    <el-image :src="'http://pic2.hanmaker.com/staff/small/' + person.head_img" :lazy="search_persons.length>7" :scroll-container="$refs.list"></el-image>

                                </span>

                                    <span class="named">{{person.full_name}}</span>

                                    <i class="bg-icon" :class="{'bg-icon-xzfill':isSelected(person.uid),'bg-icon-weixuanzhongyuanquan':!isSelected(person.uid)}"></i>

                                </p>

                            </template>

                        </div>

// 选择人员

            selectPerson(person){

                let index = this.selected.findIndex(item=> item && item.uid == person.uid);

                if(index>=0){

                    this.selected.splice(index,1);

                }else{

                    this.selected.push({...person});

                }

                this.change();

            },

保留选中的人不去除:

setDefault(data){

                let change = [];

                data.forEach(item => {

                    let index = -1;

                    let c_child = []; 

                    for(let j=0;j<this.persons.length;j++) {

                        c_child = [...c_child,...this.persons[j].children]

                    }   

                    if (typeof item == 'number' || typeof item == 'string') {

                        index = c_child.findIndex(person => person.uid == item)

                    } else {

                        index = c_child.findIndex(person => person.uid == item.uid)

                    }

                    change.push(c_child[index]);

                });

                this.selected = change;

            },

            isSelected(uid) {

                return this.selected.findIndex(item => item && item.uid == uid) >= 0;

            }

在父组件中绑定

<rp-link-person v-model="admin_users" :is-team="1" :is-open-all="true" />双向绑定

在点击添加的时候赋值

addPerson(){

                this.admin_dialog = true;

                this.admin_users = this.table_data.map(item=>item.uid);

            },

搜索:

<div class="search-body">

                <input type="text" v-model="keyword" placeholder="搜索成员">

                <i class="input-icon bg-icon bg-icon-sousuo"></i>

            </div>

watch:{

            value(val){

                this.setDefault(val);

            },

            keyword(text) {

                this.isSearch = false;

                if (text == '') {

                    this.search_persons= this.persons;

                } else {

                    this.isSearch = true;

                    let search_persons = [];

                    for(let g= 0;g<this.persons.length;g++){

                        let s_child = this.persons[g].children.filter(person => {

                            return person.full_name.indexOf(text) >= 0;

                        }) 

                        search_persons = [...search_persons,...s_child];

                    }

                    this.search_persons = [...search_persons];

                }

            }

        }

但是因为搜索结果不显示部门所以需要分开判断

显示部门:

<template v-if="!isSearch">

                    <div class="group-list" v-for="(team,index) in search_persons" :key="team.id">

                        <div class="group-name" @click="isOpenClick(team)">

                            <i class="bg-icon bg-icon-f10 is-close"

                            :style="{transform:team.is_open?'rotate(90deg)':'rotate(0deg)'}"></i>

                            <span>{{team.name}}</span>

                            <i class="bg-icon bg-icon-tianjia is-select" @click.stop="selectGroup(team)"></i>

                        </div>

                        <div class="group-person" v-if="team.is_open">

                            <template v-for="person in team.children">

                                <p :key="person.uid" @click="selectPerson(person)" :class="{on:isSelected(person.uid)}">

                                <span class="hdpic">

                                    <el-image :src="'http://pic2.hanmaker.com/staff/small/' + person.head_img" :lazy="search_persons.length>7" :scroll-container="$refs.list"></el-image>

                                </span>

                                    <span class="named">{{person.full_name}}</span>

                                    <i class="bg-icon" :class="{'bg-icon-xzfill':isSelected(person.uid),'bg-icon-weixuanzhongyuanquan':!isSelected(person.uid)}"></i>

                                </p>

                            </template>

                        </div>

                    </div>

                </template>

不显示:

<template v-if="isSearch">

                    <div class="group-person">

                        <template v-for="person in search_persons">

                            <p :key="person.uid" @click="selectPerson(person)" :class="{on:isSelected(person.uid)}">

                            <span class="hdpic">

                                <el-image :src="'http://pic2.hanmaker.com/staff/small/' + person.head_img" :lazy="search_persons.length>7" :scroll-container="$refs.list"></el-image>

                            </span>

                                <span class="named">{{person.full_name}}</span>

                                <i class="bg-icon" :class="{'bg-icon-xzfill':isSelected(person.uid),'bg-icon-weixuanzhongyuanquan':!isSelected(person.uid)}"></i>

                            </p>

                        </template>

                    </div>

                </template>

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容