阅读 2869

使用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>
复制代码

二,递归树

原型图

能够动态改变结构树,增、删、隐藏、展示。

问题

  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>
复制代码
文章分类
前端
文章标签