使用vue解決複雜邏輯

虛光發表於2017-12-14

一,動態樹形結構渲染

原型圖

使用vue解決複雜邏輯

問題

  1. 後臺需要提供提供怎樣的的資料結構
  2. 頁面渲染如何實現
  3. 如何拿到輸入框的值

解決思路

  1. 每一條資料需要提供第一個select的options選項;後面的文字框需要輸入型別;切換為區間輸入的時候資料格式的切換,每條資料的唯一name屬性。
  2. 封裝成元件,通過傳入的optios渲染第一個select,根據傳入的type型別,使用v-if渲染文字輸入框。
  3. 通過父元件v-for遍歷得到的值通過props傳個元件渲染,然後子元件通過在watch事件中通過emit將值返還給父元件,父元件通過eval方法,將name屬性宣告唯一物件和子元件相對應。

程式碼片段

父元件
<template>
<div style="border-bottom: 1px #d1dbe5 solid;padding-bottom: 1rem;margin-bottom:1rem">基本屬性</div>
    <typeElement v-for="a in getDataP.base_ids" :message="a" :detali="getDataP.basic_options" :onlyreaderlock="onlyreaderlock"  @fuzhi="fuzhifun1"></typeElement> 
<template>
<script>
import typeElement from "./element.vue"
export default {
data(){
    return {
        ensureP:{
            basic_options:{}
        }
    }
},
    created(){
        <!--獲取後臺資料-->
        <!--對後臺資料進行分割,排序,結構化-->
    },
    method:{
    fuzhifun1(e){
            eval("this.ensureP.basic_options."+e.name+"=e")
        },
    },
}
</script>
複製程式碼
子元件
<template>
<el-row>
 <el-col :span="3">{{message.rulename}}</el-col>
 <el-col :span="4">
          <el-select v-model="selectP" placeholder="請選擇" size="mini" :disabled="onlyreaderlock">
            <el-option
              v-for="item in option"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              >
            </el-option>
           </el-select>
 </el-col>
 <el-col :span="12">
 <!--待更新-->
 </el-col>
</el-row>
</template>
<script >
export default {
props:["message","detali","onlyreaderlock"],
 data() {
        let self = this;
        return {
          cityOptions : ['上海', '北京', '廣州', '深圳'],
          checkList:[],
            pickerOptions0: {
          disabledDate(time) {
            return time.getTime() < Date.now() - 8.64e7;
          }
        },
            showOK:true,//確保後天傳的東西不是空,如果為空就隱藏
            selectP:"",
            option:[],
            inputP:[],
            ppp:{flag:"",val:""},
           
        }
    },
created(){
    <!--對傳入的資料處理 判斷-->
},
watch: {
        "selectP":function(){ 
            this.ppp.name=this.message.custom_field
            this.ppp.flag=this.selectP
            this.$emit("fuzhi",this.ppp)
        },
        "inputP":function(){
            this.ppp.name=this.message.custom_field
            this.ppp.val=this.inputP
             this.$emit("fuzhi",this.ppp)
        }
       
    },
}
</script>
複製程式碼

二,遞迴樹

原型圖

使用vue解決複雜邏輯
能夠動態改變結構樹,增、刪、隱藏、展示。

問題

  1. 新增事件,新增的物件是動態的,如何動態繫結
  2. 結構是無限的,需要怎麼實現。

解決思路

  1. vue子父元件間的傳值實際是同一塊記憶體地址,因此在子元件內,是可以改變父元件的值(雖然官方並不提倡這種雙向資料流),父元件a.b物件通過props傳個子元件,子元件對b物件進行修改,父元件的a.b物件也會改變
  2. 可以使用遞迴的思想,當傳入的物件,有子屬性的時候,可以繼續遞迴使用自身(需要宣告name屬性)

程式碼片段

父元件
<template>
  <div class="hello">
    <h1 class="iconfont  icon-smile"> 遞迴樹</h1>
    <ul id="demo">
      <item class="item" :model="treeData">
      </item>
    </ul>
  </div>
</template>
<script>
import item from './cccc.vue'
export default {
  created() {

  },
  methods: {
  },
  components: { item },
  data() {
    return {
      b: "",
      treeData: {
        name: '蜂投網',
        children: [
          { name: '行政' },
          { name: '人事' },
          {
            name: '技術中心',
            children: [{
                name: '李工',
                children: [
                  { name: 'PHP組' ,
                    children:[
                    {name:'代綺'},
                    {name:'姚美美'}]},
                  { name: 'js組',
                   children:[
                   {name:"碩哥"},{name:"唐老師"},{name:'胖子'}]}
                ]
              },
              { name: '譚工' },
              { name: '龍工' },
              
            ]
          }
        ]
      }
    }
  }
}

</script>
複製程式碼

程式碼片段

子元件
<template>
  <div class="hello">
   <li>
    <div
      :class="{bold: isFolder}"
       @click="toggle"
       @dblclick="changeType"> <!-- 由於載入了fasticlick外掛,雙擊用不了 -->
      <img src="../../assets/arrow-right.png"  v-if="isFolder" style="width: 1rem;transition: transform 0.5s" :style="{transform: ttt } ">
         {{model.name}}
    </div>
    <ul v-show="open" v-if="isFolder">
      <item
        class="item"
        v-for="model in model.children"
        :model="model">
      </item>
      <li class="add" @click="addChild">+</li>
    </ul>
  </li>
  </div>
</template>
<script>
export default {
  name: 'item',
 props: {
    model: Object
  },
  data: function () {
    return {
      open: false,
      ttt:'rotate(0deg)'
    }
  },
  computed: {
    isFolder: function () {
      return this.model.children &&
        this.model.children.length
    }
  },
  methods: {
    toggle: function () {
      if (this.isFolder) {
        if(this.ttt=="rotate(90deg)"){
        this.ttt='rotate(0deg)'
      }else{
        this.ttt='rotate(90deg)'
      }
      setTimeout(()=>{this.open = !this.open},50)
      }
    },
    changeType: function () {
      if (!this.isFolder) {
         console.log("db")
        this.$set(this.model, 'children', [])
        this.addChild()
        this.open = true
      }
    },
    addChild: function () {
      let a =prompt("請輸入你的姓名","姓名")
      if(a){
      this.model.children.push({
        name: a
      })}
    }
  }
}
</script>
複製程式碼

相關文章