Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,可以高效地开发用户界面,是目前生产环境中使用最广泛的 JavaScript 框架之一
之前和很多位前端合作开发过项目,对 Vue
有一点了解,今天就用 Vue
+ Element UI
来实际开发项目
从现成的 Vue Element Admin 新建项目,目录如下:
使用到的都是目前常见的工具:代码检查、语法兼容、单元测试、样式管理等
去路由文件 src/router/index.js
建好菜单,选几个适合的 icon
,就开始开发业务了:
搜索
一般我们页面上方都是搜索的筛选项,新建个盒子写上面,加入常见的输入框和下拉框
listQuery
是查询时传给后端的参数
<div class="app-container">
<div class="filter-container">
<el-input v-model="listQuery.name" placeholder="姓名" style="width: 150px;" class="filter-item" @keyup.enter.native="handleFilter" />
<el-select v-model="listQuery.company_id" placeholder="公司" clearable filterable class="filter-item" style="width: 150px;margin-left: 10px;">
<el-option v-for="item in companyOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
</div>
事件
@keyup.enter.native
:为了操作方便,在输入框打完字后按回车就能查询,不需要再移动鼠标去点击按钮
下拉框的选项是后端直接提供的不分页的接口:
单个引入接口
import { getAllCompany } from '@/api/member'
export default {
data() {
return {
companyOptions: null
}
},
created() {
this.getCompanyOptions()
},
methods: {
getCompanyOptions() {
getAllCompany().then(response => {
this.companyOptions = response.data
})
}
}
}
再加上 2 个按钮,第一部分就完成了:
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button>
<script>
fetchData() {
// 调接口
},
handleFilter() {
this.fetchData()
}
</script>
表格
然后是中间的正文,<el-table>
属性 | 意义 |
---|---|
v-loading |
加载效果 |
:data |
绑定后端数据 |
highlight-current-row |
鼠标 hover 效果 |
border |
边框 |
@cell-click |
单元格点击事件 |
<el-table v-loading="listLoading" :data="list" element-loading-text="Loading" border fit highlight-current-row @cell-click="handleCellClick" style="font-size: small">
<el-table-column label="ID" width="70" align="center">
<template slot-scope="scope">
{{ scope.row.id }}
</template>
</el-table-column>
<el-table-column label="姓名" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
</el-table>
为了美观还加了些 <el-tag>
<i>
等
上下排列的样式
display: flex;flex-flow: column;text-align: left;
单元格点击方法是统一触发的,需要自己判断是哪一列:
需要实现
电话
字段需要默认展示中间带 号的,点击一次显示不带 的,第二次复制到剪贴板
handleCellClick(row, column, cell, event) {
if (column.label === '电话') {
row.hidden_mobile = row.mobile
if (row.copy_status) {
this.$copyText(row.mobile).then(() => {
this.$message({
message: '复制成功:' + row.mobile,
type: 'success'
})
})
}
row.copy_status = true
}
if (column.label === '跟进动态') {
// TODO
}
}
需要用到
npm install vue-clipboard2
,并在 main.js 中引入import VueClipboard from 'vue-clipboard2'
由于我更熟悉后端字符串处理,就分开传了 2 个值,处理前 hidden_mobile
与处理后的 mobile
分页
分页就用 Element UI
的了,自己新建一个组件:
<template>
<div :class="{'hidden':hidden}" class="pagination-container">
<el-pagination :background="background" :current-page.sync="currentPage" :page-size.sync="pageSize" :layout="layout" :page-sizes="pageSizes" :total="total" v-bind="$attrs" @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
</div>
</template>
<style scoped>
.pagination-container {
background: #fff;
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
</style>
引入这个分页组件:
<pagination v-show="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="fetchData" />
把相关字段准备好:
import Pagination from '@/components/Pagination'
export default {
components: { Pagination },
data() {
return {
list: null,
total: 0,
listLoading: true,
listQuery: {
page: 1,
limit: 20,
name: undefined,
mobile: undefined
}
}
}
}
完成上面空着的方法:
import { getSaleList } from '@/api/member'
fetchData() {
this.listLoading = true
getSaleList(this.listQuery).then(response => {
this.list = response.data.items
this.total = response.data.total
this.listLoading = false
})
},
handleFilter() {
this.listQuery.page = 1 // 有分页后加上页数
}
自动搜索:
created() {
this.fetchData()
}