# 🇨🇳前端手册

# 项目结构

以下目录均在src目录下

目录 说明
api 存放接口定义文件
assets 存放静态资源
components 存放组件
core 存放全局方法
core/directives 存放自定义指令
core/filters 存放自定义过滤器
core/plugins 存放插件
core/authorize 存放权限验证方法
core/store 存放vuex store文件
core/utils 存放工具脚本
layouts 存放布局组件
router 存放路由文件
views 存放页面

# DEBUG模式

如果接口进行了加密,那么查看请求参数和响应结果是非常不方便的。Eva为诸如此类的情况提供了DEBUG模式,开启DEBUG模式只需要调整一下配置即可。如下

# DEBUG模式,on开启,off关闭
VUE_APP_DEBUG = 'on'
1
2

这样在每次请求时都会在控制台打印请求参数和响应结果明文。你也可以用其来控制更多的内容,你可以像下面这样来判断是否为debug模式。

export default {
  created() {
    // 获取是否为debug模式
    console.log(this.$isDebugging)
  }
}
1
2
3
4
5
6

# 父组件

# BaseDict/字典选择器父组件

BaseDict为字典选择器组件的父组件。为了更灵活,在该组件中提供了dataList(从客户端配置中读取字典列表并根据code找到对应字典和字典数据) 方法和一些基本数据接收。

# BaseTable/列表页父组件

BaseTable为列表页面组件的父组件。为了使得开发列表页面更简单,在BaseTable中封装了分页、删除、批量删除等功能,列表页面组件只需继承她后进行简单的配置即可完成这些功能。

# BaseOpera/新建&编辑页父组件

BaseOpera为新建&编辑页的父组件,在Eva中,新建和编辑被单独抽离成组件,以将展示和数据操作功能分离,这样可以更好的进行代码复用和维护。而BaseOpera则默认实现了新建/编辑功能,操作页面组件只需继承她后进行简单的配置即可完成这些功能。

# 全局对象/方法

全局通用的方法都在core/plugins目录下以插件的方式进行定义,Eva将通用的方法归类成对象。如下

# $tip/提示

$tip对象用于提示信息,它定义在plugins/message.js中,它有如下方法

方法 说明 参数
apiSuccess 接口调用成功提示 提示消息
apiFailed 接口调用失败提示 错误对象
info 信息提示 详见Message组件 (opens new window)
success 成功提示 详见Message组件 (opens new window)
warning 警告提示 详见Message组件 (opens new window)
error 错误提示 详见Message组件 (opens new window)

示例1: 以下代码为接口调用的信息提示





 



 


// 调用创建接口
create()
  .then(() => {
    // 接口调用成功
    this.$tip.apiSuccess('创建成功')
  })
  .catch(e => {
    // 接口调用失败
    this.$tip.apiFailed(e)
  })
1
2
3
4
5
6
7
8
9
10

示例2: 以下代码为各方法调用示例,与element-ui的Message用法保持一致

this.$tip.info('信息')
this.$tip.success('成功')
this.$tip.warning('警告')
this.$tip.error('错误')
1
2
3
4

更多用法可查阅element-ui Message组件 (opens new window)

为什么需要apiSuccess和apiFailed

项目开发中不难遇到难搞的产品经理,TA可能会要求你修改接口调用后的提示形式(如操作失败了需要一个二次确认框,以防止用户没有留意到错误提示)。这样我们可以直接调整apiFailed方法的实现来快速完成。

# $dialog/对话框

$dialog对象用于做对话框的提醒,如二次确认等,它定义在plugins/messagebox.js文件中,它有如下方法

方法 说明 参数
success 成功对话框 message确认消息;title标题;delay延迟时间,默认300
deleteConfirm 删除操作二次确认对话框 message确认消息
disableConfirm 禁用操作二次确认对话框 message确认消息
exportConfirm 导出操作二次确认对话框 message确认消息
attentionConfirm 重要提醒 message确认消息;title标题,默认"重要提醒";confirmButtonText确认按钮文案,默认"知道了"
alert 提示对话框 详见MessageBox组件 (opens new window)
confirm 确认对话框 详见MessageBox组件 (opens new window)
prompt 携带输入框的对话框 详见MessageBox组件 (opens new window)
close 关闭对话框 详见MessageBox组件 (opens new window)

