一,动态树形结构渲染
原型图
问题
- 后台须要提供提供怎样的的数据结构
- 页面渲染如何实现
- 如何拿到输入框的值
解决思路
- 每一条数据须要提供第一个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>
复制代码