目录:1,固定结构,不同数据处理。2,路由导航。3,递归树
一,结构类似,不同类型渲染
分析:整个原型分为两部分(select+任意),因此第一想法是写一个组件(包含一个select+任意类型)。
输入:在父组件v-for循环渲染传入props(带入需要的输入类型)
输出:子组件的值要返回到父组件,通过$emit,事件发生在input或者change。
细节:当切换为区间的时候,传值的处理由string转为arry.
实现代码
子组件(这里使用了element-ui的栅格布局,根据传进的
message 根据这个渲染是那种输入形式
detali 已存在的选项值
onlyreaderlock 是否可以编辑
<template>
<div style="padding-left: 4rem;margin:1rem" v-if="showOK" >
<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">
<div v-if="message.inType=='text'">
<el-input size="mini" v-model="inputP" placeholder="请输入内容" :disabled="onlyreaderlock"></el-input>
</div>
<div v-else-if="message.inType=='textarea'">
<el-input size="mini" type="textarea" v-model="inputP" placeholder="请输入内容" :disabled="onlyreaderlock"></el-input>
</div>
<div v-else-if="message.inType=='select'">
<el-select v-model="inputP" placeholder="请选择" size="mini" :disabled="onlyreaderlock">
<el-option
v-for="item in message.TypeVal"
:key="item"
:label="item"
:value="item"
>
</el-option>
</el-select>
</div>
<div v-else-if="message.inType=='date'">
<el-date-picker
:disabled="onlyreaderlock"
v-model="inputP"
type="date"
placeholder="选择日期"
:picker-options="pickerOptions0">
</el-date-picker>
</div>
<div v-else-if="message.inType=='datetime'">
<el-date-picker
:disabled="onlyreaderlock"
v-model="inputP"
type="datetime"
placeholder="选择日期时间">
</el-date-picker>
</div>
<div v-else-if="message.inType=='checkbox'">
<el-checkbox-group v-model="inputP" >
<el-checkbox :label="a" v-for="a in message.TypeVal" :key="a" :disabled="onlyreaderlock">{{a}}</el-checkbox>
</el-checkbox-group>
<!-- <el-checkbox-group v-model="inputP" :disabled="onlyreaderlock">
<el-checkbox v-for="city in message.TypeVal" :label="city" :key="city">{{city}}</el-checkbox>
</el-checkbox-group> -->
</div>
</el-col>
</el-row>
</div>
</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() {
console.log("是否可选2",this.onlyreaderlock)
if(this.message.inType==null||this.message.flag==[]||this.message.custom_field==null){
this.showOK=false
return
}else{
if(this.detali){
for(let i =0;i<this.detali.length;i++){
if(this.message.custom_field==this.detali[i].name){
this.selectP=this.detali[i].flag
this.inputP=this.detali[i].val
if(this.message.inType=='checkbox'){
this.inputP=this.inputP.split(",")
}
}
}}
/* if(this.detali.length!=0){
console.log("子详情"+this.message.name,this.detali)
}*/
}
for(let a in this.message.flag){
this.option.push({value:a,label:this.message.flag[a]})
}
},
computed:{
},
methods: {
},
filters: {},
watch: {
"onlyreaderlock":function(){
console.log("是否可选",this.onlyreaderlock)
},
"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>
<style scoped>
.handle-box {
margin-bottom: 20px;
}
.handle-del {
border-color: #bfcbd9;
color: #999;
}
.handle-select {
width: 120px;
}
.handle-input {
width: 160px!important;
display: inline-block;
}
</style>
分析:整个项目分为两级路由,一级路由带图标和动画
<template>
<div class="sidebar">
<el-row class='tac' v-for="(route,index) in $router.options.routes" :key='route.path'>
<el-menu :default-active="$route.path" class="el-menu-vertical-demo" unique-opened router>
<template v-for="(item,index) in route.children" v-if="urlString == route.path">
<template v-if="item.children">
<el-submenu :index="item.path" :key='item.path'>
<template slot="title"><i :class="item.icon"></i>{{ item.name }}</template>
<el-menu-item v-for="(subItem,i) in item.children" v-if="subItem.name" :key="i" :index="subItem.path">{{ subItem.name }}
</el-menu-item>
</el-submenu>
</template>
<template v-else>
<el-menu-item :index="item.path" :key='item.path'>
<i :class="item.icon"></i>{{ item.name }}
</el-menu-item>
</template>
</template>
</el-menu>
</el-row>
</div>
</template>
<script>
export default {
props: ['urlString']
}
</script>
<style scoped>
.sidebar{
display: block;
position: absolute;
width: 250px;
left: 0;
top: 70px;
bottom:0;
background: #eef6f6;
}
.sidebar > ul {
height:100%;
}
</style>
路由配置
{
routes: [
{
path: '/',
name: 'index',
hidden: true,
redirect(to)
{
return 'login';
}
},
{
path: '/login',
name: '登录',
hidden: true,
component: components.Login
},
{
path: '/readme',
name: '后台管理系统',
component: Home,
redirect: '/readme/role',
children: [
{
path: '/readme/role',
name: '角色管理',
icon: 'el-icon-setting',
component: components.Readme.Role
},
{
path: '/readme/user',
name: '账号管理',
icon: 'el-icon-menu',
component: components.Readme.User
},
{
path: '/readme/pub',
name: '多平台管理',
icon: 'el-icon-date',
component: components.Readme.Pub
}]
},
{
path: '/product/system',
name: '策略管理',
icon: 'el-icon-setting',
component: Content,
redirect: '/product/system/log',
children: [
/*{
path: '/product/system/log',
name: '策略列表',
icon: 'reorder',
component: components.product.system.Log
},
{
path: '/product/system/platform',
name: '策略审核',
icon: 'reorder',
component: components.product.system.Platform
}*/
{
path: '/product/system/strategylist',
name: '策略管理',
icon: 'reorder',
component: components.product.system.StrategyList
},
{
path: '/product/system/log',
name: '策略审核',
icon: 'reorder',
component: components.product.system.Log,
},
{
path: '/product/view/platform',
icon: 'reorder',
component: components.product.system.Platform
}
]
},
{
path: '/readme',
name: '返回平台管理',
icon: 'el-icon-setting',
redirect: '/readme/role'
}]
}
]
}
三,递归树
分析:组件调用自身,可以根据层级修改树的结构(增加/删除 属性或者对象,打开/隐藏树),并保存。
父组件
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 {
name: 'HelloWorld',
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>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
body {
font-family: Menlo, Consolas, monospace;
color: #444;
}
.item {
cursor: pointer;
}
.bold {
font-weight: bold;
}
ul {
padding-left: 1em;
line-height: 1.5em;
list-style-type: dot;
}
</style>
子组件
<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>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
</style>