日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

淺談Vue使用Cascader級聯選擇器數據回顯中的坑

瀏覽:381日期:2023-10-14 09:19:42

業務場景

由于項目需求,需要對相關類目進行多選,類目數據量又特別大,業務邏輯是使用懶加載方式加載各級類目數據,編輯時回顯用戶選擇的類目。

問題描述

使用Cascader級聯選擇器過程中主要存在的應用問題如下:

1、由于在未渲染節點數據的情況下編輯時無法找到對應的類目數據導致無法回顯,如何自動全部加載已選擇類目的相關節點數據;

2、提前加載數據后,點擊相應父級節點出現數據重復等;

3、使用多個數據源相同的級聯選擇器,產生只能成功響應一個加載子級節點數據;

4、Vue中級聯選擇器相應數據完成加載,依然無法回顯。

解決思路

Cascader級聯選擇器在需要回顯的節點數據都存在的情況下,方可完成回顯,首先想到的是把選中節點相關的數據全部獲取到即可,遍歷已選擇的節點數據,遍歷加載相對應的數據。(如果多個級聯選擇器使用同一個數據源,使用深拷貝將數據分開,避免產生影響)

由于是級聯的數據懶加載,需要每一級相應的節點數據加載完進行下一步,故使用ES6中的Promise,將子級節點數據加載封裝成一個Promise,待Promise執行完成,對列表數據遍歷獲取完成后返回即可。

getChildrenList (fid, level = 0) { return new Promise((resolve, reject) => { API.getCategory({ fid: fid, level: level }).then( res => { if (res) { if (res.code === 0 && res.result) { resolve(res.result) } } } ) }) },let twolist = this.getChildrenList(codeArr[0], 1)let thirdlist = this.getChildrenList(codeArr[1], 2)Promise.all([twolist, thirdlist]).then((data) => { ...})

Vue2的雙向數據綁定使用ES2015中的Object.defineProperty(),該方法無法檢測到Array中的深層數據變化,需要使用$set來觸發列表數據的更新。

一個三級級聯選擇器,首先獲取全部一級類目,二級類目和三級類目采用懶加載,獲取數據的步驟如下:

1、獲取全部一級類目;

2、由于使用異步數據加載,使用Promise進行數據請求;

3、根據已選擇的類目獲取相關聯的二級類目和三級類目;

4、數據請求完成,使用$set觸發列表數據更新,在$nextTick中完成數據你回顯。

相關代碼

