iview学习笔记

1,669 阅读5分钟

iview 配置

全局配置

Vue.use(iView, {
    size: 'large',
    transfer: 'true' 
})
  • size可以配置全局的button的大小
  • transfer则是配置select等的下拉悬浮是基于全局定位还是父盒子定位。作用是,让overflow 的时候,不受盒子的影响。

自定义主题

npm i less@2.7.3 --save-dev

npm i less-loader --save-dev

// coustom.less
@import '~iview/src/styles/index.less';
@primary-color: pink;

多语言配置

使用一种语言

import locale from 'iview/dist/locale/en-US'

Vue.use(iView, {
    size: 'large',
    transfer: 'true',
    locale
})

切换多语言

// main.js
import VueI18n from 'vue-i18n'
import zh from 'iview/dist/locale/zh-CN'
import en from 'iview/dist/locale/en-US'

Vue.config.productionTip = false

Vue.use(VueI18n)
// 下面是覆盖Vue的locale 防止报错
Vue.locale = () => {}

const messages = {
  en: Object.assign({message: 'hello'}, en),
  zh: Object.assign({message: '你好'}, zh)
}
const i18n = new VueI18n({
  locale: 'zh',
  messages
})

new Vue({
  render: h => h(App),
  i18n
}).$mount('#app')

// 使用,在vue中如下:

{{$t("message")}}

iview-loader 的使用

统一 iView 标签书写规范,所有标签都可以使用首字母大写的形式,包括 Vue 限制的两个标签 Switch 和 Circle

  • 以下设置基于vuecli3.0
// vue.config.js
module.exports = {
    // 默认设置: https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-service/lib/config/base.js
    chainWebpack: config => {
    // 使用 iView Loader
        config.module
            .rule('vue')
            .test(/\.vue$/)
            .use('iview-loader')
            .loader('iview-loader')
            .tap(() => {
                return {
                    prefix: false
                }
            })
            .end();
    }
};

导航路由鉴权篇

3.0导航菜单跳转方式

<Menu>
    <MenuItem to="/home" name="home">
      Home
    </MenuItem>
    <MenuItem to="/about" target="_blank" replace>
      Home
    </MenuItem>
  </Menu>

to="/home" 跳转 target="_blank" 新窗口打开 replace 不保留历史 name 菜单高亮

根据当前路由选择对应菜单

<Menu :active-name="activeName">
    <MenuItem to="/" name="/home">
      Home
    </MenuItem>
    <MenuItem to="/about" name="/about">
      About
    </MenuItem>
 </Menu>
<script>
    export default {
        data() {
            return {
                activeName: this.$route.path
            }
        },
        watch: {
            $route(val, old) {
                this.activeName = this.$route.path
            }
        }
    }
</script>

activeName 根据router动态配置。

在路由级别对页面做鉴权

// router
{
  path: '/admin',
  name: 'admin',
  meta: {
    type: 'login'
  },
  component: () => import(/* webpackChunkName: "about" */ './views/admin.vue')
}
// main.js

router.beforeEach((to, from, next) => {
  const type = to.meta.type;
  if (type === 'login') {
    if (window.localStorage.getItem('login')) {
      next()
    } else {
      next('/login')
    }
  } else {
    next()
  }
})

可以根据路由里面的meta标签来进行鉴权。

根据不同的平台动态路由不同的组件

// route.js

const ua = window.navigator.userAgent;
let isMobile = false;

if (ua.indexOf('iPhone') >=0 ) isMobile = true;
if (ua.indexOf('Android') >=0 ) isMobile = true;
if (ua.indexOf('iPad') >=0 ) isMobile = true;

const path = isMobile ? '/mobile' : ''


{
  path: '/admin',
  name: 'admin',
  meta: {
    type: 'login'
  },
  // route level code-splitting
  // this generates a separate chunk (about.[hash].js) for this route
  // which is lazy-loaded when the route is visited.
  component: () => import(/* webpackChunkName: "about" */ './views' + path + '/admin.vue')
},

grid 布局

可以解决大部分的布局问题

基本布局


<div id="app">
    <div style="height: 50px; position: fixed; top: 0; background: red; width: 100%;z-index: 10;"></div>
    <Row :gutter="16">
        <Col v-for="n in 20" span="1">
            <Card :title="n">
                {{n}}列
            </Card>
        </Col>
        <Col :span="4">
            <Card>
                <div style="height: 200px"></div>
            </Card>
            <Affix :offset-top="50">
                <Card>
                    <div style="height: 200px"></div>
                </Card>
            </Affix>
        </Col>
    </Row>
</div>

垂直居中

<Row type="flex" justify-content="center" align-item="center"></Row>

左右流出空白效果

<Row>
    <Col :span="4" :offset-left="1"></Col>
    <Col :span="18"></Col>
</Row>

设置默认占位

<Row>
    <Col :span="4" :offset="1"></Col>
    <div Style="height: 1px; width:100%;"></div>
</Row>