示例: 删除确认和禁用确认


 





 


















// 成功对话框
this.$dialog.success('成功')

// 唤起删除确认对话框
this.$dialog.deleteConfirm('确认删除该记录吗?')
  .then(() => {
    // 处理确认逻辑
  })

// 唤起禁用确认对话框
this.$dialog.disableConfirm('确认禁用该记录吗?')
  .then(() => {
    // 处理禁用逻辑
  })

// 唤起禁用确认对话框
this.$dialog.exportConfirm('确认导出吗?')
  .then(() => {
    // 处理导出逻辑
  })

// 唤起重要提醒确认对话框
this.$dialog.attentionConfirm('操作成功,用户需重新登录后生效')
  .then(() => {
  })
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

更多用法可查阅element-ui MessageBox组件 (opens new window)

# $cache/缓存

$cache对象用于处理缓存。我们并不建议您直接使用sessionStorage或localStorage,因为项目的缓存策略可能发生变化,通过$cache对象做一层调用代理则是一个不错的选择。

方法列表

方法 说明 参数
set 添加/覆盖缓存 key缓存键;value缓存值;timeout超时时间,单位毫秒,-1表示不超时
get 从缓存中获取值 key缓存键
remove 删除缓存记录 key缓存键

属性列表

对象名称 缓存类型
session 会话级缓存,通过sessionStorage实现
local 本地级缓存,通过localStorage实现(默认)
memory 内存级缓存,通过store实现(默认)

示例

// 写入字符串
this.$cache.set('key1', 'value1')

// 写入数字
this.$cache.set('key2', 1)

// 写入布尔
this.$cache.set('key3', true)

// 写入对象
this.$cache.set('key4', {value: 'value4'})

// 写入数组
this.$cache.set('key5', [{index: 0}])

// 写入日期
this.$cache.set('key6', new Date(1650767673917))

// 设置超时时间
this.$cache.set('key7', 'value7', 3000)

// 获取缓存值
console.log('key1', this.$cache.get('key1')) // 'value1'
console.log('key2', this.$cache.get('key2')) // 1
console.log('key3', this.$cache.get('key3')) // true
console.log('key4', this.$cache.get('key4')) // { value: 'value4' }
console.log('key5', this.$cache.get('key5')) // [{ index: 0 }]
console.log('key6', this.$cache.get('key6')) // Date:1650767673917
console.log('key7', this.$cache.get('key7')) // 'value7'
setTimeout(() => {
  console.log('key7', this.$cache.get('key7')) // null
}, 3000)

// 写入sessionStorage
this.$cache.session.set('key8', 'value8')

// 从sessionStorage中获取值
console.log(this.$cache.session.get('key8')) // 'value8'
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

# $consts/常量

$consts对象用于存放项目中的常量。将常量定义在项目/src/plugins/consts文件中即可。

定义常量

export default {
  TEST: 'TEST VALUE'
}
1
2
3

读取常量

console.log(this.$consts.TEST)
1

# $download/下载文件

download方法用于下载文件流,当接口返回流时,可通过该方法进行下载处理。该方法需要结合接口download 配置使用,详见标记为导出/下载接口。该方法参数如下

参数 说明 默认值
response 接口响应对象
decode 是否需通过decodeURI解码文件名称 true
mime 流的类型 application/octet-stream
filename 文件名 application/octet-stream

解码文件名称?

导出/下载接口返回流的同时会标记流对应的文件名称,为了保证文件名称不存在乱码的问题,文件名称在后端通过encodeURI来转码。并且将其写入响应头eva-download-filename 属性中。download方法将自动从该响应头属性中获取并对齐解码。

# $c/获取系统配置值

$c方法用于获取系统配置值。

参数 说明
code 配置编码

示例:

console.log(this.$c('DEFAULT_USER_GENDER')) // 输出MALE
1

# $d/获取字典/字典数据标签

$d方法用于获取字典标签或字典数据标签。

参数 说明
code 配置编码

示例:

console.log(this.$d('GENDERS')) // 输出性别
console.log(this.$d('GENDERS.MALE')) // 输出男
1
2

# $dc/获取字典数据配置方法

$dc方法用于获取字典数据中的“其他配置”字段值。

参数 说明
code 配置编码

示例:

