初识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">{{ item.realName }}&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>{{row.name}}&lt;/span>
    &lt;/template>
    <template slot-scope="{row,index}" slot="explain">
        <Input type="text" v-model="editTwo" v-if="editIndex === index" />
        <span v-else>{{row.explain}}&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是如何做权限管控,功能管控等也实属一大遗憾