今天大概的说一下我们在对table进行渲染数据的时候,常见的一些问题,以及可能不容易注意的细节。
我们在渲染数据的时候,最喜欢的是什么呢?就是下面这样的格式:
[{'name' : 'tom','sex' : '男'},{'name' : 'jim','sex' : '女'},]
这样的数据是可以直接绑定element-ui的data属性,根据prop获取到的,或者就是直接写vue的v-for也是可以直接拿到的。这里不写了,之前已经写过了,但是会有很多下面的情况:
[{'name' : 'tom','class_lists':[{'class' : '1101'},{'class' : '1102'}],'sex' : '女'},{'name' : 'tom','class_lists':[{'class' : '1101'},{'class' : '1102'}],'sex' : '女'}]
那么这样的数据是属于一个返回的对象包含一个数据在里面,这样的应该怎么处理呢?其实也很简单,两种办法,这里不一一写,只写一个简单的。
<el-table-column prop="class_lists" width="140" label="班级列表">
<template slot-scope="scope">
<span v-for="(col,index) in scope.row.class_lists">{{col.telephone}}</span>
</template>
</el-table-column>
我们直接声明一个无语义化的标签,写一个插槽进去,利用element-ui的row属性,将该数组拿到,遍历显示出来就可以。可能有人对另一个方法比较感兴趣,这里说一下,就是我们在请求接口以后将拿到的数据切割,将数据或取出来以后进行遍历,重新转为对象,最后将转好的对象给声明的数组,那么这样最终拿到的数组一样可以直接遍历,只是需要写两层遍历循环,对性能无意是有很大的影响的,稍微数据多一点,页面就会显的很慢。
我们在渲染数据的时候,很多的时候后端为了检索方便,在进行数据检索的时候是不会直接用中文进行检索的,那么他就会提供一个类似于下面这样的数据格式出来:
Marital_Status = (
(0, "结婚"),
(1, "未婚热恋"),
(2, "单身"),
(3, "离婚后热恋"),
(-1, "离婚后单身"),
)
一般后端会给到我们这样的kay。但是不会给我们对应的value,这样的数据格式我们应该怎么处理呢?也很简单,我们只需要写一个if判断就可以了:
<el-table-column prop="Marital_Status" label="婚姻状态">
<template slot-scope="scope">
<span v-if="scope.row.master_status_lable === 0">结婚</span>
<span v-else-if="scope.row.master_status_lable === 1">未婚热恋</span>
<span v-else-if="scope.row.master_status_lable === 2">单身</span>
<span v-else-if="scope.row.master_status_lable === 3">离婚后热恋</span>
<span v-else-if="scope.row.master_status_lable === -1">离婚后单身</span>
<span v-else>未知</span>
</template>
</el-table-column>
我们经常看到京东也好,天猫也好,里面都有类似于这样的功能:
那么其实这样的一个分类的过滤器呢是一组一组的单选框,这样的分类有个特点啊,就是每一类只能选择一个,还要同时满足每一类的条件进行筛选,这样的无疑是筛选中相对比较复杂的一点的,这样的应该怎么实现的呢?这里我简单的写一下实现的代码,我们不做他那么的高大上,我们只写实现思路:
<div style="float: left">
<label>品牌</label>
<button class="common-btn">不限</button>
</div>
<div class="room-select-top">
<el-radio-group v-model="item_phone_type" @change="condition_inquire">
<el-radio v-for="phone_type in phone_types" :label="phone_type" :key="phone_type">{{phone_type}}</el-radio>
</el-radio-group>
</div>
phone_types : ['苹果', '小米', '魅族', '三星', '索尼', '夏普'],
item_phone_type : '',
phone_type : [],
效果图
那么进行选择的时候呢直接绑定对应的change时间,点击一次将绑定的item_phone_type给后端,就是进行一次数据的检索,这个多条件的时候,多写几个类似的group就可以了。
那么有人就问了,那如果你的选项是后端给的呢?这个其实都是一样的,就想京东一样,很多的筛选条件都是后端获取的,并不是写死的,那么这个时候我们需要在页面初始化的阶段就要将所有的筛选条件拿到,渲染出来,也就是再created阶段将请求筛选条件的接口执行结束,不然拿不到数据。下面的例子我会写到这里。
有的时候呢是分类以后还要每一条数据都累加起来给后端请求,类似于这样的: 我要实现的是需要同时满足这些条件的数据: 效果图
那么这样的应该怎么实现呢?
created: function() {
let that = this;
/**
* @search_live 进行第一次的无条件查询
*/
that.search_live();
/**
* @get_market_code_list 将市场码的条件拿到
*/
that.get_market_code_list();
/**
* @get_src_code 将来源码的条件拿到
*/
that.get_src_code();
},
获取市场码的过程就比较简单的了:
/**
* @get_market_code_list 获取市场码
* @param no
*/
get_market_code_list() {
let that = this;
let url = '市场码的接口;
that.$axios({
method: 'get',
url: url
}).then((res) => {
console.info(res);
if(res.data.message === 'success'){
that.item_code_market_ids = res.data.data.results;
}else{
console.error(res.data.message);
}
}).catch((err) => {
console.error(err);
})
},
后端会返回这样的数据(如果不是需要我们转为这样的格式):
{
"message": "success",
"data": {
"count": 2,
"results": [{
"code": "R",
"descript": "门市类"
}, {
"code": "G",
"descript": "团队类"
}]
}
}
item_code_market_ids 这个字段就是我们在return里面绑定的市场码,他作为遍历的对象给到页面:
<div class="order-customer">
<div style="float: left">
<label style="display: inline-block;width: 52px">市场码</label>
<button class="common-btn">不限</button>
</div>
<div class="select-sty">
<el-checkbox-group v-model="code_market_ids" @change="condition_inquire">
<el-checkbox v-for="code_market_id in item_code_market_ids" :label="code_market_id.code" :key="code_market_id.code">{{code_market_id.descript}}</el-checkbox>
</el-checkbox-group>
</div>
</div>
那么上图中我选择了以后,会给后端什么样的数据呢?
{
"guest_list": {
"master_from_lable": [],
"room_type": ["舒适双床房", "舒适家庭房"],
"code_market_id": ["C", "R"],
"code_src_id": ["WIK", "MEM"]
}
}
可能你们已经看明白怎么回事,这里简单的说一下,就是我们选择的时候,每一类是一个数组给到后端,用户每选择一次就会操作一次数组,这样可以实现实时进行过滤数据的效果,当然,你的图条件筛选的时候也需要给到后端这样的一个结构数据,只不过数据里面是空值而已。这样就实现了一个多条件筛选的过程。
我们在使用element-ui的时候,会经常用到tabs:
类似于这样的,这里我需要说明的是,我们经常使用里面的tab.index来判断当前用户点击的是哪一个,那么我们判断的时候习惯性的写:
tab.index === 0 其实这样是不对的,他的0是char类型的,也就是说我们需要 tab.index === '0’才可以进行判断,仅此记录!
expand是table里面的一个展开组件,主要是用来存放一些展示不完的选项的,大概就是这样的:
展开以后是这样的,代码是这样的:
<el-table-column prop="rt_rate" width="140" label="预定房间类型" :key="Math.random()" v-if="room_type_array_flag" type="expand">
<template slot-scope="scope">
<span>房间类型:</span><span v-for="(col,index) in scope.row.rt_rate">{{col.room_type}}、</span>
</template>
</el-table-column>
这里就是上面说到的,对象里面有数组的情况,这里不做赘述,需要说明的是 expand每一行只能使用一次,多次是没有效果的,我自己测试的是这样,不知道是不是有什么属性,有帖子解决了这个问题,解决多个expand的问题但是我不确定是不是可以,因为我尝试的时候好像没实现,应该是我写的有问题,总之一个是没有问题的,后期我会持续跟进这个问题,解决的时候我会写一篇详细的帖子出来。目前就不在这里献丑了。
v-if我们都知道是用来判断一个值对否存在的,但是我们还可以用来判断一个元素是否显示,也就是和v-show一样的功能,但是他们还是有区别的,这里就不说什么区别了,我要说的是我们在使用的时候,需要加一个唯一标识码,是因为表格是element-ui通过循环产生的,而vue在dom重新渲染时有一个性能优化机制,就是相同dom会被复用,这就是问题所在,所以,通过key去标识一下当前行是唯一的,不许复用。所以我们在使用的时候可以进行一个简单的处理:
<el-table-column prop="rt_rate" width="140" label="预定房间号" :key="Math.random()" v-if="room_type_array_flag">
<template slot-scope="scope">
<span v-for="(col,index) in scope.row.rt_rate">{{col.room_number}}、</span>
</template>
</el-table-column>
需求说明:是这样的,就是我们后端给我返回的数据是统一的,但是呢,情况是
那么每一个tab是不同的接口,意味着拿到的数据是不一样的,那么渲染出来的表格也是不一样的,我们一般的做法是每一个tab下面画一个table出来,这是常规做法,但是我只画了一个,我还不想改了,所以我是这样做的:
<el-table-column prop="room_number" label="在住房间号" :key="Math.random()" v-if="room_type_flag">
</el-table-column>
<el-table-column prop="rt_rate" width="140" label="预定房间号" :key="Math.random()" v-if="room_type_array_flag">
<template slot-scope="scope">
<span v-for="(col,index) in scope.row.rt_rate">{{col.room_number}}、</span>
</template>
</el-table-column>
<el-table-column prop="master_guest" width="140" label="在住人联系电话" :key="Math.random()" v-if="!rsc_peo_flag" type="expand">
<template slot-scope="scope">
<span v-for="(col,index) in scope.row.master_guest">{{col.telephone}}、</span>
</template>
</el-table-column>
<el-table-column prop="reserve_guest" width="240" label="预定人联系电话" :key="Math.random()" v-if="rsc_peo_flag">
<template slot-scope="scope">
<span v-for="(col,index) in scope.row.reserve_guest">{{col.telephone}}、</span>
</template>
</el-table-column>
我给不一样的列做一个判断,当需要展示的时候,我就在tab的事件里面将标志位改为true,将对应的数据展示出来,这样就可以一个表格搞定了,
我的情况属于列大部分是一样的,如果是每一个都是没关系的表格的话,我觉得还是画五个比较合适。