console.log(this.$dc('GENDERS.MALE')) // 输出null,因为MALE数据中没有配置
1

# $dayjs/dayjs对象

dayjs对象可以为现代浏览器解析、验证、操作和显示日期和时间,在eva4引入了dayjs对象并封装为$dayjs全局方法,使用方法和dayjs对象一致,详见dayjs官网 (opens new window)

# $isTesting/判断是否为测试模式

可以通过$isTesting属性判断是否为测试模式。

示例:

console.log(this.$isTesting)
1

# $isDebugging/判断是否为DEBUG模式

可以通过$isDebugging属性判断是否为DEBUG模式。

示例:

console.log(this.$isDebugging)
1

# $getImageURL/获取图片访问路径

通过$getImageURL方法将传入的图片fileKey拼接.env文件配置VUE_APP_COMMON_IMAGE_PREFIX属性后返回图片的访问路径。

参数 说明
fileKey 图片的fileKey

示例:

<img :src="$getImageURL(fileKey)">
1

# $getAttachURL/获取附件下载路径

通过$getAttachURL方法将.env文件配置VUE_APP_COMMON_ATTACH_PREFIX属性拼接传入的附件fileKey后如果附件名不为空则在后拼接上附件名,最后返回附件下载路径。

参数 说明
fileKey 附件的fileKey
filename 附件名

# 列表页的实现

列表页包含分页 & 删除 & 批量删除 & 条件搜索 & 导出 & 重置代码功能,虽然这些可以自动生成,但我们仍有必要为您讲解其实现步骤。

HTML


<TableLayout>
  <!-- 搜索表单 -->
  <template #search-form>
    <SearchForm
      ref="searchForm"
      :model="searchForm"
      label-width="80px"
    >
      <el-form-item label="条件1" prop="condition">
        <el-input
          v-model="searchForm.condition"
          v-trim placeholder="请输入搜索条件"
          @keypress.enter.native="search"
        />
      </el-form-item>
      <template #buttons>
        <el-button
          type="primary"
          icon="el-icon-search"
          @click="search"
        >
          搜索
        </el-button>
        <el-button @click="reset">重置</el-button>
      </template>
    </SearchForm>
  </template>
  <!-- 表格部分 -->
  <template #table-wrap>
    <SearchTable
      v-loading="isWorking.search"
      :data="tableData.list"
      :default-sort="{ prop: 'createdAt', order: 'descending' }"
      :fullscreen.sync="fullscreen"
      buttons-width="310px"
      @refresh="refresh"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
    >
      <template #toolbar>
        <el-button>表格上方工具栏</el-button>
      </template>
      <template #buttons>
        <el-button>行操作栏</el-button>
      </template>
    </SearchTable>
    <!-- 表格分页 -->
    <pagination
      @size-change="handleSizeChange"
      @current-change="handlePageChange"
      :pagination="tableData.pagination"
    >
    </pagination>
  </template>
</TableLayout>
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

JAVASCRIPT


 



 










 
 
 
 
 
 
 
 
 
 




// 引入BaseTable组件
import BaseTable from '@/components/base/BaseTable'

export default {
  ...
  // 继承BaseTable
  extends: BaseTable,
  data() {
    return {
      // 搜索条件
      searchForm: {
        condition: ''
      }
    }
  },
  created() {
    // 配置页面
    this.config({
      module: '订单',
      api: '/order', // 对应/api/order.js
      sorts: [{
        property: 'CREATE_TIME', // 数据库字段名称
        direction: 'DESC' // 排序方式,ASC升序,DESC降序
      }],
      'field.id': 'orderId', // 主键,默认为'id'
      'field.main': 'orderNo' // 主字段,默认为'name'
    })
  }
}
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

HTML代码中所使用到的数据和方法均来源于BaseTable组件,如果默认的方法实现不能满足您的需求,您可以直接在methods 中重写。下面是this.config参数列表和继承的方法列表。

# config方法参数

参数 说明
module 模块名称
api 接口文件地址,指定api下的路径即可
sorts 默认排序
field.id 主键字段
field.main 主字段,删除操作时用于做提示内容的字段

# 继承的方法

