# 2.1. Element-UI 表单操作

前端中后台项目基本使用 Element-UI库, 而中后台项目其实大多数是表单操作, 所以本文重点介绍表单使用

# 简介

# 基本用法

  1. 初始化项目
vue create element-test

1
2
  1. 安装
npm i element-ui -S

1
2
  1. Vue 插件
import ElementUI from 'element-ui'

Vue.use(ElementUI)

1
2
3
4
  1. 引用样式
import 'element-ui/lib/theme-chalk/index.css'

1
2
  1. element-ui 案例
<template>
  <div id="app">
    <el-button @click="show">点我</el-button>
  </div>
</template>

<script>
export default {
  name: 'app',
  methods: {
    show() {
      this.$message.success('Toast from element-ui')
    }
  }
}
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 按需加载

对项目进行打包:

npm run build

1
2

发现 vendors 库高达 789KB

-rw-r--r--  1 sam  staff   789518 10 27 20:40 chunk-vendors.cd583f5b.js

1
2

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

  1. 安装 babel-plugin-component
npm install babel-plugin-component -D

1
2
  1. 修改 babel.config.js:
{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

1
2
3
4
5
6
7
8
9
10
11
12
13
  1. 按需引入 Button 和 Message
import { Button, Message } from 'element-ui'

Vue.component(Button.name, Button)
Vue.prototype.$message = Message

1
2
3
4
5

TIP

style 引用可以去掉

重新构建,vendors 体积减小到 113KB

-rw-r--r--  1 sam  staff  113282 10 27 20:50 chunk-vendors.3d7d02b2.js

1
2

# 插件引用

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

vue add element

1
2

# 表单基本用法

  1. el-form 容器,通过 model 绑定数据
  2. el-form-item 容器,通过 label 绑定标签
  3. 表单组件通过 v-model 绑定 model 中的数据
<template>
  <div id="app">
    <el-form  
        :model="data" 
        :rules="userRules"
        ref="userRefs"
        label-width="100px"
        label-position="left">
      <el-form-item label="用户名" prop="user">
        <el-input v-model="data.user" placeholder="审批人"></el-input>
      </el-form-item>
      <el-form-item label="籍贯" prop="region">
        <el-select v-model="data.region" placeholder="籍贯">
          <el-option label="长沙" value="changsha"></el-option>
          <el-option label="常德" value="changde"></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() {
    return {
      data: {
        user: '星城哈哈',
        region: 'changsha'
      }
    }
  },
  methods: {
    onSubmit() {
      this.$refs.userRefs.validate(async valid => {
        if (!valid) return
        const { data: res } = await this.$http.post(
          'categories',
          this.ureForm
        )
        if (res.code !== 200) {
          return this.$messaage.error('添加数据失败')
        }
        this.$message.success('添加数据成功')
        // 更新列表
        this.getCateList()
        // 关闭对话框
        this.addCateDialogVisible = false
      })
    }
  }
}
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

# 表单校验基本用法

  1. 定义校验规则,可以绑定到 el-form 或 el-form-item
  2. 指定 el-form-item 的 prop 属性
const createProbleField = {
    user: "用户名",
};
export default {
  data() {
    // 自定义验证方法
    const userValidator = (rule, value, callback) => {
      if (!value) {
        callback(
          new Error(createProbleField[rule.field] + " 为必填项")
        )
      } else {
        callback()
      }
    }
    return {
      data: {
        user: '星城哈哈',
        region: 'changsha'
      },
      userRules: {
        user: [
          // { required: true, trigger: 'change', message: '用户名必须录入' },
          { validator: userValidator, trigger: 'blur' }
        ]
      }
    }
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 表单校验相关属性

  • hide-required-asterisk:隐藏必录标识
  • inline-message:验证消息是否在一行显示

# 表单校验高级用法

# 用法一:动态改变校验规则

  1. rules 只包含一个校验规则
{
  rules: {
      user: [
        { required: true, trigger: 'change', message: '用户名必须录入' },
      ]
  }
}

1
2
3
4
5
6
7
8
  1. 动态添加 rules
addRule() {
    const userValidator = (rule, value, callback) => {
      if (value.length > 3) {
        this.inputError = ''
        this.inputValidateStatus = ''
        callback()
      } else {
        callback(new Error('用户名长度必须大于3'))
      }
    }
    const newRule = [
      ...this.rules.user,
      { validator: userValidator, trigger: 'change' }
    ]
    this.rules = Object.assign({}, this.rules, { user: newRule })
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 用法二:手动控制校验状态

TIP

  • 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
2
3
4
5
6
7
8
9
  1. 自定义 status 和 error
showError() {
  this.status = 'error'
  this.error = '用户名输入有误'
},
showSuccess() {
  this.status = 'success'
  this.error = ''
},
showValidating() {
  this.status = 'validating'
  this.error = ''
}

1
2
3
4
5
6
7
8
9
10
11
12
13

# 表单属性解析

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

1
2
3
4
5
  • size:设置表单组件尺寸
/* el-input */
inputSize() {
  return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
_elFormItemSize() {
  return (this.elFormItem || {}).elFormItemSize;
}
/* el-form-item */
elFormItemSize() {
  return this.size || this._formSize;
},
_formSize() {
  return this.elForm.size;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 案例

<template>
  <div id="app">
    <el-form
        :model="data"
        style="width: 500px"
        label-position="left"
        label-width="100px"
        label-suffix=""
        :inline="false"
        :rules="rules"
        :disabled="false"
        status-icon
        validate-on-rule-change
        hide-required-asterisk
        :inline-message="false"
    >
      <el-form-item
          label="用户名"
          prop="user"
          :error="error"
          :validate-status="status"
      >
        <el-input v-model="data.user" placeholder="用户名" clearable></el-input>
      </el-form-item>
      <el-form-item label="活动区域" prop="region">
        <el-select v-model="data.region" placeholder="活动区域" style="width:100%">
          <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-button type="primary" @click="addRule">添加校验规则</el-button>
        <el-button @click="showError">错误状态</el-button>
        <el-button @click="showSuccess">正确状态</el-button>
        <el-button @click="showValidating">验证状态</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
  export default {
    name: 'app',
    data() {
      return {
        data: {
          user: 'sam',
          region: '区域二'
        },
        error: '',
        status: '',
        rules: {
          user: [
            { required: true, trigger: 'change', message: '用户名必须录入' }
          ]
        }
      }
    },
    methods: {
      /* eslint-disable */
      onSubmit() {
        console.log(this.data)
      },
      addRule() {
        const userValidator = (rule, value, callback) => {
          if (value.length > 3) {
            this.inputError = ''
            this.inputValidateStatus = ''
            callback()
          } else {
            callback(new Error('用户名长度必须大于3'))
          }
        }
        const newRule = [
          ...this.rules.user,
          { validator: userValidator, trigger: 'change' }
        ]
        this.rules = Object.assign({}, this.rules, { user: newRule })
      },
      showError() {
        this.status = 'error'
        this.error = '用户名输入有误'
      },
      showSuccess() {
        this.status = 'success'
        this.error = ''
      },
      showValidating() {
        this.status = 'validating'
        this.error = ''
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
上次更新: 2021/4/5 下午12:34:13