快捷搜索: 长连接 前端 源码 pan

vue+element-ui中实现多层级复杂的维度根据数据自动生成的表头

表头主要复杂在: 1,有三层,一层是大类,第二层是具体项,第三层是标准值/对比值 2,首列和末尾列是一层 3,整个表格的维度是根据数据的输入自己生成,也就是动态的

下面是在 vue + eleUI 中的解决方案:

<el-table :data="tableData" border style="width: 100%" max-height="700" v-loading="areaLoading" element-loading-text="拼命加载中"> <el-table-column fixed label="IP" prop="ip" width="180"></el-table-column> <el-table-column v-for="(item, index) in itemList" :key="index" :label="item.label"> <el-table-column :label="standard_name" v-for="(standard,standard_name) in item.standard" width="150"> <el-table-column :label="standard" min-width="150"> <template scope="scope"> <span>{ {scope.row.list[item.label][standard_name][value]}}</span> </template> </el-table-column> </el-table-column> </el-table-column> <el-table-column fixed="right" label="验收结果" width="100"> <template scope="scope"> <span :class="{unqualified-color: !scope.row.result}">{ {scope.row.result ? 合格 : 不合格}}</span> </template> </el-table-column>

</el-table>

其对应data: //整理出所有的label和标准对象的属性 itemList: [], //实际数据

tableData:[]

《方法二》

vue+element vue+element
html配置: html配置:
< div id= "table" >{ {tableData}} < div id= "table" >{ {tableData}}
< el-table : data= "tabledata01" : span-method= "tableSpanMethod" max-height= "420" > < el-table : data= "tabledata01" : span-method= "tableSpanMethod" max-height= "420" >
< el-table-column v-for= item in tableConfig : label= "item.label" : prop= item.prop : width= item.width : key= "item.id" > < el-table-column v-for= item in tableConfig : label= "item.label" : prop= item.prop : width= item.width : key= "item.id" >
< el-table-column v-if= item.children||item.children.length>0 v-for= "item1 in item.children" < el-table-column v-if= item.children||item.children.length>0 v-for= "item1 in item.children"
: label= "item1.label" : prop= item1.prop : width= item1.width : key= "item1.id" > : label= "item1.label" : prop= item1.prop : width= item1.width : key= "item1.id" >
< el-table-column v-if= item1.children||item1.children.length>0 v-for= "item2 in item1.children" < el-table-column v-if= item1.children||item1.children.length>0 v-for= "item2 in item1.children"
: label= "item2.label" : prop= item2.prop : width= item2.width : key= "item2.id" > : label= "item2.label" : prop= item2.prop : width= item2.width : key= "item2.id" >
</ el-table-column >
</ el-table-column >
</ el-table-column >
</ el-table >
</ div >
< div id= "table" >{ {tableData}} < el-table : data= "tabledata01" : span-method= "tableSpanMethod" max-height= "420" > < el-table-column v-for= item in tableConfig : label= "item.label" : prop= item.prop : width= item.width : key= "item.id" > < el-table-column v-if= item.children||item.children.length>0 v-for= "item1 in item.children" : label= "item1.label" : prop= item1.prop : width= item1.width : key= "item1.id" > < el-table-column v-if= item1.children||item1.children.length>0 v-for= "item2 in item1.children" : label= "item2.label" : prop= item2.prop : width= item2.width : key= "item2.id" >

