Element-ui 入门

1,737 阅读4分钟

1. 简介

2. 基本用法

  1. 初始化项目
vue create element-test
  1. 安装
npm i element-ui -S
  1. Vue插件
//main.js

import ElementUI from 'element-ui'

Vue.use(ElementUI)
  1. 引用样式
//main.js

import 'element-ui/lib/theme-chalk/index.css'

3. 按需加载

对项目进行打包

npm run build

发现 vendors 库高达 783KB

js/chunk-vendors.94d0b4a5.js (783 KiB)

这是由于我们未使用按需加载,对 element-ui 进行全量打包的结果。按需加载的用法如下:

  1. 安装 babel-plugin=component
npm install babel-plugin-component -D
  1. 修改babel.config.js:
//babel.config.js

module.exports = {
    ...
    plugins: [
        [
            'component',
            {
                libraryName: 'element-ui',
                styleLibraryName: 'theme-chalk'
            }
        ]
    ]
}
  1. 按需引入 Button 和 Message
//main.js

import {Button,Message} from 'element-ui'

Vue.component(Button.name,Button)//参数1:组件名称,参数2:组件的构造函数
Vue.prototype.$message = Message

style 的引用可以去掉

4. 插件引用

可以通过 element 插件快速集成 element-ui

vue add element

5. 表单的基本用法

  1. el-form 容器,通过 model 绑定数据
  2. el=form-item 容器,通过 label 绑定标签
  3. 表单组件通过 v-model 绑定 model 中的数据
  4. :rules 或者用 ref 来做校验
<template>
    <div id="app">
        <el-form inline :model="data" :rules="rules" ref="form">
            <el-form-item label="审批人" prop="user">
                <el-input v-model="data.user" placeholder="审批人"></el-input>
            </el-form-item>
            <el-form-item label="活动区域">
                <el-select v-model="data.region" placeholder="活动区域">
                    <el-option label="区域一" value="shanghai"></el-option>
                    <el-option label="区域二" value="beijing"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="onSubmit">查询</el-button>
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
    export default {
        name: 'app',
        data() {
            const userValidator = (rule, value, callback) => {
                if (value.length > 3) {
                    callback()
                } else {
                    callback(new Error('用户名长度必须大于3'))
                }
            }
            return {
                data: {
                    user: 'sam',
                    region: '区域二'
                },
                rules: {
                    user: [
                        {required: true, trigger: 'change', message: '用户名必须输入'},
                        {validator: userValidator, trigger: 'change'}
                    ]
                }
            }
        },
        methods: {
            onSubmit() {
                console.log(this.data)
                this.$refs.form.validate((isValidate, errors) => {
                    console.log(isValidate, errors)
                })
            }
        }
    }
</script>

6. 表单校验的高级用法

6.1 动态改变校验规则

  1. rules 只包含一个校验规则
{
    rules:{
        user:[
            {required:true,trigger:'change',message:'用户名必须录入'}
        ]
    }
}
  1. 动态添加 rules
    addRule() {
        //1.创建一个校验规则
        const userValidator = (rule, value, callback) => {
            if (value.length > 3) {
                this.inputError = ''
                this.inputValidateStatus = ''
                callback()
            } else {
                callback(new Error('用户名长度必须大于3'))
            }
        }
        //2.生成新的校验规则对象
        const newRule = [
            ...this.rules.user,
            {validator: userValidator, trigger: 'change'}
        ]
        //3.将新的校验规则赋值给 rules
        this.rules = Object.assign({}, this.rules, {user: newRule})
    }    
  1. 不立即校验
<el-form validate-on-rule-change=“false”></el-form> 

6.2 手动控制校验状态

  • validate-status:验证状态,枚举值,共四种:
    • success:验证成功
    • error:验证失败
    • validating:验证中
    • (空):未验证
  • error:自定义错误提示
  1. 设置 el-form-item 属性
<el-form-item
              label='用户名'
              prop='user'
              :error='error'
              :validate-status='status'>
    <!--...-->
</el-form-item>
  1. 自定义 status 和 error
<template>
    <div id="app">
        <el-form inline
                 :model="data"
                 validate-on-rule-change
                 status-icon>
            <!--2.将error,status 关联到:error和:validate-status -->
            <el-form-item
                    label="审批人"
                    prop="user"
                    :validate-status="status"
                    :error="error">
                <el-input v-model="data.user" placeholder="审批人"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="success" @click="showSuccess">成功校验</el-button>
                <el-button type="danger" @click="shoError">失败校验</el-button>
                <el-button type="warning" @click="showValidating">校验中</el-button>
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
    export default {
        name: 'app',
        data() {
            return {
                //1.自定义error,status
                error: '',
                status: '',
                data: {
                    user: 'sam',
                },
            }
        },
        //3. 给error,status 赋值,即可改变校验状态
        methods: {
            shoError() {
                this.status = 'error'
                this.error = '用户名输入有误'
            },
            showSuccess() {
                this.status = 'success'
                this.error = ''
            },
            showValidating() {
                this.status = 'validating'
                this.error = ''
            }
        }
    }
</script>

7 表单属性解析*

  • label-position:标签位置,枚举值,left 和 top
  • label-width:标签宽度
  • label-suffix:标签后缀
  • inline:行内表单
  • disabled:设置整个 form 中的表单组件全部 disabled,优先级低于表单组件自身的 disabled