方法名称 说明 参数
config 配置页面 见config方法参数
search 列表搜索
exportExcel 导出Excel
reset 搜索重置
handleSizeChange 页容量变化处理函数,用于绑定pagination组件的size-change事件 pageSize页容量(一页展示多少条记录)
handlePageChange 页码变化处理函数,用于绑定pagination组件的current-change事件 pageIndex变化后的页码
handleSelectionChange 行选中事件处理函数,用于绑定el-table的selection-change事件 selectedRows已选中的行对象
handleSortChange 排序事件处理函数,用于绑定el-table的sort-change事件 sortData排序字段信息
refresh 刷新列表
deleteById 根据ID删除,用于绑定行删除按钮click事件 row当前删除的行,childConfirm当列表为树列表时,删除父元素时是否弹出确认删除字元素的窗口
deleteByIdInBatch 根据已选中的行进行删除删除,用于绑定批量删除按钮click事件 childConfirm当列表为树列表时,存在选中父元素进行删除时是否弹出确认删除字元素的窗口
__getSearchForm 用于获取搜索表单对象
__afterDelete 内置方法,用于做删除后处理 deleteCount删除数
__checkApi 用于检查接口是否配置,在调用接口时调用

如果某些操作跟业务不匹配,可以直接在页面文件中覆盖对应的方法。例如当前页面无需分页,则可以覆盖handlePageChange 方法,丢弃页码直接查询所有即可。

约定

  1. 在接口文件中应该按以下命名和参数进行接口定义
  • 分页接口:export function fetchPage (data)
  • 导出Excel接口:export function exportExcel (data)
  • 根据ID删除:export function deleteById (id)
  • 批量删除:export function deleteByIdInBatch (ids)
  1. 查询条件对象应该在data中定义为searchForm。且用于做搜索的表单组件应按下列属性进行定义(ref固定为searchForm)

<SearchForm ref="searchForm">
  <el-form-item></el-form-item>
</SearchForm>
1
2
3
4

# 新增 & 编辑的实现

跟分页 & 删除 & 批量删除一样,虽然新增 & 编辑的代码页可以自动生成,但我们仍有必要为您讲解其实现步骤。

HTML


<GlobalWindow
  :title="title"
  :visible.sync="visible"
  :confirm-working="isWorking"
  @confirm="confirm"
>
  <el-form :model="form" ref="form" :rules="rules"></el-form>
</GlobalWindow>
1
2
3
4
5
6
7
8
9

JAVASCRIPT


 



 



 
 
 















// 引入BaseOpera组件
import BaseOpera from '@/components/base/BaseOpera'

export default {
  ...
  // 继承BaseOpera
  extends: BaseOpera,
  data() {
    return {
      // 表单数据
      form: {
        orderId: null,
        otherField: ''
      },
      // 验证规则
      rules: {}
    }
  },
  created() {
    // 配置组件接口文件
    this.config({
      api: '/order', // 对应/api/order.js
      'field.id': 'orderId'
    })
  }
}
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

HTML代码中所使用到的数据和方法均来源于BaseOpera组件,如果默认的方法实现不能满足您的需求,您可以直接在methods 中重写。下面是this.config参数列表和继承的方法列表。

# config方法参数

参数 说明
api 接口文件地址,指定api下的路径即可
field.id 主键字段

# 继承的方法

方法名称 说明 参数
config 配置页面 见config方法参数
open 打开窗口方法 title窗口标题,target编辑的对象
confirm 确认操作方法,用于绑定确认按钮click事件
__confirmCreate 确认新建方法
__confirmEdit 确认编辑方法
__getForm 用于获取新增编辑表单对象

约定

  1. Eva约定在接口文件中应该按以下命名和参数进行接口定义
  • 新建:export function create (data)
  • 修改:export function updateById (data)
  1. 新建/编辑表单的数据应该在data中定义为form,并且表单组件应按下列属性进行定义

<el-form ref="form"></el-form>
1
2

# 接口的定义

虽然我们可以为您生成很多功能,但我们并不能揣测您的页面中存在的业务功能。如果需要为这些业务功能添加接口,那么你需要在src/api 目录下找到对应接口定义文件(js文件),然后添加对应的接口定义。如下

export function myInterface(data) {
  return request.post('/xxx/myInterface', data, {
    // config
  })
}
1
2
3
4
5

# 接口参数的自动去空

有时候我们希望接口的参数自动去掉两侧的空格,那么可以添加trim参数,如下



 