data: data:
tableConfig:[ tableConfig:[
{id: 100,label: 一级表头,prop: ,width: ,children:[ {id: 100,label: 一级表头,prop: ,width: ,children:[
{id: 110,label: 二级表头1,prop: districtName,width: }, {id: 110,label: 二级表头1,prop: districtName,width: },
{id: 120,label: 二级表头2,prop: timeDimension,width: } {id: 120,label: 二级表头2,prop: timeDimension,width: }
]}, ]},
{id: 200,label: 一级表头,prop: ,width: ,children:[ {id: 200,label: 一级表头,prop: ,width: ,children:[
{id: 210,label: 二级表头,prop: ,width: ,children:[ {id: 210,label: 二级表头,prop: ,width: ,children:[
{id: 211,label: 三级表头,prop: residentPopNum,width: 110}, {id: 211,label: 三级表头,prop: residentPopNum,width: 110},
{id: 212,label: 三级表头,prop: residentPopDst,width: 110} {id: 212,label: 三级表头,prop: residentPopDst,width: 110}
]} ]}
]}, ]},
{id: 300,label: 一级表头,prop: ,width: ,children:[ {id: 300,label: 一级表头,prop: ,width: ,children:[
{id: 310,label: 二级表头,prop: ,width: ,children:[ {id: 310,label: 二级表头,prop: ,width: ,children:[
{id: 311,label: 三级表头,prop: liveLandArea,width: 110}, {id: 311,label: 三级表头,prop: liveLandArea,width: 110},
{id: 312,label: 三级表头,prop: liveLandDst,width: 110} {id: 312,label: 三级表头,prop: liveLandDst,width: 110}
], ],
}, },
{id: 320,label: 二级表头,prop: ,width: ,children:[ {id: 320,label: 二级表头,prop: ,width: ,children:[
{id: 321,label: 三级表头(km²),prop: employmentLandArea,width: 110}, {id: 321,label: 三级表头(km²),prop: employmentLandArea,width: 110},
{id: 322,label: 三级表头,prop: employmentLandDst,width: 110} {id: 322,label: 三级表头,prop: employmentLandDst,width: 110}
], ],
} }
]}, ]},
{id: 400,label: 一级表头,prop: ,width: ,children:[ {id: 400,label: 一级表头,prop: ,width: ,children:[
{id: 410,label: 二级表头,prop: ,width: ,children:[ {id: 410,label: 二级表头,prop: ,width: ,children:[
{id: 411,label: 三级表头(个),prop: regionTrafficHubNum,width: 110}, {id: 411,label: 三级表头(个),prop: regionTrafficHubNum,width: 110},
{id: 412,label: 三级表头(人次/km²),prop: regionTrafficHubFlow,width: 140} {id: 412,label: 三级表头(人次/km²),prop: regionTrafficHubFlow,width: 140}
], ],
}, },
{id: 420,label: 二级表头,prop: ,width: ,children:[ {id: 420,label: 二级表头,prop: ,width: ,children:[
{id: 421,label: 三级表头(个),prop: highSpeedNum,width: 110}, {id: 421,label: 三级表头(个),prop: highSpeedNum,width: 110},
{id: 422,label: 三级表头(个/km²),prop: highSpeedDst,width: 140} {id: 422,label: 三级表头(个/km²),prop: highSpeedDst,width: 140}
], ],
},{id: 430,label: 二级表头,prop: ,width: ,children:[ },{id: 430,label: 二级表头,prop: ,width: ,children:[
{id: 431,label: 三级表头(个),prop: trackTrafficSpotNum,width: 140}, {id: 431,label: 三级表头(个),prop: trackTrafficSpotNum,width: 140},
{id: 432,label: 三级表头(个/km²),prop: trackTrafficSpotDst,width: 140} {id: 432,label: 三级表头(个/km²),prop: trackTrafficSpotDst,width: 140}
], ],
}, },
{id: 440,label: 二级表头,prop: ,width: ,children:[ {id: 440,label: 二级表头,prop: ,width: ,children:[
{id: 441,label: 三级表头(km),prop: trackTrafficNetNum,width: 110}, {id: 441,label: 三级表头(km),prop: trackTrafficNetNum,width: 110},
{id: 442,label: 三级表头(km/km²),prop: trackTrafficNetDst,width: 140} {id: 442,label: 三级表头(km/km²),prop: trackTrafficNetDst,width: 140}
], ],
}, },
{id: 450,label: 二级表头,prop: ,width: ,children:[ {id: 450,label: 二级表头,prop: ,width: ,children:[
{id: 451,label: 三级表头(个),prop: cityTrafficHubNum,width: 110}, {id: 451,label: 三级表头(个),prop: cityTrafficHubNum,width: 110},
{id: 452,label: 三级表头(个/km²),prop: cityTrafficHubDst,width: 110}, {id: 452,label: 三级表头(个/km²),prop: cityTrafficHubDst,width: 110},
{id: 453,label: 三级表头(人次/km²),prop: cityTrafficHubFlow,width: 140} {id: 453,label: 三级表头(人次/km²),prop: cityTrafficHubFlow,width: 140}
], ],
}, },
{id: 460,label: 二级表头,prop: ,width: ,children:[ {id: 460,label: 二级表头,prop: ,width: ,children:[
{id: 461,label: 三级表头(km),prop: cityTrafficNetNum,width: 110}, {id: 461,label: 三级表头(km),prop: cityTrafficNetNum,width: 110},
{id: 462,label: 三级表头,prop: cityTrafficNetDst,width: 140} {id: 462,label: 三级表头,prop: cityTrafficNetDst,width: 140}
], ],
}, },
]}, ]},
{id: 500,label: 一级表头,prop: ,width: ,children:[ {id: 500,label: 一级表头,prop: ,width: ,children:[
{id: 510,label: 二级表头,prop: ,width: ,children:[ {id: 510,label: 二级表头,prop: ,width: ,children:[
{id: 511,label: 三级表头(km²),prop: pubServeLandArea,width: 110}, {id: 511,label: 三级表头(km²),prop: pubServeLandArea,width: 110},
{id: 512,label: 三级表头,prop: pubServeLandDst,width: 110} {id: 512,label: 三级表头,prop: pubServeLandDst,width: 110}
], ],
}, },
{id: 520,label: 二级表头,prop: ,width: ,children:[ {id: 520,label: 二级表头,prop: ,width: ,children:[
{id: 521,label: 三级表头(个),prop: hospitalResourcesNum,width: 110}, {id: 521,label: 三级表头(个),prop: hospitalResourcesNum,width: 110},
{id: 522,label: 三级表头(km²),prop: hospitalResourcesArea,width: 110}, {id: 522,label: 三级表头(km²),prop: hospitalResourcesArea,width: 110},
{id: 523,label: 三级表头(个/km²),prop: hospitalResourcesDst,width: 110} {id: 523,label: 三级表头(个/km²),prop: hospitalResourcesDst,width: 110}
], ],
},{id: 530,label: 二级表头,prop: ,width: ,children:[ },{id: 530,label: 二级表头,prop: ,width: ,children:[
{id: 531,label: 三级表头(个),prop: schoolResourcesNum,width: 110}, {id: 531,label: 三级表头(个),prop: schoolResourcesNum,width: 110},
{id: 532,label: 三级表头(km²),prop: schoolResourcesArea,width: 110}, {id: 532,label: 三级表头(km²),prop: schoolResourcesArea,width: 110},
{id: 533,label: 三级表头(个/km²),prop: schoolResourcesDst,width: 110} {id: 533,label: 三级表头(个/km²),prop: schoolResourcesDst,width: 110}
], ],
}, },
{id: 540,label: 二级表头,prop: ,width: ,children:[ {id: 540,label: 二级表头,prop: ,width: ,children:[
{id: 541,label: 三级表头(个),prop: humanResourcesNum,width: 110}, {id: 541,label: 三级表头(个),prop: humanResourcesNum,width: 110},
{id: 542,label: 三级表头(个/km²),prop: humanResourcesDst,width: 110} {id: 542,label: 三级表头(个/km²),prop: humanResourcesDst,width: 110}
], ],
}, },
{id: 550,label: 二级表头,prop: ,width: ,children:[ {id: 550,label: 二级表头,prop: ,width: ,children:[
{id: 551,label: 三级表头(个),prop: businessResourcesNum,width: 110}, {id: 551,label: 三级表头(个),prop: businessResourcesNum,width: 110},
{id: 552,label: 三级表头(个/km²),prop: businessResourcesDst,width: 110} {id: 552,label: 三级表头(个/km²),prop: businessResourcesDst,width: 110}
], ],
}, },
{id: 560,label: 二级表头,prop: ,width: ,children:[ {id: 560,label: 二级表头,prop: ,width: ,children:[
{id: 561,label: 三级表头(个),prop: environResourcesNum,width: 110}, {id: 561,label: 三级表头(个),prop: environResourcesNum,width: 110},
{id: 562,label: 三级表头(个/km²),prop: environResourcesDst,width: 110} {id: 562,label: 三级表头(个/km²),prop: environResourcesDst,width: 110}
], ],
}, },
]}, ]},
{id: 600,label: 一级表头,prop: ,width: ,children:[ {id: 600,label: 一级表头,prop: ,width: ,children:[
{id: 610,label: 二级表头,prop: ,width: ,children:[ {id: 610,label: 二级表头,prop: ,width: ,children:[
{id: 611,label: 三级表头(分),prop: populationScore,width: 110}, {id: 611,label: 三级表头(分),prop: populationScore,width: 110},
], ],
}, },
{id: 620,label: 二级表头,prop: ,width: ,children:[ {id: 620,label: 二级表头,prop: ,width: ,children:[
{id: 621,label: 三级表头(分),prop: landScore,width: 110}, {id: 621,label: 三级表头(分),prop: landScore,width: 110},
], ],
},{id: 630,label: 二级表头,prop: ,width: ,children:[ },{id: 630,label: 二级表头,prop: ,width: ,children:[
{id: 631,label: 三级表头(分),prop: trafficScore,width: 110}, {id: 631,label: 三级表头(分),prop: trafficScore,width: 110},
], ],
}, },
{id: 640,label: 二级表头,prop: ,width: ,children:[ {id: 640,label: 二级表头,prop: ,width: ,children:[
{id: 641,label: 三级表头(分),prop: communalFacilitiesScore,width: 110}, {id: 641,label: 三级表头(分),prop: communalFacilitiesScore,width: 110},
], ],
}, },
{id: 650,label: 二级表头,prop: ,width: ,children:[ {id: 650,label: 二级表头,prop: ,width: ,children:[
{id: 651,label: 三级表头(分),prop: modelScore,width: 110}, {id: 651,label: 三级表头(分),prop: modelScore,width: 110},
], ],
} }
]}, ]},
], ],
tableConfig:[ {id: 100,label: 一级表头,prop: ,width: ,children:[ {id: 110,label: 二级表头1,prop: districtName,width: }, {id: 120,label: 二级表头2,prop: timeDimension,width: } ]}, {id: 200,label: 一级表头,prop: ,width: ,children:[ {id: 210,label: 二级表头,prop: ,width: ,children:[ {id: 211,label: 三级表头,prop: residentPopNum,width: 110}, {id: 212,label: 三级表头,prop: residentPopDst,width: 110} ]} ]}, {id: 300,label: 一级表头,prop: ,width: ,children:[ {id: 310,label: 二级表头,prop: ,width: ,children:[ {id: 311,label: 三级表头,prop: liveLandArea,width: 110}, {id: 312,label: 三级表头,prop: liveLandDst,width: 110} ], }, {id: 320,label: 二级表头,prop: ,width: ,children:[ {id: 321,label: 三级表头(km²),prop: employmentLandArea,width: 110}, {id: 322,label: 三级表头,prop: employmentLandDst,width: 110} ], } ]}, {id: 400,label: 一级表头,prop: ,width: ,children:[ {id: 410,label: 二级表头,prop: ,width: ,children:[ {id: 411,label: 三级表头(个),prop: regionTrafficHubNum,width: 110}, {id: 412,label: 三级表头(人次/km²),prop: regionTrafficHubFlow,width: 140} ], }, {id: 420,label: 二级表头,prop: ,width: ,children:[ {id: 421,label: 三级表头(个),prop: highSpeedNum,width: 110}, {id: 422,label: 三级表头(个/km²),prop: highSpeedDst,width: 140} ], },{id: 430,label: 二级表头,prop: ,width: ,children:[ {id: 431,label: 三级表头(个),prop: trackTrafficSpotNum,width: 140}, {id: 432,label: 三级表头(个/km²),prop: trackTrafficSpotDst,width: 140} ], }, {id: 440,label: 二级表头,prop: ,width: ,children:[ {id: 441,label: 三级表头(km),prop: trackTrafficNetNum,width: 110}, {id: 442,label: 三级表头(km/km²),prop: trackTrafficNetDst,width: 140} ], }, {id: 450,label: 二级表头,prop: ,width: ,children:[ {id: 451,label: 三级表头(个),prop: cityTrafficHubNum,width: 110}, {id: 452,label: 三级表头(个/km²),prop: cityTrafficHubDst,width: 110}, {id: 453,label: 三级表头(人次/km²),prop: cityTrafficHubFlow,width: 140} ], }, {id: 460,label: 二级表头,prop: ,width: ,children:[ {id: 461,label: 三级表头(km),prop: cityTrafficNetNum,width: 110}, {id: 462,label: 三级表头,prop: cityTrafficNetDst,width: 140} ], }, ]}, {id: 500,label: 一级表头,prop: ,width: ,children:[ {id: 510,label: 二级表头,prop: ,width: ,children:[ {id: 511,label: 三级表头(km²),prop: pubServeLandArea,width: 110}, {id: 512,label: 三级表头,prop: pubServeLandDst,width: 110} ], }, {id: 520,label: 二级表头,prop: ,width: ,children:[ {id: 521,label: 三级表头(个),prop: hospitalResourcesNum,width: 110}, {id: 522,label: 三级表头(km²),prop: hospitalResourcesArea,width: 110}, {id: 523,label: 三级表头(个/km²),prop: hospitalResourcesDst,width: 110} ], },{id: 530,label: 二级表头,prop: ,width: ,children:[ {id: 531,label: 三级表头(个),prop: schoolResourcesNum,width: 110}, {id: 532,label: 三级表头(km²),prop: schoolResourcesArea,width: 110}, {id: 533,label: 三级表头(个/km²),prop: schoolResourcesDst,width: 110} ], }, {id: 540,label: 二级表头,prop: ,width: ,children:[ {id: 541,label: 三级表头(个),prop: humanResourcesNum,width: 110}, {id: 542,label: 三级表头(个/km²),prop: humanResourcesDst,width: 110} ], }, {id: 550,label: 二级表头,prop: ,width: ,children:[ {id: 551,label: 三级表头(个),prop: businessResourcesNum,width: 110}, {id: 552,label: 三级表头(个/km²),prop: businessResourcesDst,width: 110} ], }, {id: 560,label: 二级表头,prop: ,width: ,children:[ {id: 561,label: 三级表头(个),prop: environResourcesNum,width: 110}, {id: 562,label: 三级表头(个/km²),prop: environResourcesDst,width: 110} ], }, ]}, {id: 600,label: 一级表头,prop: ,width: ,children:[ {id: 610,label: 二级表头,prop: ,width: ,children:[ {id: 611,label: 三级表头(分),prop: populationScore,width: 110}, ], }, {id: 620,label: 二级表头,prop: ,width: ,children:[ {id: 621,label: 三级表头(分),prop: landScore,width: 110}, ], },{id: 630,label: 二级表头,prop: ,width: ,children:[ {id: 631,label: 三级表头(分),prop: trafficScore,width: 110}, ], }, {id: 640,label: 二级表头,prop: ,width: ,children:[ {id: 641,label: 三级表头(分),prop: communalFacilitiesScore,width: 110}, ], }, {id: 650,label: 二级表头,prop: ,width: ,children:[ {id: 651,label: 三级表头(分),prop: modelScore,width: 110}, ], } ]}, ],
注:动态生成表头必须配置"key" 注:动态生成表头必须配置"key"
view: view:
《elementUI使用指南》 《elementUI使用指南》

