一,動態樹形結構渲染
原型圖
問題
- 後臺需要提供提供怎樣的的資料結構
- 頁面渲染如何實現
- 如何拿到輸入框的值
解決思路
- 每一條資料需要提供第一個select的options選項;後面的文字框需要輸入型別;切換為區間輸入的時候資料格式的切換,每條資料的唯一name屬性。
- 封裝成元件,通過傳入的optios渲染第一個select,根據傳入的type型別,使用v-if渲染文字輸入框。
- 通過父元件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子父元件間的傳值實際是同一塊記憶體地址,因此在子元件內,是可以改變父元件的值(雖然官方並不提倡這種雙向資料流),父元件a.b物件通過props傳個子元件,子元件對b物件進行修改,父元件的a.b物件也會改變
- 可以使用遞迴的思想,當傳入的物件,有子屬性的時候,可以繼續遞迴使用自身(需要宣告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>
複製程式碼