# 初识 iview

iview 是我第一次入职公司接触过的第二个前端框架,第一个 layui,由于 layui 用了很久,感觉很顺手,js/jquery 写的很方便,以至于我 iview 用的有点手脚放不开,主要是 vue 的特点双向绑定,讲究最大程度的去除 js/jquery 的写法方式。最后 iview 真香

# 文档

任何框架如果文档看明白了,学习起来就轻松一半了,所以我简单的介绍下 iview 文档的常用元素的使用

//props

props指的是属性,指的就是props前面那个标签的属性
如:这个截图前面标签是Menu,那么下面的属性就都是<Menu>&lt;/Menu>标签属性
例如:<Menu mode="String" theme ="String">&lt;/Menu>
也如vue一样可以双向绑定
例如 this里面有个modeList
	<Menu :mode="modeList" theme ="String">&lt;/Menu>
小技巧
	有些属性的值为boolean 不填为默认,填了则相反
	例如:上面的accordion 默认 false
	<Menu accordion>&lt;/Menu> //这样填了就直接默认相反为true,不需要专门写个 accordion = “true"

//slot

<template slot="header|footer|close">&lt;/template> //替换掉固有的指定元素,如弹出层的头部,底部
例如 上面第二张图可以自定义设置header|footer|close 也就是页头,页脚与右上角关闭内容

//events

在events 前面的元素内使用@+事件名="方法名"
在methods里面写上 方法名(对应返回值)
例如上面的:下拉框的下拉事件
		<select @onquery-change="sousuo">&lt;/select> //搜索词改变事件
methods内有一个sousuo方法
		sousuo(d){console.log(d)//打印的是改变后的值,也就搜索框内当前的值,d只是个变量代指这个值。其它名字也行}

//methods

methods该属性与events相似 都是元素的事件,但使用上有些不同
this.$refs.属性上的ref名.方法名(参数)
例子:<select rel="nihao">&lt;/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">&lt;/Option>
&lt;/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>&lt;/span>
    &lt;/template>
    <template slot-scope="{row,index}" slot="explain">
        <Input type="text" v-model="editTwo" v-if="editIndex === index" />
        <span v-else>&lt;/span>
    &lt;/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">&lt;/span>
            <span slot="close">&lt;/span>
        &lt;/i-Switch>
        <div v-else>
            <Tag  color="error" v-if="row.classify == 1">
                权益
            &lt;/Tag>
            <Tag color="success" v-if="row.classify == 2">
                福利
            &lt;/Tag>
        &lt;/div>
    &lt;/template>
    <template slot-scope="{row,index}" slot="action">
        <ButtonGroup>
            <Button type="error" @click="handleDel(index)">删除&lt;/Button>
            <Button type="success" v-if="editIndex === index" @click="handleEemove">还原&lt;/Button>
            <Button type="primary" v-else @click="handleEdit(row,index)">修改&lt;/Button>
        &lt;/ButtonGroup>
    &lt;/template>
&lt;/Table>
<!-- 思路:与官方代码思路一样
因为 table 表格数据就是数组,点击修改获取当行的下标,设置 editIndex 的值,使之那一行的”editIndex === index" 成立
后面就差不多,我这边的逻辑是他点击其它行或者,点击添加时,才改变那行的值,没有保存按钮。
-->

# 尾语

第一次使用 iview 框架,也算是对于我的 vue 的一次升华,因为我实际上并没系统学过 vue,我更懂的是 js,jquery。看 vue.js 的文档的时候,总是看不进去,因为自身不是很喜欢看那些例子,所有也就稍微瞄了前面几个基本章节,影响最深的就是数据的双向绑定,事件的简化,但对于其它使用还不懂。

在这次的 iview 中我感受到了 vue 的快乐,从刚开始的难受到真香。同样在 form 表单,layui 用监听获取值,vue 数据双向绑定,找错看起来极为明了。在本篇文章中也记录了我在 iview 中事,虽然有些没有记录如:百度地图,视频播放调用,如父子组件的使用,但我觉得这些东西虽然做出了,却也是拾人牙慧未能明白始末就不予记载。而且由于初入公司未曾有幸经历 iview 框架的开始到结尾。不了解 iview 是如何做权限管控,功能管控等也实属一大遗憾

更新于 阅读次数