export function myInterface(data) {
  return request.post('/xxx/myInterface', data, {
    trim: true
  })
}
1
2
3
4
5

# 标记为导出/下载接口

当我们的接口为一个导出/下载接口时,意味着接口返回的是一个流,此时我们需要调整接口的responseType,为了使用方便和增强统一维护的能力。Eva提供了download标识。如下



 



export function exportExcel(data) {
  return request.post('/xxx/myInterface', data, {
    download: true
  })
}
1
2
3
4
5

标记为download后将自动为接口设置responseType为blob。下载接口在调用完成后需要对流进行下载( 详见download方法),如下:

exportExcel({...})
  .then(response => {
    this.download(response)
  })
  .catch(e => {
    this.$tip.apiFailed(e)
  })
1
2
3
4
5
6
7

# 接口数据缓存处理

版本:v1.4.1,如您需要使用此方案且您使用的是v1.4.1之前的版本,请在gitee issue中提出。

有时候我们希望部分接口的数据可以缓存下来,在下次调用时优先从缓存中获取。Eva提供了这样的处理方案,并且十分好用。

# 定义接口

export function fetchList() {
  return request.cache('MY_CACHE_KEY').get('/myinterface')
}
1
2
3

# 调用接口

fetchList()
  .cache()
  .then(data => {
    // data为优先从缓存中获取的数据
  })
1
2
3
4
5

保留原始调用

如果在某些情况下我们希望不从缓存中获取,那么我们在调用时去掉cache即可。如下

fetchList()
  .then(data => {
    // data始终为从接口中获取的数据
  })
1
2
3
4

# 接口加密处理

# 接口的加密

如果接口需要加密请求参数,则可以在定义接口时标记一下。如下

// GET
export function getData(data) {
  return request.get('/xxx/xxxx', {
    params: data,
    secure: true
  })
}

