vue 公共列表选择组件,引用Vant-UI的样式方式
程序员文章站
2022-05-09 18:05:11
此组件用于公共选择组件。引用vant ui 作为样式特性:1、支持动态、静态数据源。2、支持分页加载。3、支持模糊搜索。4、支持单选、多选。组件源码:
此组件用于公共选择组件。引用vant ui 作为样式
特性:
1、支持动态、静态数据源。
2、支持分页加载。
3、支持模糊搜索。
4、支持单选、多选。
组件源码:
<template> <div class="gn-pubselect"> <van-action-sheet v-model="inshow"> <div class="gn-pubselect-main" :style="{'height':mainheight}"> <van-search class="gn-search" placeholder="请输入搜索关键词" v-model="condition" show-action> <van-button slot="action" size="small" type="primary" @click="inshow = false">确认</van-button> </van-search> <div class="gn-select-list"> <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="filterselectlist" > <!--单选控件--> <van-radio-group v-model="radioresult" v-if="type == 'radio'"> <van-cell-group> <van-cell class="gn-cell" v-for="(item, index) in filterlist" :title="item.name" @click="radioresult = item" :key="item.id" clickable> <van-radio checked-color="#07c160" slot="right-icon" :name="item" /> {{item.number}} </van-cell> </van-cell-group> </van-radio-group> <!--复选控件--> <van-checkbox-group v-model="checkboxresult" v-if="type == 'checkbox'"> <van-cell-group> <van-cell class="gn-cell" v-for="(item, index) in filterlist" clickable :key="item.id" :title="`${item.name}`" @click="toggle(index)" > <van-checkbox ref="checkboxes" checked-color="#07c160" slot="right-icon" :name="item" /> {{item.number}} </van-cell> </van-cell-group> </van-checkbox-group> </van-list> </div> </div> </van-action-sheet> </div> </template> <script> var vm = null; import {postaction} from '@/api/manage' export default { /*name:'pubselect'+math.random(),*/ props: { show: { type:boolean, required: true }, type:{ type:string, required: true, validator: function(value){ return value == 'radio' || value == 'checkbox'; } }, islink:{ type:boolean, default:function () { return false; } }, url:{ type:string }, selectlist:{ type:array } }, data() { return { inshow:false, //是否显示选择组件 condition:'', //查询关键字 checkboxresult:[], //复选框 选中结果 radioresult:{}, //单选框 选中结果 filterlist: [], //过滤后的选择列表 loading:false, finished:false, page:1 } }, computed:{ mainheight(){ let h = document.documentelement.clientheight || document.body.clientheight; return (h*0.9)+'px'; } }, watch:{ condition(newval,oldval){ /*条件改变时更新选择列表*/ this.filterlist = []; this.page = 1; this.filterselectlist(); }, inshow(newval,oldval){ //子组件向父组件传值 this.$emit('update:show',newval); //关闭选择控件时自动带回选中的值 if(!newval){ this.updateselectlist(); } }, show(newval,oldval){ //子组件接收父组件的值 this.inshow = newval; } }, created() { vm = this; this.initcheck(); this.filterselectlist(); }, mounted() { }, destroyed() { }, methods: { filterselectlist(){ /*过滤选择列表*/ if(!this.islink){ this.filterlist = []; for(let i=0;i<this.selectlist.length;i++){ let item = this.selectlist[i]; if(item.name.indexof(this.condition) != -1 || item.number.indexof(this.condition) != -1){ this.filterlist.push(item); } } this.finished = true; }else{ /*动态加载数据*/ this.loading = true; postaction(this.url,{pagesize:10,page:this.page++,condition:this.condition}).then((result) => { // 加载状态结束 this.loading = false; // 数据全部加载完成 if (result.length == 0) { this.finished = true; }else{ for(let i=0;i<result.length;i++){ this.filterlist.push(result[i]); } } }); } }, toggle(index) { this.$refs.checkboxes[index].toggle(); }, updateselectlist(){ /*更新选中结果*/ if(this.type == 'radio'){ this.$emit('update:result',this.radioresult); }else{ this.$emit('update:result',this.checkboxresult); } }, initcheck(){ /*检验参数有效性*/ if(this.islink){ if(this.url == undefined || this.url == null || this.url == ""){ throw new error("[url]参数必填!"); } }else{ if(this.selectlist == undefined || this.selectlist == null ){ throw new error("[selectlist]参数必填!"); } } } } }; </script> <style scoped="scoped" lang="scss"> .gn-pubselect { .gn-pubselect-main{ display: flex; flex-flow: column; position: relative; max-height: 90%; .gn-search{ } .gn-select-list{ flex: 1; overflow-y: scroll; .gn-cell{ .van-cell__title{ margin-right: 10px; flex: 1; } .van-cell__value{ text-align: left; word-break: break-all; flex: none; margin-right: 10px; max-width: 120px; display: flex; align-items: center; } } } } } </style>
组件中的【动态加载数据】是经过封装的请数据,需要改为axios请求。
数据源:
1、静态数据源格式
"list": [ { "id": "", "number": "", "name": "" } ],
2、动态数据源格式
{ "success": true, "data": [ { "id": "", "number": "", "name": "" } ], "page": 1, "pagesize": 3 }
使用方式
1、在需要使用选择组件的地方引入组件
import pubselect from '@/base/pubselect.vue'
2、静态数据源使用方式
<pub-select id="pub-select" type="radio" :show.sync="showselectproject" :selectlist="list" :result.sync="form.project" />
3、动态数据源使用方式
<pub-select id="pub-select" type="checkbox" :show.sync="showselectproject" :result.sync="fcourse" url="/assetctl/projectlist" islink />
补充知识:van-picker级联选择(自定义字段显示)
前言
vant之van-picker级联选择
1、将自定义平铺结构转化为层级结构数据
2、动态$set()给每一条数据对象添加text属性用于展示
数据处理
原始数据
[ {id: 'node1',pid: 'root',content: 'test'}, {id: 'node2',pid: 'root',content: 'test'}, {id: 'node3',pid: 'node1',content: 'test'}, {id: 'node4',pid: 'node2',content: 'test'}, {id: 'node5',pid: 'node3',content: 'test'}, {id: 'node6',pid: 'node1',content: 'test'} ]
转化后数据
[ { id: 'node1', pid: 'root', content: 'test', children: [ { id: 'node3', pid: 'node1', ccontent: 'test', children: [ {id: 'node5',pid: 'node3',content: 'test'} ] }, {id: 'node6',pid: 'node1',content: 'test'} ] }, { id: 'node2', pid: 'root', content: 'test', children: [ {id: 'node4',pid: 'node2',content: 'test'} ] }, ]
转化函数tile2nest
// 平铺结构转嵌套结构 tile2nest(array, key, pkey, childrenkey) { if (!array || array.constructor !== array) { return array; } // 复制一份,避免修改原始数组 let ary = [...array]; key = key || "id"; // 平铺数据主键 pkey = pkey || "parentid";//平铺数据父节点数据 childrenkey = childrenkey || "children";//子节点名称 // 定义一个待移除数组 let ary2remove = []; ary.map(item => { //动态添加属性text以适应van-picker组件默认显示text字段 this.$set(item,'text',item.name); if (item[key] !== item[pkey]) { // 找父节点 let p = ary.filter(c => c[key] === item[pkey]); if (p && p.length == 1) { p[0].children = p[0].children || []; // 将子节点放到父节点中 p[0].children.push(item); ary2remove.push(item[key]); } } }); // 遍历移除待删除对象 ary2remove.map(item => { ary = ary.filter(c => c[key] !== item); }); //返回转化后的层次结构数据 return ary; }
使用组件
<van-field readonly clickable placeholder="一二级分类" :value="form.kind" @click="showpicker = true" /> <van-popup v-model="showpicker" position="bottom" :duration="0"> <van-picker show-toolbar title="分类选择" :columns="columns" @cancel="showpicker = false" @confirm="onconfirm" @change="onchange" /> </van-popup>
onconfirm(value) { let str = ""; // 呈现页面显示 /xxx/xxx/xxx for(let i= 0;i<value.length;i++){ if(i>0){ str += "/" + value[i]; } else{ str +=value[i]; } } this.form.kind = str; this.showpicker = false },
效果
选择效果
以上这篇vue 公共列表选择组件,引用vant-ui的样式方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。