开发环境


1.安装webpack

npm install -g webpack
    1

2.安装vue-cli

vue-cli是什么?

vue-cli 是vue.js的脚手架,用于自动生成vue.js模板工程的。

使用步骤:

    安装vue-cli: npm install -g vue-cli 1 使用vue-cli构建项目 vue init webpack project-name //创建一个基于webpack模板的名为project-name的项目 1 目前可用的模板包括: –全功能的Browserify + vueify,包括热加载,静态检测,单元测试。 –一个简易的Browserify + vueify,以便于快速开始。 –全功能的Webpack + vueify,包括热加载,静态检测,单元测试。 –一个简易的Webpack + vueify,以便于快速开始。 安装项目依赖 cd project-name //进入项目目录 npm install //安装项目依赖 npm run dev //运行项目 1 2 3

此时在浏览器打开:localhost:8080即可看到欢迎页。

关于webpack和vue-cli的更多使用方法参见官方文档。
    但是这个只能在本地跑,要如何在我们自己的服务器上访问呢?此时需要执行 npm run build 1

搭建开发环境

本来想用vue-cli重新创建项目,试了几次总是出现各种问题,没办法成功。最后在仔细查看 Element-UI 的的 快速上手 部分的时候发现 饿了么 团队给了一个他们自己的 。于是我就用这个模板来尝试了下,结果成功了。所以,如果你不想太折腾的话,建议还是使用官方给的项目模板,可以省很多事。