// POST
export function postData(data) {
  return request.post('/xxx/xxxx', data, {
    secure: true
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

这样在调用接口时会自动为参数加密,并且也会自动为响应解密。

注意

  1. 如果是上传接口,即contentType以'multipart/form-data'开头的,都是不会加密的。
  2. 如果是下载接口,即响应头包含eva-opera-type为download的接口,都是不会解密的。

# 修改密钥

密钥应当与后端保持一致,修改密钥如下

.env

# 加密请求密钥
VUE_APP_ENCRYPT_REQUEST_KEY = '0000111100001111' # 16位
VUE_APP_ENCRYPT_REQUEST_IV = '1111222211112222' # 16位
1
2
3

前端密钥应当与后端密钥保持一致,否则无法正确的加解密。

# 开启2FA认证

跟处理加密一样,也只是在定义接口时处理下即可,如下

// 任意请求方式
export function create(data) {
  return request.twoFA().post('/xxx/xxxx', data)
}
1
2
3
4

这样在调用接口时将自动弹出2FA认证窗口,并在发送请求时自动添加认证参数。也可以为2FA认证窗口设置参数,如下

// 任意请求方式
export function create(data) {
  return request.twoFA({
    title: '确认删除',
    message: '输入密码以继续删除',
    confirmText: '确认删除'
  }).post('/xxx/xxxx', data)
}
1
2
3
4
5
6
7
8

参数说明详见2FA认证窗口

# 权限控制

Eva提供了v-roles, v-permissions指令和全局方法$hasRoles, $hasAnyRoles, $hasPermissions$hasAnyPermissions方法。

  • v-roles: 用于验证是否包含某角色,当值存在多个角色时为"或者"关系。

<button v-roles="['admin']"></button>
1
2
  • $hasRoles: 用于验证是否包含所有角色。
this.$hasRoles(['admin', 'test'])
1
  • $hasAnyRoles: 用于验证是否包含任意指定角色。
this.$hasAnyRoles(['admin', 'test'])
1
  • v-permissions: 用于验证是否包含某权限,当值存在多个角色时为"或者"关系。

<button v-permissions="['system:user:create']"></button>
1
2
  • $hasPermissions: 用于验证是否包含所有权限。
this.$hasPermissions(['system:user:create'])
1
  • $hasAnyPermissions: 用于验证是否包含任意指定权限。
this.$hasAnyPermissions(['system:user:create'])
1

No 1. el-table-column无法使用v-roles和v-permissions来完成列的控制,当出现这种问题时,需要结合v-if和全局权限控制方法来代替指令。 :::

# 字段排序的实现

在实现字段排序前,请确保您的列表页已继承BaseTable组件。

表格添加监听排序变化事件



 




<SearchTable
  ...
  @sort-change="handleSortChange"
></SearchTable>
1
2
3
4
5

其中handleSortChange来自BaseTable组件。

在列上标记排序字段



 
 




<el-table-column
  ...
  sortable="custom"
  sort-by="EMP_NO"
></el-table-column>
1
2
3
4
5
6

其中sortable属性用于标记列可排序,sort-by属性用于设置排序的字段名称。

默认排序

如果需要给列表添加默认排序,则需要调整两处地方。如下

No 1: 列表上添加默认排序字段,使排序箭头默认按照设置高亮。



 





<SearchTable
  ...
  :default-sort="{ prop: 'createdAt', order: 'descending' }"
>
</SearchTable>
1
2
3
4
5
6

No 2: 配置默认排序字段,使列表初始化时就按照指定字段进行排序。





 
 
 
 






export default {
  created() {
    this.config({
      ...
        sorts
  :
    [{
      property: 'CREATE_TIME',
      direction: 'DESC'
    }]
  })
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 代码格式化

在项目根目录下执行以下命令即可。

npm run fix
1

# 关闭EsLint

删除package.json文件中eslintConfig属性即可。

# 项目上下文路径的配置

如果发布项目时需要携带项目路径,如/myproject,则可以通过.env文件进行配置,如下

# 环境通用配置

# 项目上下文路径
VUE_APP_CONTEXT_PATH = '/'

# 接口前缀
VUE_APP_API_PREFIX = '/api'
1
2
3
4
5
6
7

注意,前端框架在v2.3.0之前的版本需要执行coderd eva fix-client命令,问题编号选择OPT-context-path以优化项目上下文处理后才可进行此配置。

# 接口代理配置

接口前缀配置

接口前缀指的是代理接口的路径,如/api,前缀配置在环境配置文件的VUE_APP_API_PREFIX变量中。调整后需重启服务。

接口地址配置

接口地址配置在文件vue.config.jsdevServer.proxy.target属性中。调整后需重启服务。

# 环境配置及环境变量的命名规范

默认情况下,Eva拥有三个环境,但拥有四个环境配置文件。如下

  • .env: 用于配置所有环境公用的环境变量
  • .env.development:配置开发环境的环境变量
  • .env.staging:配置测试环境的环境变量
  • .env.production:配置生产环境的环境变量

注意

环境变量必须以VUE_APP_开头,且除了开发环境外,其他环境的NODE_ENV都应该为production 。详细内容请参考vue-cli官方:模式和环境变量部分 (opens new window)

# 自定义图标

如果系统图标和Element-UI的图标不能满足您的需求,您可以前往iconfont (opens new window) 选取您喜欢的图标,加入购物车后,在购物车中将图标添加至你的项目中并下载文件。 随后在项目public/目录下新建一个目录文件如my-icons,在下载的图标文件中将iconfont.cssiconfont.ttficonfont.wofficonfont.woff2四个文件复制到my-icons中。 最后在项目public/index.html文件中引入my-icons文件即可使用。

引入示例

<link
  rel="stylesheet"
  href="<%= BASE_URL %>my-icons/iconfont.css?v=<%= htmlWebpackPlugin.options.version %>"
>
1
2
3
4

使用示例

<Icon class="iconfont icon-file"/>
1

# 自定义菜单图标

自定义菜单图标在菜单管理中的菜单图标中新建即可。使用本地图标需要先完成自定义图标步骤。

# 输入框自动去除两侧空格

添加v-trim指令即可,如下


<el-input v-trim/>
1
2

v-trim生效的组件

v-trim在原生input和textarea以及Element-UI的<el-textarea/><el-input/>组件生效。

# 内容复制


<el-button
  v-clipboard:copy="formattedContent"
  v-clipboard:success="copySuccess"
  v-clipboard:error="copyFailed"
>复制
</el-button>
1
2
3
4
5
6
7
参数 说明
v-clipboard:copy 需要复制的内容
v-clipboard:success 复制成功处理函数
clipboard:error 复制失败处理函数