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

  • Post author:
  • Post category:vue


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



版权声明:本文为qq_38832375原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。