第一步:安装

    克隆/下载项目模板 将下载的模板放到你项目的根目录下 安装依赖 npm install 1 运行项目模板 npm run dev 1 此时在浏览器打开:localhost:8080即可看到欢迎页。
项目模板里已经把需要配置的文件都配置好了。

第二步:安装element-ui

第一步,我们成功安装了项目模板,接下来,我们需要安装element-ui到项目下。
npm i element-ui@next -D
    1

开始使用

接下来我们就可以参照 Element-UI 的上手开发了。

例子

我们参照官方的按钮组件使用说明,在项目模板的基础上做一个按钮的例子。其它文件不需要改动,只修改App.vue文件的内容。代码如下:

App.vue

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <h1>{
          
   { msg }}</h1>
    <el-button @click.native="startHacking">Lets do it</el-button>
    <div class="block">
    <span class="demonstration">显示默认颜色</span>
    <span class="wrapper">
    <el-button type="success">成功按钮</el-button>
    <el-button type="warning">警告按钮</el-button>
    <el-button type="danger">危险按钮</el-button>
    <el-button type="info">信息按钮</el-button>
    </span>
    </div>
    <br/>
    <div class="block">
      <span class="demonstration">hover 显示颜色</span>
    <span class="wrapper">
    <el-button :plain="true" type="success">成功按钮</el-button>
    <el-button :plain="true" type="warning">警告按钮</el-button>
    <el-button :plain="true" type="danger">危险按钮</el-button>
    <el-button :plain="true" type="info">信息按钮</el-button>
    </span>
    </div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      msg: Use Vue 2.0 Today!
    }
  },

  methods: {
    startHacking () {
      this.$notify({
        title: It Works,
        message: We have laid the groundwork for you. Now its your time to build something epic!,
        duration: 6000
      })
    }
  }
}
</script>