<template> <div> <el-cascader placeholder='請選擇所屬類目' :options='categoryList' :show-all-levels='false' v-model='category' collapse-tags :props='{ multiple: true, value: ’code’, label: ’name’, children: ’children’, ...props, }' /> <el-cascader placeholder='請選擇所屬類目' :options='secondCategoryList' :show-all-levels='false' v-model='secondCategory' collapse-tags :props='{ multiple: true, value: ’code’, label: ’name’, children: ’children’, ...props, }' /> </div></template> <script>export default { data () { return { categoryList: [], category: [], secondCategoryList: [], secondCategory: [], props: { lazy: true, // checkStrictly: true, // 父子級節點關聯 async lazyLoad (node, reso) { const { level, data } = node if (data && data.children && data.children.length !== 0) { return reso(node) } if (data && data.leaf) { return reso([]) } const lv3Code = data ? data.code : null setTimeout(() => { lv3Code && API.getCategory({ fid: lv3Code, level: level }).then( res => { if (res) { if (res.code === 0 && res.result) { const nodes = res.result.map(item => ({ leaf: level === 2, ...item, children: [] })) data.children = nodes reso(nodes) } else { reso([]) } } } ) }, 500) } } } }, mounted () { this.getCategory() this.initData() }, methods: { initData () { let _that = this 異步獲取編輯數據。。。 .then(result => { // 此處僅處理result中firstCategory和secondCategory均不為空的情況 let firstTemp = _that.getCategoryListFormat(result.firstCategory, _that.categoryList) let secondTemp = _that.getCategoryListFormat(result.secondCategory, _that.secondCategoryList) let promiseArr = [firstTemp, secondTemp].filter(_ => _) Promise.all(promiseArr).then((formatRes) => { // 觸發列表數據響應 this.$set(_that.categoryList, formatRes[0].tragetCategoryList) this.$set(_that.secondCategoryList, formatRes[1].tragetCategoryList) _that.$nextTick(() => { // 數據加載完成后,在下一次循環中回顯 _that.category = formatRes[0].category _that.secondCategory = formatRes[1].category }) }) }) }, getCategoryListFormat (categorySelectList, tragetCategoryList) { return new Promise((resolve, reject) => { const category = [] let flag = 0 let counter = categorySelectList.length categorySelectList.forEach(v => { // 遍歷已選擇節點數據 const oneNode = v const twoNode = v.children const threeNode = v.children.children const codeArr = [oneNode.code, twoNode.code, threeNode.code] category.push(codeArr) twoNode.children = twoNode.children ? twoNode.children : [] let twolist = this.getChildrenList(codeArr[0], 1) let thirdlist = this.getChildrenList(codeArr[1], 2) Promise.all([twolist, thirdlist]).then((data) => { let twochildren = data[0] let threechildren = data[1] threechildren = threechildren.map(item => ({ leaf: true, ...item })) // 三級節點設置成葉子節點 twoNode.children = threechildren tragetCategoryList.forEach(w => { // 遍歷列表添加相應節點數據 if (w.code === oneNode.code) { if (!w.children) { w.children = twochildren } w.children.forEach(item => { if (item.code === twoNode.code) { item.children = twoNode.children } }) } }) flag++ if (flag === counter) { resolve({ tragetCategoryList, category }) } }) }) }) }, getChildrenList (fid, level = 0) { return new Promise((resolve, reject) => { API.getCategory({ fid: fid, level: level }).then( res => { if (res) { if (res.code === 0 && res.result) { resolve(res.result) } } } ) }) }, getCategory(fid = 0, level = 0) { API.getCategory({ fid: fid, level: level }) .then( res => { if (res) { if (res.code == 0 && res.result) { this.categoryList = this.deepClone(res.result); } } } ) }, deepClone (source) { // 深拷貝 if (!source && typeof source !== ’object’) { throw new Error(’error arguments’, ’shallowClone’) } const targetObj = source.constructor === Array ? [] : {} Object.keys(source).forEach(keys => { if (source[keys] && typeof source[keys] === ’object’) { targetObj[keys] = source[keys].constructor === Array ? [] : {} targetObj[keys] = deepClone(source[keys]) } else { targetObj[keys] = source[keys] } }) return targetObj } }}</script> <style lang='less' scoped> </style>

補充知識:Ant Design 級聯選擇的一種寫法

簡單記錄類似省、市、區或品牌、車系、車型等多級結構,級聯選擇添加并展示的一種寫法:

import React from ’react’;import {Button, Form, message, Row, Tag,Select,Col} from ’antd’;import request from '../../../../utils/request';const FormItem = Form.Item;const Option = Select.Option; class CarSeriesCascader extends React.Component { constructor(props) { super(props); this.state = { defaultBrandList:[], selectedCarModelList: props.carModelList ? props.carModelList : [], brandCode:null, carModelList:[], carId:null, modelCode:null, modelName:null } } componentDidMount() { let promise = request(`/car/getBrandList`); promise.then(result =>{ if(result != null){ this.setState({ defaultBrandList:result }); }else{ message.error('獲取品牌數據失敗'); } }).catch(err => { message.error('獲取品牌數據失敗'); }); // this.setState({ // selectedCarModelList:(this.props.carModelList ? this.props.carModelList : []) // }); this.handleChange(this.state.selectedCarModelList); } getLimitList = (selectedCarModelList) => { let limitList = selectedCarModelList.map((carModel,index) => { let limitItem = {}; limitItem.modelName = carModel.modelName; limitItem.modelCode = carModel.modelCode; limitItem.carId = carModel.carId; return limitItem; }); return limitList; } addCarModel = () => { let addCarModel = {}; let selectedCarModelList = this.state.selectedCarModelList; // 選中車型號 if (this.state.carId !== null) { // 檢查車型是否已選中 for (let index = this.state.selectedCarModelList.length - 1; index >= 0; index--) { let carModel = this.state.selectedCarModelList[index]; if (carModel.carId == this.state.carId) { message.error('車型已在已選車型中'); return; } } addCarModel.carId = this.state.carId; addCarModel.modelCode = this.state.modelCode; addCarModel.modelName = this.state.modelName; selectedCarModelList.push(addCarModel); } else { return; } this.handleChange(selectedCarModelList); this.setState({ selectedCarModelList }); } handleChange = (selectedCarModelList) => { if (this.props.onChange) { let limitList = this.getLimitList(selectedCarModelList); this.props.onChange(limitList); } } deleteTag = (limitCode) => { debugger let selectedCarModelList = this.state.selectedCarModelList; selectedCarModelList = selectedCarModelList.filter(carModel => !(carModel.modelCode === limitCode)); this.handleChange(selectedCarModelList); this.setState({selectedCarModelList}); } //品牌變化 brandChange = (brandName) => { this.state.defaultBrandList.map((item, index) => { if (item.brandName == brandName) { let promise = request(`/car/getModelList?brandCode=` + item.brandCode); promise.then(result =>{ if(result != null){ this.setState({ brandCode:item.brandCode, carModelList:result }); }else{ message.error('獲取車型數據失敗'); } }).catch(err => { message.error('獲取車型數據失敗:'); }); } }); } //車型變化 modelChange = (modelName) => { this.props.form.setFieldsValue({modelName: null}); let _this = this; this.state.carModelList.map((item, index) => { if (item.modelName == modelName) { console.log(item); this.setState({ modelCode : item.modelCode, carId : item.carId, modelName : item.modelName }); } }); } render() { const {getFieldDecorator} = this.props.form; //品牌名稱列表 let allBrandListOption = this.state.defaultBrandList != null ? this.state.defaultBrandList.map((item, index) => { return <Option value={item.brandName} key={index}>{item.brandName}</Option>; }) : null; //車型名稱列表 let allModelListOption = this.state.carModelList != null ? this.state.carModelList.map((item, index) => { return <Option value={item.modelName} key={index}>{item.modelName}</Option>; }) : null; const { closable=true, } = this.props; const existCarModel = []; const limitList = this.getLimitList(this.state.selectedCarModelList); for (let index = limitList.length - 1; index >= 0; index--) { let limitItem = limitList[index]; existCarModel.push(<Tag key={limitItem.modelCode} closable={closable} onClose={(e) => { e.preventDefault(); this.deleteTag(limitItem.modelCode); }} >{limitItem.modelName}</Tag>); } return ( <div> <Row> <FormItem > {getFieldDecorator(’brandName’, { rules: [{ message: ’請選擇品牌’ }], })( <Select placeholder='品牌' dropdownMatchSelectWidth={false} onChange={this.brandChange} style={{ marginRight: 10, width: 100 }}> <Option value={null}>選擇品牌</Option> {allBrandListOption} </Select> )} {getFieldDecorator(’modelName’, { rules: [{ message: ’請選擇車型’ }], })( <Select placeholder='車型' dropdownMatchSelectWidth={false} onChange={this.modelChange} style={{ marginRight: 10, width: 260 }}> <Option value={null}>選擇車型</Option> {allModelListOption} </Select> )} <Button type={'primary'} icon={'plus'} onClick={this.addCarModel}>添加車型</Button> </FormItem> </Row> <Row> {existCarModel} </Row> </div> ) }} export default Form.create()(CarSeriesCascader);

以上這篇淺談Vue使用Cascader級聯選擇器數據回顯中的坑就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: vue
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品一区二区三区的国产在线观看| 中文一区二区| 精品国产美女a久久9999| 日韩动漫一区| 日韩av字幕| 日韩有吗在线观看| 日韩久久99| 日韩av一二三| 国产精品视频首页| 麻豆免费精品视频| 久久伊人亚洲| 蜜臀久久精品| 黑人精品一区| 好看的av在线不卡观看| japanese国产精品| 国产视频一区欧美| 亚州精品视频| 日韩中文字幕一区二区三区| 亚洲资源网站| 国产精品777777在线播放 | 国产精品丝袜xxxxxxx| 亚洲专区欧美专区| 国产麻豆一区二区三区精品视频| 欧美国产不卡| 日韩欧美二区| aa国产精品| 国产午夜一区| 神马日本精品| 国产一区二区高清| 国产精品超碰| 国产精品97| 欧美激情aⅴ一区二区三区| 久久视频国产| 麻豆久久一区| 性色一区二区| 毛片在线网站| 日韩精品三级| 亚洲欧美日韩高清在线| 国产精品欧美一区二区三区不卡| 免费视频亚洲| 给我免费播放日韩视频| 亚洲午夜免费| 久久天堂精品| 日本一区二区中文字幕| www.com.cn成人| 国产日本精品| 蜜桃91丨九色丨蝌蚪91桃色| 日本一区二区免费高清| 亚洲香蕉视频| 欧美日韩亚洲在线观看| 欧美国产另类| 日韩成人av影视| 中文字幕免费精品| 制服诱惑一区二区| 999精品在线| 国产aⅴ精品一区二区三区久久| 亚洲无线观看| 午夜一区在线| 日韩视频网站在线观看| 免费观看亚洲天堂| 欧美视频精品全部免费观看| 视频一区视频二区中文| 欧美日韩精品一本二本三本| 欧美羞羞视频| 91精品一区二区三区综合| 成人日韩精品| 天堂日韩电影| 亚洲精品中文字幕乱码| 私拍精品福利视频在线一区| 视频一区中文| 红桃视频国产一区| 国产一区导航| 婷婷综合一区| 国产亚洲毛片在线| 中文字幕一区二区av| 日韩美女精品| 欧美激情视频一区二区三区在线播放| 国产精品宾馆| 亚洲精品国产嫩草在线观看 | 中文视频一区| 日韩一区二区三区高清在线观看| 91麻豆精品| 激情中国色综合| 亚洲午夜黄色| 免费观看在线综合| 国产精品一二| 欧美亚洲精品在线| 欧美精选视频一区二区| 狠狠干成人综合网| 欧美亚洲福利| 日韩另类视频| 日韩精品一二区| 国产精品白浆| 精品一区毛片| 国产欧美日韩精品高清二区综合区 | 国产在线不卡一区二区三区| 亚洲va久久久噜噜噜久久| 国产91精品对白在线播放| 国产视频网站一区二区三区| 国产精品手机在线播放| 97se亚洲| 国产精品日韩精品中文字幕| 视频在线在亚洲| 综合欧美精品| 日韩中文字幕亚洲一区二区va在线| 色在线视频观看| 99视频精品免费观看| 精品视频97| 亚洲天堂免费| 成人福利av| 免费人成网站在线观看欧美高清| 国产精品丝袜在线播放| 国产亚洲精品v| 亚洲精品成人一区| 日本一区二区高清不卡| 777久久精品| 免费一级片91| 妖精视频成人观看www| 久久九九国产| 国产aa精品| 久久99国产精品视频| 欧美一区二区三区久久| 美美哒免费高清在线观看视频一区二区| 国产精品久久观看| 久久精品亚洲| 日韩和欧美一区二区三区| 影音国产精品| 亚洲激情五月| 国产精品美女| 久久国产精品久久w女人spa| 狠狠色狠狠色综合日日tαg| 欧美91视频| 久久精品卡一| 尹人成人综合网| 亚洲欧美日韩精品一区二区| 美女久久久久| 好吊日精品视频| 视频一区二区三区入口| 午夜在线视频观看日韩17c| 欧美在线亚洲| 日韩精品久久久久久久电影99爱| 精品视频久久| 成人羞羞在线观看网站| 欧美一级精品| 99在线精品视频在线观看| 免费日本视频一区| 久久国产欧美日韩精品| 精品亚洲a∨一区二区三区18| 日本精品黄色| 亚洲欧美日韩国产| 日韩美女国产精品| 久久午夜影院| 日韩一区电影| 久久国产精品久久w女人spa| 亚洲区欧美区| 久久国际精品| 偷拍精品精品一区二区三区| 9国产精品视频| 国产精品午夜av| 国产精品av久久久久久麻豆网| 免费看日韩精品| 精品国产99| 综合国产视频| 日本蜜桃在线观看视频| 丝袜美腿一区二区三区| 久久精品一本| 亚洲一区导航| 中文字幕成在线观看| 亚洲欧美日本日韩| 精品在线网站观看| 偷拍欧美精品| 久久国产人妖系列| av不卡在线| 中文字幕在线免费观看视频| 日韩精品一区二区三区中文字幕| bbw在线视频| 国产毛片精品久久| 亚洲在线电影| 秋霞影视一区二区三区| 国产日产精品_国产精品毛片 | 最新国产精品| 久久激情中文| 91综合网人人| 日韩精品免费视频人成| 亚洲女同一区| 久久久久美女| 天堂√中文最新版在线| 国产极品久久久久久久久波多结野 | 中文字幕av一区二区三区四区| 久久精品国内一区二区三区水蜜桃| 欧美国产日本| 久久午夜影院| 动漫av一区| 牛牛精品成人免费视频| 视频一区二区三区入口| 视频一区国产视频| 亚洲小说春色综合另类电影| 综合一区二区三区| 亚洲精品成人一区| 日本不卡高清|