响应式

{
    xs: '480px',
    sm: '576px',
    md: '768px',
    lg: '992px',
    xl: '1200px',
    xxl: '1600px'
}
<Row>
    <Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 6, offset: 1}"></Col>
    <Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 16, offset: 0}"></Col>
</Row>

Layout

  • 基本布局方式1

  • 基本布局方式2

本节实例如下:

  1. devArtical是一个独立的Layout组件
  2. 4个页面分别对应4个菜单 App/Manage/Push/Dev ,每个组件内部使用devArtical布局。
  3. App.vue 是根文件
  4. Main.js 主入口文件,全局注册devArtival组件

具体代码如下:

  • mian.js 全局注册
// main.js
...
import devArtical from './components/dev-artical'
Vue.component('dev-artical', devArtical)
...
  • App.vue router-view展示
<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>
  • view下的4个页面引用
<template>
    <div>
        <dev-artical>
            this is manage
        </dev-artical>
    </div>
</template>
  • dev-artical 是代码最多的,所以放在最后。

首先是Lauout部分

<Layout>
    <Header></Header>
    <Layout></Layout>
</Layout>

然后是Header部分

<Header class="header">
    <Row>
        <Col :span="4" offset="1">
            <img src="../assets/logo.png" class="logo" alt="">
        </Col>
        <Col :span="14">
            <Menu mode="horizontal" :activeName="activeName">
                <MenuItem name="/app" to="/app">应用分析</MenuItem>
                // 其余菜单
            </Menu>
        </Col>
        <Col :span="4">
            <Row>
                <Col :span="8">
                    <Dropdown>
                        <Avatar src="https://dev-file.iviewui.com/avatar_default/avatar"></Avatar>
                        <DropdownMenu slot="list">
                            <DropdownItem>
                                我的主页
                            </DropdownItem>
                            <DropdownItem>
                                我的设置
                                <Badge status="error"></Badge>
                            </DropdownItem>
                            <DropdownItem divided>
                                退出登录
                            </DropdownItem>
                        </DropdownMenu>
                    </Dropdown>
                </Col>
                <Col :span="8">
                    <Dropdown>
                        <Badge :count="2" :offset="[20, 4]">
                            <Icon type="md-notifications-outline" size="24" />
                        </Badge>
                        <Tabs slot="list" value="notification">
                            <TabPane label="通知" name="notification">
                                <div class="notification">通知内容</div>
                            </TabPane>
                            <TabPane label="关注" name="follow">
                                <div class="notification">通知内容</div>
                            </TabPane>
                            <TabPane label="标签2" name="system">
                                <div class="notification">系统通知</div>
                            </TabPane>
                        </Tabs>
                    </Dropdown>
                </Col>
                <Col :span="8">
                    <Icon @click="value1=true" type="ios-color-palette-outline" size="24"/>
                </Col>
            </Row>
        </Col>
    </Row>
</Header>
.header {
    position: fixed;
    width: 100%;
    height: 60px;
    background: #fff;
    box-shadow: 0 1px 1px rgba(0,0,0,0.05);
    top: 0;
    left: 0;
    z-index: 100;
}
.logo {
    height: 50px;
    margin-top: 5px;
}
.notification {
    text-align: center;
    height: 200px;
}
.ivu-menu-horizontal.ivu-menu-light:after {
    display: none;
}
.sider {
    position: fixed;
    height: 100%;
    left: 0;
    overflow: auto;
    z-index: 1;
}
.sider-menu {
    margin-top: 60px;
}
.sider-hide .ivu-menu-item span {
    display: none;
}
.content {
    margin-left: 240px;
    margin-top: 60px;
    padding: 16px;
    transition: 0.2s all ease-in-out;
}
.content-expand {
    margin-left: 64px;
}
export default {
    data() {
        return {
            activeName: this.$route.path,
            value1: false,
            isCollapsed: false
        }
    },
    created() {
        this.activeName = this.$route.path;
    }
}

  • 服务端分页

  • 自定义序号

  • 服务端排序和过滤

  • 远程过滤

前端分页和排序、过滤

  • 前端排序、筛选

  • 过滤分页数据

  • 使用数据

可编辑单元格和整行编辑

可编辑单元格

  • 取消按钮

可编辑整行

  • 默认的修改按钮

  • 保存和取消

外部筛选、隐藏

  • badge 在表格中展示

  • 时间在表格中的展示

  • 动态请求数据

  • 重置数据

新建一行

  • Form

  • 提交

动态展示列

Table 初始化排序持久化

  • 筛选持久化

  • 过滤持久化

动态修改任意单元格class

table 的Render

纯render实现

组件

slot-scope

Form

  • iview 使用的校验库

  • 常规校验

  • 给Form去校验,用在循环上面。

  • label和input联动

  • 普通联动

  • 城市联动

  • tab 可关闭

  • Tree点击标题可以收起

  • 在某个元素里面展开抽屉非全屏

  • 模态框提交异步不关闭