# 初识 iview
iview 是我第一次入职公司接触过的第二个前端框架,第一个 layui,由于 layui 用了很久,感觉很顺手,js/jquery 写的很方便,以至于我 iview 用的有点手脚放不开,主要是 vue 的特点双向绑定,讲究最大程度的去除 js/jquery 的写法方式。最后 iview 真香
# 文档
任何框架如果文档看明白了,学习起来就轻松一半了,所以我简单的介绍下 iview 文档的常用元素的使用
//props
props指的是属性,指的就是props前面那个标签的属性 | |
如:这个截图前面标签是Menu,那么下面的属性就都是<Menu></Menu>标签属性 | |
例如:<Menu mode="String" theme ="String"></Menu> | |
也如vue一样可以双向绑定 | |
例如 this里面有个modeList | |
<Menu :mode="modeList" theme ="String"></Menu> | |
小技巧 | |
有些属性的值为boolean 不填为默认,填了则相反 | |
例如:上面的accordion 默认 false | |
<Menu accordion></Menu> //这样填了就直接默认相反为true,不需要专门写个 accordion = “true" |
//slot
<template slot="header|footer|close"></template> //替换掉固有的指定元素,如弹出层的头部,底部 | |
例如 上面第二张图可以自定义设置header|footer|close 也就是页头,页脚与右上角关闭内容 |
//events
在events 前面的元素内使用@+事件名="方法名" | |
在methods里面写上 方法名(对应返回值) | |
例如上面的:下拉框的下拉事件 | |
<select @onquery-change="sousuo"></select> //搜索词改变事件 | |
methods内有一个sousuo方法 | |
sousuo(d){console.log(d)//打印的是改变后的值,也就搜索框内当前的值,d只是个变量代指这个值。其它名字也行} |
//methods
methods该属性与events相似 都是元素的事件,但使用上有些不同 | |
this.$refs.属性上的ref名.方法名(参数) | |
例子:<select rel="nihao"></select> | |
在随便哪个方法里面,你都可以调用 this.$refs.nihao.clearSingleSelect()方法实现清空单选 |
# 遇到问题
前面讲了 iview 框架的所有组件涉及的元素使用方法,下面我记录下我在使用 iview 中遇到的扯淡问题
# form 验证数字并不能为空
// 理论写法 | |
//--required 必填 and type 为 number | |
{required: true, message: '数字且不能为空', trigger: 'blur',type:"number"} | |
// 真实写法 | |
//-- 第一种 (优点可提示文字,可自定义正则) | |
{required: true, message: '请输入', trigger: 'blur'}, | |
{type: 'string', pattern: /^\d+$/, message: '请输入数字', trigger: 'blur'} | |
//-- 第二种 (优点可提示文字) | |
{required: true, message: '请输入', trigger: 'blur'}, | |
{type: 'number', message: '请输入数字', trigger: 'blur'} | |
//-- 第三种 (优点简单) | |
<Input number> // 直接将 input 框定为 number 类型 | |
{required: true, message: '请输入', trigger: 'blur'} | |
// 附上身份正验证 | |
{type: 'string', pattern: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$|^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$/, message: '请输入正确的身份证号', trigger: 'blur'} |
# 下拉列表远程搜索
<!-- 官网参考例子:https://run.iviewui.com/ | |
涉及的 props 有 filterable 是否支持搜索 remote 是否使用远程搜索 remote-method 远程搜索的方法 rel 标识符 clearable 是否可以清空选项,单选有效 | |
涉及的 methods 有 clearSingleSelect 清空单选项,仅在 clearable="true" 时有效 | |
--> | |
<Select v-model="editTemp.uid" filterable remote clearable | |
:remote-method="selectMethod" | |
ref="agency" | |
style="width:300px"> | |
<Option v-for="item in UserList" :value="item.uid" :key="item.uid"></Option> | |
</Select> |
selectMethod(query){ | |
if (query != '' && query != null) { | |
// 这里执行异步获取数据 | |
this.UserList = // 获取到的数据 | |
} else { | |
this.UserList = []; | |
this.$refs["agency"].clearSingleSelect();//clearSingleSelect () 方法,将选中值清空 | |
} | |
}, | |
// 如果是修改功能 | |
this.$refs["agency"].query = item.realName | |
// 等于要显示的值,不是 item.uid。此时 editTemp.uid 依旧为空。 | |
// 解决方案一 后台使用 uid 为空不修改 | |
// 解决方案二 前端再定义一个属性存 uid 的值,等确认修改了再附上去 | |
// 原因:editTemp.uid 的值如果附上去 搜索功能会发生未知 bug | |
// 记录的 bug:第一次点击修改,Select 框值为空,再点一次,Select 框条件为 editTemp.uid,再点一次,Select 框条件为 item.realName | |
// 总共点击三次,第三次数据是我想要的。bug 未知, | |
// 猜想:vue 双向绑定与,select 组件渲染速度问题 | |
// 尝试解决:使用 props 中的 filter-by-label + label 解决 (失败) | |
//--------------------==============================----------------------- | |
// 总结:这是一次很有意思的尝试,但由于对 iview 框架的不熟练,以至于在细节上操作遇到阻碍 |
# table 表格功能使用
除了基本的功能,我也要记录下两个常用例子
1: 单个表格点击编辑,并修改数据库数据
{ | |
title: '物流单号', //table 表格内字段 | |
key: 'trackingNum', // 对应名字 | |
minWidth: 200, // 最小宽度 | |
render: (h, params) => { // 内部字段显示 h 为 td 内元素,params 为当前行的值 | |
if (params.row.$isEdit) { // 判断 params.row.$isEdit 元素(其实第一次元素根本不存在所有肯定为 false) | |
return h( | |
"div",{props: {}}, // 返回一个 div 元素,内部有多个元素 (也就是数组) | |
[ | |
h("Input", { | |
props: { // 设置 input 元素的属性 | |
type: "text", | |
value: params.row.trackingNum | |
}, | |
on: { | |
"on-blur": event => { | |
// 判断输入框是否为空,为空的话虚拟字段变成 “不能为空” | |
// 判断失焦后输入框的值是否为空,若为空则对 params.row.valid 赋值,下面的 span 元素也就显示这个值,用作判断 | |
if(event.target.value == ""){ | |
this.$set(params.row, 'valid', "不能为空"); | |
}else{ | |
// 不为空,即通过验证,将值附上去,然后把虚拟字段置空 | |
this.records[params.index].valid = ""; | |
// 判断新的值与原来的值是否相同 | |
if(params.row.trackingNum != event.target.value){ | |
// 更改为已发货状态 | |
this.records[params.index].cargo = 2; | |
// 使用个异步处理 (更丝滑) | |
setTimeout(function(){ | |
// 调用修改接口 | |
},0) | |
// 把旧值都替换为新输入的值 | |
params.row.trackingNum = event.target.value; | |
this.records[params.index].trackingNum = event.target.value; | |
} | |
// 将 params.row.$isEdit 状态改为 false | |
this.$set(params.row, '$isEdit', false); | |
} | |
}, | |
} | |
}),// 返回一个 input 输入框,添加了失焦事件 | |
h( | |
"span", | |
{ | |
attrs: { | |
title: params.row.valid | |
}, | |
style: { | |
color: "red" | |
} | |
}, | |
params.row.valid // 如果有值则显示,无则没有 (用于提醒操作人员不能为空) | |
) // 返回一个 span 元素 | |
] | |
); | |
} else if(params.row.cargo !=3 ) { // 判断状态时候为非已完成的 | |
return h('div', { | |
style: { | |
width: "164px", | |
height: "21px" | |
}, | |
on: { | |
click: () => { | |
this.$set(params.row, '$isEdit', true); | |
}, | |
},// 返回一个 div 元素,内部放个 params.row.trackingNum 值,加了点样式 | |
// 附上了一个点击事件,点击则 params.row.$isEdit 值为 true, 进入第一个判断 | |
},params.row.trackingNum); | |
}else{ // 如果是已经完成的状态,则正常显示不需要加上点击事件 | |
return h('div', {},params.row.trackingNum); // 返回一个 div 元素,内部放个 params.row.trackingNum 值 | |
} | |
}, | |
} |
1: 修改一行的表单数据
官方实例:https://run.iviewui.com/50ahQHrs
我做出的效果:
<Table :columns="quanyi" :data="editModelTemp.quanDate"> | |
<template slot-scope="{row,index}" slot="name"> | |
<Input type="text" v-model="editOne" v-if="editIndex === index" /> | |
<span v-else></span> | |
</template> | |
<template slot-scope="{row,index}" slot="explain"> | |
<Input type="text" v-model="editTwo" v-if="editIndex === index" /> | |
<span v-else></span> | |
</template> | |
<template slot-scope="{row,index}" slot="classify"> | |
<i-Switch true-color="#13ce66" false-color="#ff4949" true-value="2" false-value="1" v-model="editTre" v-if="editIndex === index"> | |
<span slot="open">福</span> | |
<span slot="close">权</span> | |
</i-Switch> | |
<div v-else> | |
<Tag color="error" v-if="row.classify == 1"> | |
权益 | |
</Tag> | |
<Tag color="success" v-if="row.classify == 2"> | |
福利 | |
</Tag> | |
</div> | |
</template> | |
<template slot-scope="{row,index}" slot="action"> | |
<ButtonGroup> | |
<Button type="error" @click="handleDel(index)">删除</Button> | |
<Button type="success" v-if="editIndex === index" @click="handleEemove">还原</Button> | |
<Button type="primary" v-else @click="handleEdit(row,index)">修改</Button> | |
</ButtonGroup> | |
</template> | |
</Table> | |
<!-- 思路:与官方代码思路一样 | |
因为 table 表格数据就是数组,点击修改获取当行的下标,设置 editIndex 的值,使之那一行的”editIndex === index" 成立 | |
后面就差不多,我这边的逻辑是他点击其它行或者,点击添加时,才改变那行的值,没有保存按钮。 | |
--> |
# 尾语
第一次使用 iview 框架,也算是对于我的 vue 的一次升华,因为我实际上并没系统学过 vue,我更懂的是 js,jquery。看 vue.js 的文档的时候,总是看不进去,因为自身不是很喜欢看那些例子,所有也就稍微瞄了前面几个基本章节,影响最深的就是数据的双向绑定,事件的简化,但对于其它使用还不懂。
在这次的 iview 中我感受到了 vue 的快乐,从刚开始的难受到真香。同样在 form 表单,layui 用监听获取值,vue 数据双向绑定,找错看起来极为明了。在本篇文章中也记录了我在 iview 中事,虽然有些没有记录如:百度地图,视频播放调用,如父子组件的使用,但我觉得这些东西虽然做出了,却也是拾人牙慧未能明白始末就不予记载。而且由于初入公司未曾有幸经历 iview 框架的开始到结尾。不了解 iview 是如何做权限管控,功能管控等也实属一大遗憾