/* el-input 源码 */
inputDisabledd(){
    return this.disabled || (this.elForm || {}).disabled;
}
  • size:设置表单组件尺寸
/* el-input */
inputSize(){
    return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
_elFormItemSize(){
    return (this.elFormItem || {}).elFormItemSize;
}

8. Vuex 和 vue-router

8.1 Vuex 实现原理

Vuex 的原理关键:使用 Vue 实现管理状态

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
    {{data}}
</div>
<div id="app2">
    {{data2}}
</div>
<div id="app3">
    <button @click="change">change</button>
</div>
<script>
    function registerPlugin(Vue) {
        const vuex = {}
        vuex._vm = new Vue({
            data: {
                message: 'hello vue.js'
            }
        })
        vuex.state = vuex._vm
        vuex.mutations = {
            setMessage(value) {
                vuex.state.message = value
            }
        }

        function init() {
            this.$store = vuex
        }

        Vue.mixin({
            beforeCreate: init
        })
    }

    Vue.use(registerPlugin)
    new Vue({
        el: '#app',
        computed: {
            data() {
                return this.$store.state.message
            }
        }
    })
    new Vue({
        el: '#app2',                                                                 
        computed: {
            data2() {
                return this.$store.state.message
            }
        }
    })
    new Vue({
        el: '#app3',
        methods: {
            change() {
                const newValue = this.$store.state.message + '.'
                this.$store.mutations.setMessage(newValue)
            }
        }
    })
</script>
</body>
</html>

8.2 vue-router 路由守卫

创建 router.js

import Vue from 'Vue'
import Route from 'vue-router'
import HelloWorld from './components/HelloWorld'

Vue.use(Route)
const routes = [
    {
        path:'/hello-world',component:HelloWorld
    }
]
const router = new Route({
    routes
})
export default router

在 main.js 中引用 router,并加入 vue 实例

import router from './router'

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

全局守卫

//路由触发调用
router.beforeEach((to,from,next)=>{
    console.log('beforeEach',to,from)
    next()
})
//路由解析调用
router.beforeResolve((to,from,next)=>{
     console.log('beforeResolve',to,from)
    next()
})
//路由进入后调用
router.afterEach((to,from)=>{
    console.log('afterEach',to,from)
})

局部守卫

//路由进入
router.beforeEnter((to,from,next)=>{
    console.log('beforeEnter',to,from)
    next()
})
//路由更新
router.beforeRouteUpdate((to,from,next)=>{
     console.log('beforeRouteUpdate',to,from)
    next()
})
//路由离开
router.beforeRouteLeave((to,from)=>{
    console.log('beforeRouteLeave',to,from)
})

8.3 路由元信息

//1.写入meta元信息
const routes = [
    {path: '/a', component: A, meta: {title: 'A'}},
    {path: '/b', component: B},
    {path: '/hello-world', component: HelloWorld, meta: {title: 'HelloWorld'}}
]
const router = new Route({
    routes
})
//2.路由守卫中获取元信息进行处理
router.beforeEach((to, from, next) => {
    console.log('beforeEach', to, from)
    if (to.meta.title) {
        document.title = to.meta.title
    }else{
        document.title = 'default'
    }
    next()
})

//给所有的组件都注入进去(不推荐)*
Vue.mixin({
    beforeCreate() {
        console.log('beforeCreate',this.$router,this.$route)
        if (this.$route.meta.title) {
            document.title = this.$route.meta.title
        }else{
            document.title = 'default'
        }
    }
})

8.4 vue-router API的使用

使用 router.addRoutes 动态添加路由

addRoute(){
    this.$router.addRoutes([{
        path:'/b',component:B,meta:{title:'Custom Title B'}
    }])
}

此时可以访问到 B 组件

<router-link to='/b'>to B</router-link>

9 前端框架的搭建

9.1 项目初始化

git clone https://github.com/PanJiaChen/vue-element-admin.git
cd vue-element-admin
npm i
npm run dev

9.2 项目精简

  • 删除 src/views 下的源码,保留:
    • dashboard:首页
    • error-page:异常页面
    • login:登录
    • redirect:重定向
  • 对 src/router/index 进行相应的修改
  • 删除 src/router/modules 文件夹
  • 删除 src/vendor 文件夹

如果是线上项目,建议将 components 的内容也进行清理,以免影响访问速度,或者直接使用 vue-admin-template 构建项目,选择 vue-element-admin 初始化项目,是因为 vue-element-admin 实现了登录模块,包括 token 校验、网络请求等,可以简化开发工作。

9.3 项目配置

通过 src/settings.js 进行全局配置

  • title:站点标题,进入某个页面后,格式为:
页面标题 - 站点标题
  • showSetting:是否显示右侧悬浮配置按钮
  • tagsView:是否显示页面标签功能条
  • fixedHeader:是否将头部布局固定
  • sidebarLogo:菜单栏中是否显示LOGO
  • errorLog:默认显示错误日志的环境

9.4 源码调试

如果需要进行源码调试,需要修改 vue.config.js

config
	//https://webpack.js.org/configuration/devtool/#development
	.when(process.env.NODE_ENV === 'development',
         config => config.devtool('cheap-source-map'))

将 cheap-source-map 改为 source-map,如果希望提升构建速度可以改为 eval

通常建议开发时保持 eval 配置,以增加构建速度,当出现需要源码调试排查问题的时候改为 srouce-map