vue 公共列表选择组件,引用Vant-UI的样式方式


Posted in Javascript onNovember 02, 2020

此组件用于公共选择组件。引用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请求。

vue 公共列表选择组件,引用Vant-UI的样式方式

数据源:

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的样式方式

选择效果

vue 公共列表选择组件,引用Vant-UI的样式方式

以上这篇vue 公共列表选择组件,引用Vant-UI的样式方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery.ui.progressbar 中文文档
Nov 26 Javascript
基于jQuery的计算文本框字数的代码
Jun 06 Javascript
JS中批量给元素绑定事件过程中的相关问题使用闭包解决
Apr 15 Javascript
javascript中数组中求最大值示例代码
Dec 18 Javascript
jQuery学习笔记之基础中的基础
Jan 19 Javascript
jQuery插件pagination实现无刷新分页
May 21 Javascript
实例详解display:none与visible:hidden的区别
Mar 30 Javascript
详解webpack+gulp实现自动构建部署
Jun 29 Javascript
ReactNative之键盘Keyboard的弹出与消失示例
Jul 11 Javascript
详解a标签添加onclick事件的几种方式
Mar 29 Javascript
基于layui框架响应式布局的一些使用详解
Sep 16 Javascript
antd多选下拉框一行展示的实现方式
Oct 31 Javascript
在vant 中使用cell组件 定义图标该图片和位置操作
Nov 02 #Javascript
Vant picker 多级联动操作
Nov 02 #Javascript
vue实现列表拖拽排序的功能
Nov 02 #Javascript
用vue写一个日历
Nov 02 #Javascript
在vue中使用vant TreeSelect分类选择组件操作
Nov 02 #Javascript
vant自定义二级菜单操作
Nov 02 #Javascript
JavaScript动态生成表格的示例
Nov 02 #Javascript
You might like
PHP 图片水印类代码
2012/08/27 PHP
php中出现空白页的原因及解决方法汇总
2014/07/08 PHP
PHP实现的文件浏览器功能简单示例
2019/09/12 PHP
HTTP头隐藏PHP版本号实现过程解析
2020/12/09 PHP
Firebug 字幕文件JSON地址获取代码
2009/10/28 Javascript
jquery删除提示框弹出是否删除对话框
2014/01/07 Javascript
javascript实现全角半角检测的方法
2015/07/23 Javascript
一个仿微博登陆邮箱提示框js开发案例
2016/07/28 Javascript
Bootstrap 模态框实例插件案例分析
2016/12/28 Javascript
Node.js实现连接mysql数据库功能示例
2017/09/15 Javascript
对于input 框限定输入值为浮点型的js代码
2017/09/25 Javascript
js 客户端打印html 并且去掉页眉、页脚的实例
2017/11/03 Javascript
完美解决手机浏览器顶部下拉出现网页源或刷新的问题
2017/11/30 Javascript
使用D3.js创建物流地图的示例代码
2018/01/27 Javascript
JS实现点击li标签弹出对应的索引功能【案例】
2019/02/18 Javascript
vue-cli3+typescript初体验小结
2019/02/28 Javascript
详解mpvue实现对苹果X安全区域的适配
2019/07/31 Javascript
Vue实现按钮级权限方案
2019/11/21 Javascript
前端深入理解Typescript泛型概念
2020/03/09 Javascript
[15:39]教你分分钟做大人:龙骑士
2014/10/30 DOTA
[02:37]2018DOTA2亚洲邀请赛赛前采访 VP.no[o]ne心中最强SOLO是谁
2018/04/04 DOTA
Python中bisect的用法
2014/09/23 Python
Python2.x中文乱码问题解决方法
2015/06/02 Python
windows下ipython的安装与使用详解
2016/10/20 Python
使用python调用zxing库生成二维码图片详解
2017/01/10 Python
Python面向对象程序设计类的多态用法详解
2019/04/12 Python
tensorflow 保存模型和取出中间权重例子
2020/01/24 Python
Python抓包程序mitmproxy安装和使用过程图解
2020/03/02 Python
使用Python实现音频双通道分离
2020/12/25 Python
解决pycharm不能自动保存在远程linux中的问题
2021/02/06 Python
Booking.com亚太地区:Booking.com APAC
2020/02/07 全球购物
美国艺术和工艺品商店:Hobby Lobby
2020/12/09 全球购物
机电专业求职信
2014/06/14 职场文书
中学清明节活动总结
2014/07/04 职场文书
关于群众路线的心得体会
2014/11/05 职场文书
五星级酒店前台接待岗位职责
2015/04/02 职场文书