各種搞了好幾天了一直出問題,請(qǐng)大神給個(gè)思路,感覺是自己對(duì)數(shù)組,數(shù)據(jù)操作的時(shí)候問題
添加運(yùn)費(fèi)模板,用戶選擇地區(qū)后該地區(qū)不可選或者刪除,當(dāng)用戶編輯的時(shí)候數(shù)據(jù)回顯
把選過的id放到一個(gè)數(shù)組disabled中并存到vuex中,然后再次編輯的時(shí)候?qū)⒕庉嫷捻?xiàng)從disabled中刪除
但是左側(cè)數(shù)據(jù)只初始化一次,再次編輯操作的時(shí)候數(shù)據(jù)會(huì)相互影響
數(shù)據(jù)結(jié)構(gòu)
{"name":",模板",
"valuation_type":"1",
"valuation_rules":
[{"regions":[
{"id":"13","title":"河北省","pid":"0","open":false},
{"id":"1301","title":"石家莊市","pid":"13"}],
"first_amount":1,
"first_fee":"0.00",
"additional_amount":"0",
"additional_fee":"0.00"
}.{"regions":[
{"id":"11","title":"北京市","pid":"0","open":false},
{"id":"1101","title":"市轄區(qū)","pid":"11"}
"first_amount":1,
"first_fee":"0.00",
"additional_amount":"0",
"additional_fee":"0.00"
}]
}
調(diào)用組件
<div class="app-container">
<div class="content">
<el-form :model="freForm" status-icon :rules="freRules" ref="freForm" label-width="100px" class="fre-form" size="mini">
<el-form-item label="模板名稱" prop="name">
<el-input type="text" v-model="freForm.name" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="計(jì)費(fèi)方式" prop="valuation_type">
<el-radio-group v-model="freForm.valuation_type">
<el-radio :label="2">按件數(shù)</el-radio>
<el-radio :label="3">按重量</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="配送區(qū)域" prop="checkPass">
<table class="fre-table sui-table table-bordered " style="width:900px">
<thead>
<tr>
<th class="center">可配送區(qū)域</th>
<th class="center">首件(個(gè))</th>
<th class="center">運(yùn)費(fèi)(元)</th>
<th class="center">續(xù)件(個(gè))</th>
<th class="center">續(xù)費(fèi)(元)</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in freForm.valuation_rules" :key="index">
<td class="left-td">
<span v-for="area in item.regions" :key="area.id" class="area-title" :class="{'strong':area.pid==0}"> {{area.title}} </span>
<el-button type="text" size="small" @click="editArea(index)">編輯</el-button>
<el-button type="text" size="small">刪除</el-button>
</td>
<td class="center">
<el-input type="text" size="mini" v-model="item.first_amount" auto-complete="off"></el-input>
</td>
<td class="center">
<el-input type="text" size="mini" v-model="item.first_fee" auto-complete="off"></el-input>
</td>
<td class="center">
<el-input type="text" size="mini" v-model="item.additional_amount" auto-complete="off"></el-input>
</td>
<td class="center">
<el-input type="text" size="mini" v-model="item.additional_fee" auto-complete="off"></el-input>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<el-button type="text" size="small" @click="addArea">指定可配送區(qū)域和運(yùn)費(fèi)</el-button>
</td>
</tr>
</tfoot>
</table>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('freForm')">保存</el-button>
<el-button @click="resetForm('freForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
<!--address dialog-->
<el-dialog :visible.sync="dialogVisible" width="630px" center>
<synctree ref="synctree" v-model="finalData"></synctree>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="submitArea">保 存</el-button>
</span>
</el-dialog>
<!--address dialog-->
</div>
<script>
import Synctree from '@/components/Synctree'
import originData from '@/components/Synctree/data' //地址數(shù)據(jù)
export default {
components: {
Synctree
},
data() {
return {
dialogVisible: false, //顯示彈出
originData: originData, //地址數(shù)據(jù)
freForm: { // 數(shù)據(jù)
valuation_rules: [],
name: '',
valuation_type: 2
},
}
}
},
methods: {
// 點(diǎn)擊添加
addArea() {
this.dialogVisible = true
},
// 點(diǎn)擊保存
submitArea() {
// 如果編輯地址
if (this.editIndex !== null) {
// 更新編輯數(shù)據(jù)
this.freForm.valuation_rules[this.editIndex].regions = this.finalData
// 編輯id重置
this.editIndex = null
} else {
const temp = {
regions: this.finalData,
first_amount: 1,
first_fee: '0.00',
additional_amount: '0',
additional_fee: '0.00'
}
// 添加一行數(shù)據(jù)
if (this.finalData.length > 0) {
this.freForm.valuation_rules.push(temp)
}
}
// 清空選擇地址數(shù)據(jù),為下次添加準(zhǔn)備
this.finalData = []
this.dialogVisible = false
},
// 編輯選擇配送區(qū)域
editArea(index) {
this.editIndex = index
// 獲取編輯數(shù)據(jù)重新復(fù)制
this.finalData = this.freForm.valuation_rules[index].regions
this.dialogVisible = true
},
init() {
if (this.templateId) {
const formData = {
templateId: this.templateId
}
getFreightDetail(formData).then(res => {
this.freForm = res.data.supplierFreightDetails
console.log(this.freForm)
})
}
}
},
子組件
<template>
<div class="v-component-sync-tree">
<div class="origin-tree tree-item">
<div class="tree-header">選擇可配送區(qū)域</div>
<div class="tree-body">
<el-tree :data="originTree" show-checkbox ref="originTree" node-key="id" :props="defaultProps" @check-change="getOriginKeys"></el-tree>
</div>
</div>
<div class="tree-cut">
<i class="ivu-icon ivu-icon-ios-arrow-right"></i>
<el-icon class="el-icon-arrow-right"></el-icon>
</div>
<div class="final-tree tree-item">
<div class="tree-header">配送區(qū)域</div>
<div class="tree-body">
<div class="body-main">
<ul>
<li v-for="(item,index) of finalTree" :key="item.id">
<span class="item-text item-expand" @click.stop="toggleOpen(item.id)"> <el-icon class="item-icon" :class="item.open ?'el-icon-caret-bottom':'el-icon-caret-right'"></el-icon>{{ item.title }}</span>
<!--<span class="item-edit" @click.stop="popEditModal(item.id, item.title)">
<el-icon class="el-icon-edit"></el-icon>
</span>-->
<span class="item-del" @click.stop="popDelModal(item.id, item.pid)">
<el-icon class="el-icon-delete"></el-icon>
</span>
<ul class="tree-child" style="margin-left:20px;" :class="{'tree-show': item.open}">
<li v-for="child of item.children" :key="child.id">
<span class="item-text">{{ child.title }}</span>
<!--<span class="item-edit" @click.stop="popEditModal(child.id, child.title)">
<el-icon class="el-icon-edit"></el-icon>
</span>-->
<span class="item-del" @click.stop="popDelModal(child.id, child.pid)">
<el-icon class="el-icon-delete"></el-icon>
</span>
</li>
</ul>
</li>
</ul>
</div>
<div class="edit-mask" v-if="editShow">
<div class="edit-wrapper">
<el-input class="edit-input" v-model="editText"></el-input>
<div class="edit-opra-wrapper">
<el-button-group>
<el-button class="edit-cancel" type="default" @click="editCancel">
取消
</el-button>
<el-button class="edit-ok" type="primary" @click="editOk">
確認(rèn)
</el-button>
</el-button-group>
</div>
</div>
</div>
<div class="del-mask" v-if="delShow">
<div class="del-wrapper">
<div class="del-text">
<el-icon class="el-icon-warning"></el-icon>
是否刪除
</div>
<div class="del-opra-wrapper">
<el-button-group>
<el-button class="del-cancel" @click="delCancel">
取消
</el-button>
<el-button class="del-ok" type="primary" @click="delOk">
確認(rèn)
</el-button>
</el-button-group>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Tool from './tool'
require('./vue-component-sync-tree.scss')
import {
mapGetters
} from 'vuex'
export default {
name: 'synctree',
model: {
prop: 'finalList',
event: 'change'
},
props: {
// 目的列表數(shù)據(jù)
finalList: {
type: Array,
default: () => []
},
// 源列表數(shù)據(jù)
data: {
type: Array,
default: () => []
}
},
data() {
return {
delShow: false, // 刪除確認(rèn)彈出層控制器
delId: '', // 刪除彈出層 => id
delPid: '', // 刪除彈出層 => pid
editShow: false, // 修改彈出層控制器
editText: '', // 修改彈出層 => text
editId: '', // 修改彈出層 => id
originTree: [], // 源列表Tree
originKeys: [], // 源列表keys
defaultProps: {
children: 'children',
label: 'title'
},
showChild: false,
tempList: [],
delKeys: [],
ableKeys: []
}
},
computed: {
// 源列表數(shù)據(jù)
originList() {
return this.data;
},
// 目的列表Tree
finalTree() {
this.finalList.forEach(item => {
if (item.open === undefined && Number(item.pid) === 0) {
this.$set(item, 'open', false)
}
})
return Tool.arrToTree(this.finalList)
},
// 目的列表keys
finalKeys() {
return this.finalList.map(item => item.id)
},
// 根據(jù)源列表選擇的keys生成的目的列表的keys
originToFinalKeys() {
const parentKeys = []
this.originList.forEach(item => {
if (this.originKeys.includes(item.id) && Number(item.pid) !== 0) {
parentKeys.push(item.pid)
}
})
return this.unique([...parentKeys, ...this.originKeys])
}
},
created() {
// 初始化源列表Tree
this.initOriginTree()
},
mounted() {
// 初始化源列表點(diǎn)選
this.initOriginChecked()
// this.initOriginDisChecked()
},
methods: {
// 彈出刪除彈出層
popDelModal(id, pid) {
this.delId = id
this.delPid = pid
this.delShow = true
},
getFinalKeys() {
// console.log(this.originToFinalKeys)
},
// 刪除彈出層確認(rèn)
delOk() {
const keys = []
keys.push(this.delId)
if (Number(this.delPid) === 0) {
// 如果刪除的key是一級(jí)分類
this.finalTree.forEach(item => {
if (item.id === this.delId) {
item.children.forEach(child => {
keys.push(child.id)
})
}
})
} else {
// 如果刪除的key是二級(jí)分類
keys.push(this.delPid)
}
// 刪除
keys.forEach(key => {
this.originKeys = this.removeByValue(this.originKeys, key)
})
// 同步到左側(cè)
this.$refs.originTree.setCheckedKeys(this.originKeys)
this.delCancel()
},
// 刪除彈出層取消
delCancel() {
this.delShow = false
this.delId = ''
this.delPid = ''
},
// 初始化源列表Tree
initOriginTree() {
this.originTree = Tool.arrToTree(this.originList)
},
// 初始化源列表點(diǎn)選
initOriginChecked() {
const checkedKeys = []
this.finalList.forEach(item => {
if (Number(item.pid) !== 0) {
checkedKeys.push(item.id)
} else {
// 判斷是否只有一級(jí)分類
if (!this.finalList.map(i => i.pid).includes(item.id)) {
checkedKeys.push(item.id)
}
}
})
this.$refs.originTree.setCheckedKeys(checkedKeys)
},
// 獲取源列表keys
getOriginKeys(data, checked, indeterminate) {
// console.log(data, checked, indeterminate)
// if (checked === true) {
// this.disabledKeys.push(data.id)
// } else {
// this.disabledKeys.splice(this.disabledKeys.findIndex(item => item === data.id), 1)
// }
this.originKeys = this.$refs.originTree.getCheckedKeys()
// 點(diǎn)選源列表時(shí)關(guān)閉目的列表編輯彈出層
// this.editCancel()
// 點(diǎn)選源列表時(shí)關(guān)閉目的列表刪除彈出層
// this.delCancel()
},
// 在 target 數(shù)組中取出 arg 數(shù)組中沒有的值組成數(shù)組返回
findOut(target, arg) {
return target.filter(v => !arg.includes(v))
},
// 刪除數(shù)組中的某個(gè)值
removeByValue(target, arg) {
const index = target.indexOf(arg)
if (index !== -1) {
target.splice(index, 1)
}
return target
},
// 數(shù)組去重
unique(arr) {
const newArr = []
arr.forEach(item => {
if (!newArr.includes(item)) {
newArr.push(item)
}
})
return newArr
},
// 展開
toggleOpen(id) {
// 修改的是finalList 不是 finalTree,所以要通過id去獲取而非index
this.finalList.forEach(item => {
if (item.id === id) {
this.$set(item, 'open', !item.open)
}
})
}
},
watch: {
// 根據(jù)源列表的操作,同步目的列表
originToFinalKeys() {
// 點(diǎn)選源列表生成的目的列表中存在,但當(dāng)前目的列表中沒有
this.findOut(this.originToFinalKeys, this.finalKeys).forEach(key => {
this.originList.forEach(item => {
if (item.id === key) {
this.finalList.push(Tool.deepClone(item))
}
})
})
// 源列表取消選中,去除目的列表中的item
this.findOut(this.finalKeys, this.originToFinalKeys).forEach(key => {
this.finalList.forEach(item => {
if (item.id === key) {
this.finalList = this.removeByValue(this.finalList, item)
}
})
})
},
finalList() {
// 初始化左側(cè)點(diǎn)選
this.initOriginChecked()
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.item-icon {
font-size: 16px;
vertical-align: middle;
color: #c0c4cc;
}
.tree-child {
display: none;
}
.tree-show {
display: block!important;
}
</style>
選過的數(shù)據(jù)不可選,選過的數(shù)據(jù)不可選可以時(shí)間,但是編輯的時(shí)候回顯出現(xiàn)問題
自己解決了,關(guān)鍵是重新初始化了數(shù)據(jù),每次彈出框的時(shí)候,將數(shù)據(jù)拷貝一份,傳入組件,
每次重新渲染組件的方式就是用v-if
<synctree v-if="reloadTree" :data.sync="tempList" v-model="finalData"></synctree>
每次點(diǎn)擊的時(shí)候重新渲染,不過這樣有個(gè)弊端,數(shù)據(jù)多了性能差,希望大家能有其他的解決辦法
handleAdd() {
this.reloadTree = true
// 拷貝數(shù)據(jù)
this.tempList = deepClone(this.originData)
// 修改不可選數(shù)據(jù)disabled屬性
this.disabledKeys.forEach(key => {
this.tempList.forEach(item => {
if (key === item.id) {
this.$set(item, 'disabled', true)
}
})
})
// 顯示彈框
this.dialogVisible = true
},
閑了會(huì)去整理一個(gè)小的demo出來,歡迎去我的github圍觀
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問,美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。