<style>
body {
  font-family: Helvetica, sans-serif;
}
</style>
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

效果如下图所示:


使用过程中碰到的问题:

1. phantomjs安装失败

由于源的问题,安装phantomjs必须要“搭梯子”,使用内网无法下载。所以解决的方法有两种:

    方法一:通过科学上网,然后安装。 方法二:对于不知道怎么“搭梯子”的同学,可以通过更改源来下载,操作方法如下: npm install phantomjs --phantomjs_cdnurl=http://cnpmjs.org/downloads 1

2.打开页面乱码

通过 Element-UI 官方提供的项目模板开发,会发现在浏览器打开页面的时候,中文是乱码的。如下图所示:

但html页面中已经设置了<meta chartset=utf-8> 。

仔细查看该页面所涉及的文件的编码格式的时候,发现引用的App.vue 文件的编码格式是GBK ,所以把该文件编码格式改为UTF-8 即可。

“ 使用VUE开发多级多选树形菜单组件 ”

要开发一个这样的多级多选菜单组件,功能是:

    点击父标题栏可以打开与折叠子列表 点击父标题栏的勾选图标可以全选或取消子列表 点击子列表的勾选图标达到全选时,父标题栏的勾选图标自动勾选;反之,没达到全选时,父标题栏的勾选图标自动取消勾选 当所有父标题栏的勾选图标达到全选时,最底下那个全选框自动勾选;反之,没达到全选时,最底下那个全选框自动取消勾选 点击最底下那个全选框可以全选或取消全部的勾选图标 所以总结起来我们重点要利用子列表勾选了哪些项来计算出父标题与底下的全选框是自动勾选还是自动取消,并且父标题与底下的全选框在选择变化时子列表应有什么变化。要做到以上,实现过程是:
