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

此组件用于公共选择组件。引用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的样式方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vue全局使用less样式,组件使用全局样式文件中定义的变量操作

    当你想要在vue项目的一个组件中使用全局样式文件中定义好的变量,此时只在main.js中import是不行的. 目录结构如下: 即在MHeader.vue中想要使用src下的less下的variables.less文件中定义好的变量. 此时,只用import在main.js中导入variables.less文件是会报错的. 解决办法: 1.安装less和less-loader npm i less less-loader -D 2.要想全局使用还需使用一个插件( sass-resources-l

  • 解决vue scoped html样式无效的问题

    1.问题场景 page1,page2都使用flexible移动端自适应的时候,有一个页面page2需要手动设置rem基准值, //手动设置基准 html{ font-size: 120px !important; } 但是在page2引用的self.less里面设置了基准,竟然没有生效 2.问题分析scoped属性 在引用self.less的时候,使用了属性scoped vue中引入了scoped这个概念,设计思想就是让当前组件的样式不会修改到其他页面的样式,使用了data-v-hash的方式来

  • vue修改Element的el-table样式的4种方法

    修改Element中的el-table样式,可以使用以下几种方法: 1. row-style 行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style. 2. cell-style 单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有单元格设置一样的 Style. 3. header-row-style 表头行的 style 的回调方法,也可以使用一个固定的 Object 为所有表头行设置一样的 Style. 4. header-c

  • vue中选中多个选项并且改变选中的样式的实例代码

    1:HTML: <ul class="content"> <li v-for="(item,index) in touristList" @click="onStorage(item,index)" :class="{'active': rSelect.indexOf(item)!=-1}" :key="item.id"> <div>{{item.name}}</d

  • Vue检测屏幕变化来改变不同的charts样式实例

    css中我们经常会通过媒体查询就可以完成对不同的屏幕展现不同的样式 在js中我们也可以通过检测屏幕的变化来展现不同的样式 在我的实例中:因为第一次打开也不知道到底是应该展示哪一个屏幕,所以会进行先判断一次,之后用addEventListener来是实现功能,暂时是通过这种方式实现的,以后有更好的方法再更新... mounted() { this.checkScreen() }, methods: { // 屏幕检测变化 checkScreen() { var _this = this if (d

  • vue-cli —— 如何局部修改Element样式

    最近在做vue项目时用到了Element,发现这玩意儿用起来很舒服,很新颖,上手也很快,而且效果足够酷炫.但是后面发现一个很大的问题,那就是Element的样式有限,这极大地限制了项目的应用广度,所以我们有必要对Element内部的CSS进行一定的覆盖,来改变其样式.在修改Element样式时,遇到了一些问题,这里简单做一些记录,便于以后查阅. 我在用el-switch做开关切换时,使用默认样式: 代码如下: 效果: 现在我想把蓝色字体改为其他颜色,但是我发现无论我如何修改样式,界面始终没有任何

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

    此组件用于公共选择组件.引用Vant UI 作为样式 特性: 1.支持动态.静态数据源. 2.支持分页加载. 3.支持模糊搜索. 4.支持单选.多选. 组件源码: <template> <div class="gn-PubSelect"> <van-action-sheet v-model="inShow"> <div class="gn-PubSelect-main" :style="{'he

  • Vue.js 图标选择组件实践详解

    本文介绍了Vue.js 图标选择组件实践详解,分享给大家,具体如下: 背景 最近项目中在做一个自定义菜单需求,其中有一个为菜单设置小图标的功能,就是大家常见的左侧菜单 设置图标不难,方案就是字体图标,可供使用的图标库也有很多,比如阿里巴巴的 Iconfont,以及 Fontaswsome 等,问题在于如何优雅的提供几百个图标供用户选择,而不需要开发去一个一个的写标签,也不需要一个个的去找图标. 字体图标库 Fontawesome 方案 我们使用字体图标的方式,一般是一个 <i class="

  • 基于 Vue 的树形选择组件的示例代码

    本文介绍了基于 Vue 的树形选择组件.分享给大家,具体如下: 系统要求:Vue 2 基本特性 完美的多级联动效果 支持无限多的分级 有 全选.半选.不选 三种状态  截图展示 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="icon" href="https://v1-c

  • 在vue中使用vant TreeSelect分类选择组件操作

    中文文档:TreeSelect 分类选择 效果展示: //先在你需要的页面中引入,第一个是弹出层,第二个是选择的 import { Popup } from "vant"; import { TreeSelect } from "vant"; 代码部分: <van-popup v-model="policeShow" position="top" :overlay="true"> <van

  • Mint UI 基于 Vue.js 移动端组件库

    官网地址 http://mint-ui.github.io/ Mint UI 包含丰富的 CSS 和 JS 组件,能够满足日常的移动端开发需要.通过它,可以快速构建出风格统一的页面,提升开发效率. 真正意义上的按需加载组件.可以只加载声明过的组件及其样式文件,无需再纠结文件体积过大. 考虑到移动端的性能门槛,Mint UI 采用 CSS3 处理各种动效,避免浏览器进行不必要的重绘和重排,从而使用户获得流畅顺滑的体验. 依托 Vue.js 高效的组件化方案,Mint UI 做到了轻量化.即使全部引

  • vue.js模仿京东省市区三级联动的选择组件实例代码

    前言 在最近的工作中需要一个盒京东购物车地址选择相似的一个省市区三级联动选择组件,google查了下都是下拉框形式的,于是自己写了一个,希望对使用vue开发项目的朋友有帮助,下面话不多说了,来一起看看详细的介绍吧. 显示效果如下: 注意:使用vue2.0开发 实例代码 html代码如下 <!--居住地址三级联动选项--> <section class="showChose" v-show="showChose"> <section cl

  • 在vue项目中引入高德地图及其UI组件的方法

    引入高德地图: 打开index.html,引用高德地图的JavaScript API: <script type="text/javascript" src="http://webapi.amap.com/maps?v=1.3&key=你的API key"></script> 在"key="这里添加你申请的key,key不需要加引号. 引入高德地图UI组件,只需要在上面代码后面再加一串代码: <script

  • Vue下拉选择框Select组件使用详解(二)

    本文实例为大家分享了Vue下拉选择框Select组件的使用方法,供大家参考,具体内容如下 效果图如下: 下拉组件宽度可自定义设置以下属性: ①下拉组件宽度width属性,默认宽度290 ②placeholder属性 ③是否禁用下拉的disabled属性 已预设下拉列表最多8条,超过时滚动显示,具体可自定义调整,如果下拉选项过长省略号显示,鼠标悬浮显示全称,由于业务需求,设置mode属性,区别默认name和value  与  dictKey和dictVal ①创建组件Select.vue <tem

  • 如何抽象一个Vue公共组件

    之前一直想写一篇关于抽象 Vue 组件的随笔,无奈一直没想到好的例子.恰巧最近为公司项目做了一个数字键盘的组件,于是就以这个为例聊聊如何抽象 Vue 的组件. 先上 Demo 与 源码.(demo最好在浏览器里以手机模式浏览) 在讲具体实现前,我想先分享下自己认为的理想的公用组件是什么样的: 1. 黑盒性,即除了你自己以外,其他的开发者在快速阅读使用文档之后可以立刻上手,而不用关心你的内部实现: 2. 独立性,即做好解耦,不与父组件有过多关联: 3 自定义性,适当地暴露一些输入接口或者方法给外部

  • Android组件实现列表选择框功能

    android提供的列表选择框(Spinner)相当于web端用户注册时的选择下拉框,比如注册候选择省份城市等.如下图便是一个列表选择框 下拉列表的列表选择项能够通过xml文件的android:entries属性指定,或是在java代码中导入,属性android:prompt是列表项的标题. 一    列表项数据: 实际运用当中,很多下拉列表项的数据实际是可知的,可以放在xml资源文件中.这时,开发者可以通过xml属性进行指定数据. 除了资源文件之外,开发者还能够使用适配器适配数据源.(适配器:

随机推荐