Vue+Element实训:后台管理系统-3
续后台管理系统–2
首页创建
- 首先我们的首页是一个左右布局 所以来到elementuiplus官网中来进行布局设置
- 找到布局容器并且找到对应效果
- 注入到首页页面中
- 设置背景颜色区分区块
- 实现高度自适应
elementui-plus–Menu导航
- 在homeview文件夹下创建components文件夹并且创建文件用来容纳左侧导航
- 创建首页左侧导航
- 在首页中引用使用
导航折叠的菜单
- 创建左侧顶部菜单组件
- 在首页中引用使用
- 在头部组件中设置点击图标用来切换导航 并设置图标样式
- 在vuex中创建模块 用来设置点击图标后切换导航的布尔值
- 在store下新建module文件夹用来容纳首页的vuex模块
- 在vuex的index文件中引用使用模块
- 给图标设置点击事件 从而修改vuex的布尔值 在真假中切换
Vuex–useStore
- 引用useStore 并且调用commit来进行数据的修改
- 创建对应的mutations
- 在页面中添加相反的箭头 用v-ifvuex的数据具体显示哪一个
- 在左侧导航设置 collapse属性控制导航折叠
- 导航是变了,但是右侧整体宽度不会随着页面的改变而变化,把左侧的宽度设置成auto即可自动改变
首页多级路由设置
首页下有:
-
数据统计 EchartsView.vue
-
住户信息统计 UserOne.vue
- 住户信息展示 UserList.vue
- 住户信息修改 UserUpdate.vue
创建对应页面 与路由规则的配置
-
设置路由出口
- 在homeview页面下右侧下方区域设置router-view路由出口 并且在userone.vue中设置路由出口
- 在页面中进行测试
路由实时路由获取
- 我们左侧的导航是根据路由规则实时获取动态展示 所以先把当前路由规则读取出来
- 在左侧导航
- 在leftnav.vue中获取当前路由信息
- 设置路由标题与分类标题(因为有可能有二级菜单)
- 修改左侧列表删除掉没有用的内容
- 在左侧导航
import { createRouter, createWebHistory,createWebHashHistory, RouteRecordRaw } from 'vue-router'
import {
MessageBox,Grid,User
} from '@element-plus/icons-vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/login',
name: 'login',
component: () => import( '../views/login/LoginView.vue')
},
{
path: '/home',
name: 'home',
component: () => import( '../views/home/HomeView.vue'),
children:[
{
path:"/echarts",
name:"echarts",
component:()=>import("../views/home/childrens/EchartsView.vue"),
meta:{
title:"数据展示",
icon:MessageBox
}
},
// {
// path:"/pay",
// name:"pay",
// component:()=>import("../views/home/childrens/PayList.vue"),
// meta:{
// title:"缴费管理",
// icon:Grid
// }
// },
{
path:"/user",
name:"user",
component:()=>import("../views/home/childrens/UserOne.vue"),
meta:{
title:"住户信息",
icon:User
},
children:[
{
path:"/userList",
name:"userList",
component:()=>import("../views/home/childrens/UserList.vue"),
meta:{
classifyTitle:"住户信息",
title:"住户信息列表"
}
},
{
path:"/userupdata",
name:"userupdata",
component:()=>import("../views/home/childrens/UserUpdata.vue"),
meta:{
classifyTitle:"住户信息",
title:"住户信息修改"
}
},
]
},
]
},
{
path:"/",
redirect:"/login"
}
]
const router = createRouter({
history: createWebHashHistory(process.env.BASE_URL),
routes
})
export default router
- 开始遍历之前得到的路由信息
- 添加 展示数据
- 生成二级菜单
- 设置导航
- 在导航中也设置index属性的值为path路径从而完成页面的跳转
- 宽度有问题设置下宽度
住户信息列表
- 获取到elementplus的表格到我们页面当中Userlist.vue
- 增加点数据之后发现数据会把页面撑大 所以我们要进行分页处理
- 设置分页 找到带附加功能的分页 并且使用All combined这个分页项
- 设置分页属性与方法
- 修改绑定的参数
- 修改表格宽度
- 删除掉表格上面的width属性
住户信息列表查找
- 在表格顶部添加输入框(elementui 表格想相关设置) 并且使用计算属性处理数据
住户信息修改
- 复用用户信息列表userlist组件内容到userupdate组件中
- 添加删除和修改的按钮从element找
- 设置点击修改之后的输入弹框
- 在elementplus中的对话框 dialog中找到自定义内容
- 设置嵌套表单的弹出框
- 在components中新建 组件用来封装弹出框 UpdateDialog.vue
- 把封装的组件在userupdate中引用 使用
- 分析代码 发现当点击之后需要设置一个变量的改变控制弹出框 但是不同组件 所以使用vuex来进行这个变量的状态共享
- vuex中创建state
- 在页面的修改按钮上绑定事件点击之后修改这个状态
- 创建mutations
- 在弹出框上绑定变量状态
- 在修改弹出框的两个按钮 点击之后关闭弹出框
- 修改弹出框样式(内容)
- 修改每隔elform-item上的label-wath属性到 el-from上
- 修改输入框宽度
- 开始修改
- 当点击确定按钮时候调用函数并且在函数中得到修改的输入框的值
- 修改输入框的类型 和绑定的变量
- 在函数中得到输入框的值
- 但是这个方法确定和取消都在用 所以我们传递一个形参 来辨别用户到底点击了那个
- 设置表格数据在vuex中
- 因为我们要对展示数据进行操纵 所以把原有写在组件中的表格数据放到vuex中
- 把表格的数据从vuex中获取
- 当点击确定按钮时候调用函数并且在函数中得到修改的输入框的值
项目分辨率响应式创建
- 我们的项目是需要根据页面的大小改变 做出响应式改变的 所以我们可以使用
- 我们可以使用 第三方插件flexible.js帮助我们修改html根节点的font-size大小 从而控制当前页面的rem**(会根据页面的html根节点font-size大小改变而改变)**样式改变
- flexible.js
- flexible.js web自适应方案 阿里团队开源的一个库。使用flexible.js轻松搞定各种不同的移动端设备兼容自适应问题。
- 下载 npm i -S lib-flexible
- 在main.js中进行配置
- 修改flexible配置
- 因为默认情况下只会在540px分辨率一下生效 所以我们需要根据我们的项目分辨率进行调整
- flexible.js web自适应方案 阿里团队开源的一个库。使用flexible.js轻松搞定各种不同的移动端设备兼容自适应问题。
- 这个时候重启项目大家打开浏览器调试器 即可发现在浏览器大小改变的时候 在html根节点上会自动设置一个font-size
- cssrem插件 :我们在写代码的时候发现如果我们都根据80px为1rem在编写代码的时候转换非常的麻烦 所以我们可以在vscode中安装一个cssrem的插件帮助我们进行转换 这样一来开发过程中会更加的方便
- 在vscode扩展中找到 cssrem插件 最新名字叫px to rem & rpx 安装到vscode中 点击右下角设置
- 修改Root Font Size(基准font-size) 配置项为80即可
数据展示组件封装
- 创建一个大容器来容纳左右两个区域
- 在EchartsView.vue页面中创建一个大容器
- 创建容器样式
- 设置左右布局容器
- 设置左右布局样式
- 左右图表展示区块容器样式
- 要展示的2个区域的容器效果是一样的。所以我们可以剥离成一个组件 然后重复调用即可。并且在其中放置slot槽口 后期方便向容器内插入图表
- 创建容器组件
- 在components文件夹下创建 ItemPage.vue
- 编写样式与插槽
- 在views下的Echartview.vue中引用调用使用
- 运行之后大家会发现左右区块就展现出2个容器
- 左右每个区块内容插入容器槽口
- 一共2个图表 使用一个公共的组件容器 所以我们编写这2个不同图表的组件并且 分别显示
- 创建2个组件 在components下 isOne.vue等等 一共2个
- 然后在2个文件中分别设置相关内容与样式(每个图表的标题不一样要修改)
- 在EchartsView.vue中引用调用使用这4个组件 并且插入对应的槽口
代码部分
-EchartsView.vue
<template>
<div class="container">
<div class="itemleft">
<Ip>
<template #main>
<One/>
</template>
</Ip>
</div>
<div class="itemright">
<Ip>
<template #main>
<Two/>
</template>
</Ip>
</div>
</div>
</template>
<script setup>
import Ip from "../../../components/ItemPage.vue"
import One from "../../../components/IsOne.vue"
import Two from "../../../components/IsTwo.vue"
</script>
<style lang="scss">
.container{
width:100%;
margin:0 auto;
background-color: gray;
display: flex;
.itemleft,.itemright{
flex:1;
}
}
</style>
- UserList.vue
<template>
<el-table :data="tableData.listdata.slice((currentPage4-1)*pageSize4,currentPage4*pageSize4)" stripe style="width: 100%">
<el-table-column prop="id" label="编号" />
<el-table-column prop="title" label="楼盘"/>
<el-table-column prop="type" label="类型" />
<el-table-column prop="num" label="门牌号" />
<el-table-column prop="hometype" label="户型" />
<el-table-column prop="name" label="户主" />
<el-table-column>
<template #header>
<el-input v-model="search" size="small" placeholder="请输入查询内容" @blur="searchLink"/>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
v-model:current-page="currentPage4"
v-model:page-size="pageSize4"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:current_page="currentPage4"
:total="tableData.listdata.length"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</template>
<script lang="ts" setup>
import { Search } from '@element-plus/icons-vue/dist/types';
import { ref,onMounted,reactive } from 'vue'
import link from "../../../api/Link.js"
import apiUrl from "../../../api/Url.js"
let search=ref("")
const currentPage4 = ref(1)
const pageSize4 = ref(15)
const small = ref(false)
const background = ref(false)
const disabled = ref(false)
const handleSizeChange = (val: number) => {
pageSize4.value=val
}
const handleCurrentChange = (val: number) => {
currentPage4.value=val
}
let tableData=reactive({
listdata:[]
})
let searchLink=()=>{
link(apiUrl.userList,"get",{},{name:search.value}).then((ok:any)=>{
console.log(ok)
tableData.listdata=ok.data
})
}
onMounted(()=>{
link(apiUrl.userList).then((ok:any)=>{
console.log(ok)
tableData.listdata=ok.data
})
})
</script>
<style>
- UserOne.vue
<template>
<div>
<router-view/>
</div>
</template>
<script>
</script>
<style>
</style>
- UserUpdata.vue
<template>
<el-table :data="
$store.state.HomeModule.listdata.slice((currentPage4-1)*pageSize4,currentPage4*pageSize4)" stripe style="width: 100%">
<el-table-column prop="id" label="编号" />
<el-table-column prop="title" label="楼盘"/>
<el-table-column prop="type" label="类型" />
<el-table-column prop="num" label="门牌号" />
<el-table-column prop="hometype" label="户型" />
<el-table-column prop="name" label="户主" />
<el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.$index, scope.row)"
>修改</el-button
>
<el-button
size="small"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
v-model:current-page="currentPage4"
v-model:page-size="pageSize4"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:current_page="currentPage4"
:total="tableData.listdata.length"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<!-- 修改的弹出框 -->
<Ud/>
</template>
<script lang="ts" setup>
import { Search } from '@element-plus/icons-vue/dist/types';
import { ref,onMounted,reactive } from 'vue'
import link from "../../../api/Link.js"
import apiUrl from "../../../api/Url.js"
import Ud from '../../../components/UpdataDialog.vue';
import {useStore} from "vuex"
let store=useStore()
interface User {
date: string
name: string
address: string
}
let search=ref("")
const currentPage4 = ref(1)
const pageSize4 = ref(15)
const small = ref(false)
const background = ref(false)
const disabled = ref(false)
const handleSizeChange = (val: number) => {
pageSize4.value=val
}
const handleCurrentChange = (val: number) => {
currentPage4.value=val
}
const handleEdit = (index: number, row: User) => {
console.log(index, row);
store.commit("SET_DIALOG",row)
}
const handleDelete = (index: number, row: User) => {
console.log(index, row);
store.dispatch("DEL_DATA",row)
}
let tableData=reactive({
listdata:[]
})
onMounted(()=>{
store.dispatch("USERUPDATA_LIST")
link(apiUrl.userList).then((ok:any)=>{
console.log(ok)
tableData.listdata=ok.data
})
})
</script>
<style>
</style>
- HomeView.vue
<template>
<div class="common-layout">
<el-container>
<el-aside width="auto">
<Lm/>
</el-aside>
<el-container>
<el-header>
<Rm/>
</el-header>
<el-main>
<router-view/>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup>
import Lm from "../../components/LeftMenu.vue"
import Rm from "../../components/RightTop.vue"
</script>
<style lang="scss">
.el-aside{
background-color: #545c64;
}
.el-header{
background-color: white;
}
.el-main{
background-color: gainsboro;
}
.el-aside,.el-container,.common-layout,#app,body,html{
height:100%;
}
</style>
- IsOne.vue
<template>
<div>
<h2>人数统计</h2>
<div id="chartone" class="one"></div>
</div>
</template>
<script setup>
import {inject,onMounted,reactive} from "vue"
import link from "../api/Link.js"
import url from "../api/Url.js"
let $echarts=inject("echarts")
let data=reactive({})
let xdata=reactive([])
let ydata=reactive([])
onMounted(()=>{
let myChart=$echarts.init(document.getElementById("chartone"))
link(url.chartDataOne).then((ok)=>{
let {data}=ok;
console.log(data)
xdata=data.map(v=>v.title)
ydata=data.map(v=>v.num)
console.log("x",xdata)
console.log("y",ydata)
myChart.setOption({
xAxis:{
type:"value",
axisLine:{
lineStyle:{
color:"#fff"
}
}
},
yAxis:{
type:"category",
data:xdata,
axisLine:{
lineStyle:{
color:"#fff"
}
}
},
grid:{
top:"3%",
left:"1%",
bottom:"3%",
right:"6%",
containLabel:true
},
series:[
{
type:"bar",
data:ydata,
itemStyle:{
normal:{
barBorderRadius:[0,20,20,0],
color:new $echarts.graphic.LinearGradient(0,0,1,0,[
{
offset:0,
color:"#005eaa"
},
{
offset:0.5,
color:"#339ca7"
},
{
offset:1,
color:"#cda818"
}
])
}
}
}
]
})
})
})
</script>
<style lang="scss" scoped>
h2{
height: 0.6rem;
color:#fff;
text-align: center;
font-size: 0.25rem;
}
.one{
height:4.5rem;
}
</style>
- IsTwo.vue
<template>
<div>
<h2>报修统计</h2>
<div id="charttwo" class="two"></div>
</div>
</template>
<script setup>
import {inject,onMounted,reactive} from "vue"
import link from "../api/Link.js"
import url from "../api/Url.js"
let $echarts=inject("echarts")
// let data=reactive({})
let xdata=reactive([])
let ydata=reactive([])
onMounted(()=>{
let myChart=$echarts.init(document.getElementById("charttwo"))
link(url.chartDataTwo).then((ok)=>{
console.log(ok)
myChart.setOption({
legend:{top:"bottom"},
tooltip:{},
series:[
{
type:"pie",
data:ok.data,
radius:[10,100],
center:["50%","45%"],
roseType:"area"
}
]
})
})
})
</script>
<style lang="scss" scoped>
h2{
height: 0.6rem;
color:#fff;
text-align: center;
font-size: 0.25rem;
}
.one{
height:4.5rem;
}
.two{
height:4.5rem;
}
</style>
- ItemPage.vue
<template>
<div class="item">
<slot name="main"></slot>
</div>
</template>
<script setup>
</script>
<style lang="scss">
.item{
height:5.125rem;
border:1px solid grey;
margin:0.25rem;
background-color: gainsboro;
}
</style>
- LeftMenu.vue
<template>
<div class="item">
<slot name="main"></slot>
</div>
</template>
<script setup>
</script>
<style lang="scss">
.item{
height:5.125rem;
border:1px solid grey;
margin:0.25rem;
background-color: gainsboro;
}
</style>
- RightTop.vue
<template>
<div>
<el-icon @click="ck"><ArrowRightBold v-if="$store.state.HomeModule.navBool"/><ArrowLeftBold v-else/></el-icon>
</div>
</template>
<script setup>
import {ArrowRightBold,ArrowLeftBold} from '@element-plus/icons-vue'
// import {ref}from "vue"
// let bool=ref(true)
// let ck=()=>{
// bool.value=!bool.value;
// console.log("我被点击了")
// }
import {useStore}from "vuex"
let store=useStore()
let ck=()=>{
store.commit("SET_NAV_BOOL")
}
</script>
<style lang="scss">
.el-header{
line-height: 65px;
.el-icon{
font-size: 20px;
}
}
</style>
- UpdataDialog.vue
<template>
<el-dialog v-model="$store.state.HomeModule.dialogFormVisible" title="请输入修改信息">
<el-form :model="form" :label-width="formLabelWidth">
<el-form-item label="户主" :label-width="formLabelWidth">
<el-input v-model="form.name" autocomplete="off" />
</el-form-item>
<el-form-item label="楼盘名称" :label-width="formLabelWidth">
<el-input v-model="form.title" autocomplete="off" />
</el-form-item>
<el-form-item label="房源类型" :label-width="formLabelWidth">
<el-input v-model="form.type" autocomplete="off" />
</el-form-item>
<el-form-item label="门牌号" :label-width="formLabelWidth">
<el-input v-model="form.num" autocomplete="off" />
</el-form-item>
<el-form-item label="房源户型" :label-width="formLabelWidth">
<el-input v-model="form.hometype" autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeDialog(0)">取消</el-button>
<el-button type="primary" @click="closeDialog(1)">
确定
</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { composeEventHandlers } from 'element-plus/es/utils';
import { reactive, ref } from 'vue'
import { useStore } from "vuex"
import link from "../api/Link.js"
import url from "../api/Url.js"
let store=useStore()
// const dialogFormVisible = ref(false)
const formLabelWidth = '140px'
const form = reactive({
name: '',
title:"",
type:"",
num:"",
hometype:""
})
let closeDialog=(num:number)=>{
store.commit("DIALOG")
if(num==1){
console.log(store.state.HomeModule.uplistData)
let data={
name:form.name,title:form.title,type:form.type,num:form.num,hometype:form.hometype
}
link(url.userList+"/"+store.state.HomeModule.uplistData.id,"PUT",data).then((ok:any)=>{
console.log(ok)
})
}
}
</script>
<style scoped>
.el-button--text {
margin-right: 15px;
}
.el-select {
width: 300px;
}
/* .el-input {
width: 300px;
} */
.dialog-footer button:first-child {
margin-right: 10px;
}
</style>
- HomeModule.ts
import link from "../../api/Link.js"
import apiUrl from "../../api/Url.js"
const HomeModule: object={
state:{
navBool: true,
dialogFormVisible:false,
uplistData:{},
listdata:[]
},
mutations:{
SET_NAV_BOOL(state:any){
state.navBool=!state.navBool
},
SET_DIALOG(state:any,paylog:any){
state.dialogFormVisible=!state.dialogFormVisible;
state.uplistData=paylog
},
DIALOG(state:any){
state.dialogFormVisible=!state.dialogFormVisible;
window.location.reload()
},
LISTDATA(state:any,paylog:any){
state.listdata=paylog
},
},
actions:{
USERUPDATA_LIST(context:any){
link(apiUrl.userList).then((ok:any)=>{
console.log(ok)
context.commit("LISTDATA",ok.data)
})
},
DEL_DATA(context:any,payload:any){
link(apiUrl.userList+"/"+payload.id,"delete").then((ok:any)=>{
console.log(ok)
window.location.reload()
})
}
}
}
export default HomeModule
- Url.js
let apiUrl={
register: "/register",
userList:"/userlist",
chartDataOne:"/chartDataOne",
chartDataTwo:"/chartDataTwo"
}
export default apiUrl
- data.json
{
"register": [
{
"id": 1,
"name": "123@123.com",
"pwd": "admin123"
},
{
"name": "982852662@qq.com",
"pwd": "lyqlyq010502",
"id": 2
},
{
"name": "999@qq.com",
"pwd": "admin123",
"id": 3
},
{
"name": "777@123.com",
"pwd": "admin123",
"id": 4
},
{
"name": "999@qq.com",
"pwd": "123123lyq",
"id": 5
},
{
"name": "999@123.com",
"pwd": "aba0182ef03fdc7b7116729df2a6ec66",
"id": 6
},
{
"name": "111@123.com",
"pwd": "0192023a7bbd73250516f069df18b500",
"id": 7
},
{
"name": "101010@qq.com",
"pwd": "2cca4024094f1a971841a765b0b73941",
"id": 8
},
{
"name": "10101010@qq.com",
"pwd": "0b11a1d4619ede26f88d683343a6fd51",
"id": 9
},
{
"name": "111111@qq.com",
"pwd": "4e91b273dad767d777d41e62d341ffc1",
"id": 10
}
],
"userList": [
{
"id": 287,
"title": "海天家园",
"type": "商铺",
"num": "2-2-2",
"hometype": "三室一厅",
"name": "王五"
},
{
"id": 381,
"title": "海天家园",
"type": "住宅",
"num": "3-1-2",
"hometype": "一室一厅",
"name": "李四"
},
{
"id": 382,
"title": "海天家园",
"type": "住宅",
"num": "3-2-2",
"hometype": "三室一厅",
"name": "黄潘"
},
{
"id": 397,
"title": "海天家园",
"type": "住宅",
"num": "3-3-2",
"hometype": "三室两厅",
"name": "王耀"
},
{
"id": 393,
"title": "海天家园",
"type": "住宅",
"num": "4-2-2",
"hometype": "三室三厅",
"name": "周七"
},
{
"id": 317,
"title": "海天家园",
"type": "商铺",
"num": "5-1-2",
"hometype": "三室两厅",
"name": "陈凡"
},
{
"id": 487,
"title": "海天家园",
"type": "住宅",
"num": "5-2-2",
"hometype": "三室一厅",
"name": "陈章"
},
{
"id": 380,
"title": "海天家园",
"type": "住宅",
"num": "1-2-2",
"hometype": "三室两厅",
"name": "林二"
},
{
"id": 1187,
"title": "海天家园",
"type": "商铺",
"num": "12-1-2",
"hometype": "两室两厅",
"name": "张武"
},
{
"id": 1287,
"title": "海天家园",
"type": "商铺",
"num": "21-2-2",
"hometype": "三室一厅",
"name": "王五"
},
{
"id": 1381,
"title": "海天家园",
"type": "住宅",
"num": "32-1-2",
"hometype": "一室一厅",
"name": "李四"
},
{
"id": 1382,
"title": "海天家园",
"type": "住宅",
"num": "13-2-2",
"hometype": "三室一厅",
"name": "黄三"
},
{
"id": 1397,
"title": "海天家园",
"type": "住宅",
"num": "13-3-2",
"hometype": "三室两厅",
"name": "王土"
},
{
"id": 3193,
"title": "海天家园",
"type": "住宅",
"num": "40-2-2",
"hometype": "三室三厅",
"name": "周伦"
},
{
"id": 3217,
"title": "海天家园",
"type": "商铺",
"num": "9-1-2",
"hometype": "三室两厅",
"name": "陈军"
},
{
"id": 1487,
"title": "海天家园",
"type": "住宅",
"num": "8-2-2",
"hometype": "三室一厅",
"name": "陈章"
},
{
"id": 2387,
"title": "海天家园",
"type": "住宅",
"num": "7-3-2",
"hometype": "三室两厅",
"name": "林北"
},
{
"id": 2187,
"title": "海天家园",
"type": "商铺",
"num": "9-8-2",
"hometype": "两室两厅",
"name": "张明"
},
{
"id": 2287,
"title": "海天家园",
"type": "商铺",
"num": "3-7-2",
"hometype": "三室一厅",
"name": "王三"
},
{
"id": 1381,
"title": "海天家园",
"type": "住宅",
"num": "4-2-2",
"hometype": "一室一厅",
"name": "李四"
},
{
"id": 3282,
"title": "海天家园",
"type": "住宅",
"num": "13-2-2",
"hometype": "三室一厅",
"name": "张涛"
},
{
"id": 3927,
"title": "海天家园",
"type": "住宅",
"num": "32-3-2",
"hometype": "三室两厅",
"name": "王耀"
},
{
"id": 3932,
"title": "海天家园",
"type": "住宅",
"num": "41-2-2",
"hometype": "三室三厅",
"name": "周鳞"
},
{
"id": 2317,
"title": "海天家园",
"type": "商铺",
"num": "10-2-2",
"hometype": "三室两厅",
"name": "陈静"
},
{
"id": 2487,
"title": "海天家园",
"type": "住宅",
"num": "14-5-2",
"hometype": "三室一厅",
"name": "陈航"
}
],
"chartDataOne":[
{"title":"一号楼","num":1827},
{"title":"二号楼","num":342},
{"title":"三号楼","num":541},
{"title":"四号楼","num":1347},
{"title":"五号楼","num":2431},
{"title":"六号楼","num":876},
{"title":"七号楼","num":1578}
],
"chartDataTwo":[
{ "value": 567, "name":"卫生" },
{ "value": 123, "name":"电梯" },
{ "value": 324, "name":"停车引导" },
{ "value": 89, "name":"水电" },
{ "value": 453, "name":"一般报修" },
{ "value": 767, "name":"门禁" }
]
}
实现效果