您好,登錄后才能下訂單哦!
vue 公共列表選擇組件實(shí)現(xiàn)引用Vant-UI樣式的方法?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
特性:
1、支持動(dòng)態(tài)、靜態(tài)數(shù)據(jù)源。
2、支持分頁(yè)加載。
3、支持模糊搜索。
4、支持單選、多選。
組件源碼:
<template> <div class="gn-PubSelect"> <van-action-sheet v-model="inShow"> <div class="gn-PubSelect-main" :> <van-search class="gn-search" placeholder="請(qǐng)輸入搜索關(guān)鍵詞" v-model="condition" show-action> <van-button slot="action" size="small" type="primary" @click="inShow = false">確認(rèn)</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> <!--復(fù)選控件--> <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:'', //查詢關(guān)鍵字 checkboxResult:[], //復(fù)選框 選中結(jié)果 radioResult:{}, //單選框 選中結(jié)果 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){ /*條件改變時(shí)更新選擇列表*/ this.filterList = []; this.page = 1; this.filterSelectList(); }, inShow(newVal,oldVal){ //子組件向父組件傳值 this.$emit('update:show',newVal); //關(guān)閉選擇控件時(shí)自動(dòng)帶回選中的值 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{ /*動(dòng)態(tài)加載數(shù)據(jù)*/ this.loading = true; postAction(this.url,{PageSize:10,Page:this.page++,Condition:this.condition}).then((result) => { // 加載狀態(tài)結(jié)束 this.loading = false; // 數(shù)據(jù)全部加載完成 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(){ /*更新選中結(jié)果*/ if(this.type == 'radio'){ this.$emit('update:result',this.radioResult); }else{ this.$emit('update:result',this.checkboxResult); } }, initCheck(){ /*檢驗(yàn)參數(shù)有效性*/ if(this.isLink){ if(this.url == undefined || this.url == null || this.url == ""){ throw new Error("[url]參數(shù)必填!"); } }else{ if(this.selectList == undefined || this.selectList == null ){ throw new Error("[selectList]參數(shù)必填!"); } } } } }; </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>
組件中的【動(dòng)態(tài)加載數(shù)據(jù)】是經(jīng)過封裝的請(qǐng)數(shù)據(jù),需要改為axios請(qǐng)求。
數(shù)據(jù)源:
1、靜態(tài)數(shù)據(jù)源格式
"list": [ { "Id": "", "Number": "", "Name": "" } ],
2、動(dòng)態(tài)數(shù)據(jù)源格式
{ "Success": true, "Data": [ { "Id": "", "Number": "", "Name": "" } ], "Page": 1, "PageSize": 3 }
使用方式
1、在需要使用選擇組件的地方引入組件
import PubSelect from '@/base/PubSelect.vue'
2、靜態(tài)數(shù)據(jù)源使用方式
<pub-select id="pub-select" type="radio" :show.sync="showSelectProject" :selectList="list" :result.sync="form.project" />
3、動(dòng)態(tài)數(shù)據(jù)源使用方式
<pub-select id="pub-select" type="checkbox" :show.sync="showSelectProject" :result.sync="FCourse" url="/assetCtl/projectList" isLink />
補(bǔ)充知識(shí):van-picker級(jí)聯(lián)選擇(自定義字段顯示)
前言
Vant之van-picker級(jí)聯(lián)選擇
1、將自定義平鋪結(jié)構(gòu)轉(zhuǎn)化為層級(jí)結(jié)構(gòu)數(shù)據(jù)
2、動(dòng)態(tài)$set()給每一條數(shù)據(jù)對(duì)象添加text屬性用于展示
數(shù)據(jù)處理
原始數(shù)據(jù)
[ {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'} ]
轉(zhuǎn)化后數(shù)據(jù)
[ { 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'} ] }, ]
轉(zhuǎn)化函數(shù)tile2nest
// 平鋪結(jié)構(gòu)轉(zhuǎn)嵌套結(jié)構(gòu) tile2nest(array, key, pKey, childrenKey) { if (!array || array.constructor !== Array) { return array; } // 復(fù)制一份,避免修改原始數(shù)組 let ary = [...array]; key = key || "id"; // 平鋪數(shù)據(jù)主鍵 pKey = pKey || "parentId";//平鋪數(shù)據(jù)父節(jié)點(diǎn)數(shù)據(jù) childrenKey = childrenKey || "children";//子節(jié)點(diǎn)名稱 // 定義一個(gè)待移除數(shù)組 let ary2remove = []; ary.map(item => { //動(dòng)態(tài)添加屬性text以適應(yīng)van-picker組件默認(rèn)顯示text字段 this.$set(item,'text',item.name); if (item[key] !== item[pKey]) { // 找父節(jié)點(diǎn) let p = ary.filter(c => c[key] === item[pKey]); if (p && p.length == 1) { p[0].children = p[0].children || []; // 將子節(jié)點(diǎn)放到父節(jié)點(diǎn)中 p[0].children.push(item); ary2remove.push(item[key]); } } }); // 遍歷移除待刪除對(duì)象 ary2remove.map(item => { ary = ary.filter(c => c[key] !== item); }); //返回轉(zhuǎn)化后的層次結(jié)構(gòu)數(shù)據(jù) return ary; }
使用組件
<van-field readonly clickable placeholder="一二級(jí)分類" :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 = ""; // 呈現(xiàn)頁(yè)面顯示 /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 },
效果
選擇效果
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。