构建我们model层数据
datas : [
  {
    //用于判断是否展示子列表
    isShowListItem : false,
    //用于记录选中了哪些子项
    selected : [],
    //父标题
    listTitle : "保利南悦湾",
    //子列表
    listItem : [
      {
        id : 1,
        name : "李小龙"
      },
      {
        id : 2,
        name : "周星驰"
      },
      {
        id : 3,
        name : "周杰伦"
      }
    ]
  },
  {
    isShowListItem : false,
    selected : [],
    listTitle : "南庄万科城",
    listItem : [
      {
        id : 4,
        name : "大魔王"
      },
      {
        id : 5,
        name : "老妖怪"
      }
    ]
  }
]
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
记录子列表勾选了哪些项

子列表通过v-model=”data.selected”去双向绑定到selected数组中,当子列表项的checked发生变化时,就会把当前项的id记录到selected数组里去

<input 
type="checkbox"
:value="item.id"
v-model="data.selected"
>
    1 2 3 4 5
当父标题勾选变化时的处理方法 自动处理父标题勾选图标的变化

在HTML里,通过绑定:checked=”isTitleChecked(data)”,这时,每当其他项变化时,父标题都会调用一下isTitleChecked这个方法去判断一下这时自己的checked状态是true还是false,从而达到根据子项选中数目不同,父标题自动变化的目的。 通过@change=”changeTitleChecked(data,$event)”,每当父标题主动勾选或取消时触发 父标题HTML

