在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ vue element ui tree 選擇數(shù)據(jù)后隱藏,編輯時(shí)顯示

vue element ui tree 選擇數(shù)據(jù)后隱藏,編輯時(shí)顯示

各種搞了好幾天了一直出問題,請(qǐng)大神給個(gè)思路,感覺是自己對(duì)數(shù)組,數(shù)據(jù)操作的時(shí)候問題

問題描述

添加運(yùn)費(fèi)模板,用戶選擇地區(qū)后該地區(qū)不可選或者刪除,當(dāng)用戶編輯的時(shí)候數(shù)據(jù)回顯

問題出現(xiàn)的環(huán)境背景及自己嘗試過哪些方法

把選過的id放到一個(gè)數(shù)組disabled中并存到vuex中,然后再次編輯的時(shí)候?qū)⒕庉嫷捻?xiàng)從disabled中刪除
但是左側(cè)數(shù)據(jù)只初始化一次,再次編輯操作的時(shí)候數(shù)據(jù)會(huì)相互影響

相關(guān)代碼

clipboard.png

數(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>

你期待的結(jié)果是什么?實(shí)際看到的錯(cuò)誤信息又是什么?

選過的數(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圍觀
clipboard.png

2017年9月18日 01:23