vue +element 封装一个选人弹窗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue +element 封装一个选人弹窗相关的知识,希望对你有一定的参考价值。

参考技术A 一:需求:

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>

以上是关于vue +element 封装一个选人弹窗的主要内容,如果未能解决你的问题,请参考以下文章

vue封装element弹窗组件封装为什么抛不出去点击事件

封装一个用vue+element-ui实现的远程搜索组件(vue-cli项目中)

二次封装el-dialog组件

Vue + Element-ui实现后台管理系统---封装一个ECharts组件的一点思路

Vue + Element-ui实现后台管理系统---封装一个ECharts组件的一点思路

Vue + Element-ui实现后台管理系统---封装一个Form表单组件和Table表格组件