<input :id="data.listTitle"
  class="list-input"
  type="checkbox"
  :checked="isTitleChecked(data)"
  @change="changeTitleChecked(data,$event)"
>
    1 2 3 4 5 6

父标题JS

    changeTitleChecked方法:当主动触发父标题的勾选图标时,如果这次触发chaeked的状态是true,则要把子列表项中没选中的全部选中,即将它们全部加进selected数组中;如果是false,则要把子列表项全部取消选中,即清空selected数组。 isTitleChecked方法:当子列表项全部选中时自动勾选父标题。
/**
* 当父标题状态变化时的处理方法
* @param data  [当前项的data]
* @param event [当前项的event]
*/
changeTitleChecked : function (data,event) {
  if (event.target.checked === true) {
    data.listItem.forEach(function (item) {
    data.selected.indexOf(item.id) === -1 && data.selected.push(item.id);
    })
  }else {
    data.selected = [];
  }
}
    1 2 3 4 5 6 7 8 9 10 11 12 13 14
/**
* 判断父标题选择状态
* @param data        [当前项的data]
* @returns {boolean}
*/
isTitleChecked : function (data) {
  var _selected = data.selected;
  var _listItem = data.listItem;
  // 验证selected中是否含有全部的item的id 如果是 证明title要选中
  return _listItem.every(function (item) {
   return _selected.indexOf(item.id) != -1;
  });
}
    1 2 3 4 5 6 7 8 9 10 11 12 13
当底下的全选框变化时的处理方法 自动处理底下的全选框的变化

全选框HTML:

<input id="all-checked"
  type="checkbox"
  :checked="isAllChecked()"
  @change="changeAllChecked($event)"
>
    1 2 3 4 5

全选框JS:

    changeAllChecked方法:当主动触发全选框时,如果checked为true,则将全部的子项都放进selected数组里;反之则清空全部selected数组。 isAllChecked 方法:判断selected数组的长度是否等于全部子项数,如果相等,则全选框checked状态设为true。
/**
* 全选框change事件的回调处理方法
* @param event 
*/
changeAllChecked : function (event) {
          
   
  if (event.target.checked === true) {
    this.datas.forEach(function (data) {
          
   
      data.listItem.forEach(function (item) {
          
   
      data.selected.indexOf(item.id) === -1 && data.selected.push(item.id);
    })
  })
}else {
      this.datas.forEach(function (data) {
          
   
      data.selected = [];
    })
  }
}
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/**
* 判断全选框选择状态
* @returns {boolean}
*/
isAllChecked : function () {
    return this.datas.every(function (data) {
        return data.selected.length === data.listItem.length;
    });
}

vue组件库的总结

UI组件

开发框架

    - 流行的轻量高效的前端组件化方案 - Vue管理面板框架 - Electron及VueJS快速启动样板 - Vue2单页应用样板 - 前后端分离后的单页应用开发 - VueJS与Framework7结合 - 轻量级高性能MVVM Admin UI框架 - 仿VueJS Vue loader示例 - vue启动页

实用库

    - 专为 Vue.js 应用程序开发的状态管理模式 - 简单轻量级的基于模块的Vue.js验证 - qingcheng主题 - 创建管理面板网站的UI库 - 管理app的meta信息 - 将axios整合到VueJS的封装 - vue2的可变彩色svg图标方案 - VueJS测试实用工具库 - 结合VueJS使用的Framework7组件 - vue的Bootstrap样式组件 - 用实时编辑和预览来渲染Vue组件 - reactive的在线和离线组件 - 用于Vue组件的延迟渲染 - 交互式密码强度计 - 支持 vuecli 的 Element UI 的后台模板 - 将选择的API封装到Vue对象中的插件 - 基于cleave.js的Cleave组件 - 简化事件的VueJS插件 - 应用于Vue.js的Vue-ShortKey 插件 - Cordova的VueJS插件 - 页面过渡插件 - VueJS的手势事件插件 - 从html及js环境加载vue文件 - 用于qartjs的Vue2指令 - 处理VueJS事件 - VueJS的Websocket插件 - 具有类型支持的Vuejs本地储存插件 - 懒加载图片 - VueJS的事件总线 - vue插件的Reactive层 - 非阻塞通知库 - 懒加载组件或者元素的Vue指令 - vue中添加用于配合媒体查询的方法 - 当元素在页面上可见或隐藏时检测 - 在Vue装载机检查脚本 - 简单通用的分页组件 - 定位插件 - 检测HTML调整大小事件的vue指令 - 分享某种Vuex mutations - 将文件转换为Base64的vue组件 - Vue Bulma的modal组件 - Famous库的vue组件 - 异步的表单验证组件 - 简单的表单验证 - 截断字符串的VueJS过滤器 - 一个高级zoombox - 基于内容自动调整文本输入的大小 - 图片懒加载插件

服务端

    - 用于服务器渲染Vue app的最小化框架 - 简单的使用服务器端渲染vue.js - 非常简单的VueJS服务器端渲染模板 - 结合Express使用Vue2服务端渲染 - Nodejs服务端渲染

辅助工具

    - Vuejs可视化及压力测试 - 展示Vue组件的最小化框架 - 目前vscode最好的vue代码提示插件 - 轻松生成Vue js组件的CLI工具 - 简单的多页CLI - vuejs starter套件

应用实例

    - 基于网络的个人音频流媒体服务 - 轻量级的CMS建站系统 - 博客平台 - 个人博客系统 - 重写vue版cnode社区 - 博客内容管理器 - 简单的rss阅读器 - 依赖GitHub Pages无需本地生成的静态博客 - Web版的聊天应用 - nuvo-dashing-js的fork - 功能极其简单的笔记本 - 使用Vue2.0 和Vuex的vue-blog

Demo示例

vue的组件开发手风琴菜单实例

小图标是引入font-awesome字体图标库绘制的。效果如下图所示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>index</title>
    <link rel="stylesheet" href="css/font-awesome.min.css">
    <link rel="stylesheet" href="css/index.css">
    <script type="text/javascript" src="../lib/vue.min.js"></script>
    <script type="text/javascript" src="../lib/jquery-1.11.3.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            padding-top: 100px;
        }

        #tabPanel {
            width: 120px;
            height: auto;
            margin: 0 auto;
        }

        #tabPanel .item .sildermun ul li {
            height: 40px;
            line-height: 40px;
            list-style: none;
        }

        #tabPanel .item .sildermun ul li:hover {
            background: #ccc;
        }

        #tabPanel .item .menutitle {
            height: 40px;
            line-height: 40px;
            text-align: center;
            background: #ccc;
        }

        #tabPanel .item .sildermun {
            text-align: center;
            background: #eee;
        }
    </style>
</head>

<body>

    <div id="tabItem">
        <slider-item></slider-item>
        <slider-item></slider-item>
        <slider-item></slider-item>
        <slider-item></slider-item>
    </div>

    <!--组件模板,也可以使用template标签方式引入模板-->
    <template id="tab">
        <div id="tabPanel">
            <div class="item">
                <div class="menutitle" @click="toggle()"><i class="icon-th-list"></i>&nbsp;{
          
   {
          
   parentItem}}</div>
                    <div class="sildermun" v-show="status">
                        <ul>
                            <li v-for="(index,v) in childItems"><i class="icon-star"></i>&nbsp;{
          
   {
          
   v+index}}</li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </template>
    <!--组件模板,也可以使用template标签方式引入模板-->
</body>

</html>
<script>
    var vue = new Vue({
        el: "#tabItem",
        data: {

        },
        components: {
            slider-item: {
                template: #tab,
                data: function() {
            
     
                    return {
                        status: false,
                        parentItem: "父级菜单",
                        childItems: ["子级菜单", "子级菜单", "子级菜单", "子级菜单"]
                    }
                },
                methods: {
                    //切换滑块
                    toggle: function() {
            
     
                        this.status = !this.status;
                    }
                }
            }
        }
    });
</script>

经验分享 程序员 微信小程序 职场和发展