目录
一、Vue组件库Element(学会怎么CV)
之前讲解的前端开发模式MVVM,我们之前学习的vue是侧重于VM开发的,主要用于数据绑定到视图的,那么接下来我们学习的ElementUI就是一款侧重于V开发的前端框架,主要用于开发美观的页面的。
Element:是饿了么公司前端开发团队提供的一套基于 Vue 的网站组件库,用于快速构建网页。
Element 提供了很多组件(组成网页的部件)供我们使用。例如 超链接、按钮、图片、表格等等。如下图所示就是我们开发的页面和ElementUI提供的效果对比:可以发现ElementUI提供的各式各样好看的按钮
ElementUI的学习方式和我们之前的学习方式不太一样,对于ElementUI,我们作为一个后台开发者,只需要学会如何从ElementUI的官网拷贝组件到我们自己的页面中,并且做一些修改即可。其官网地址:Element - The world's most popular Vue UI frameworkElement,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.cn/#/zh-CN,我们主要学习的是ElementUI中提供的常用组件,至于其他组件可以通过我们这几个组件的学习掌握到ElementUI的学习技巧,然后课后自行学习。
快速入门
首先,我们先要安装ElementUI的组件库,打开VS Code,停止之前的项目,然后在命令行输入如下命令:
npm install element-ui@2.15.3具体操作如下图所示:
然后我们需要在main.js这个入口js文件中引入ElementUI的组件库,其代码如下:
import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
具体操作如图所示:
然后我们需要按照vue项目的开发规范,在src/views目录下创建一个vue组件文件,注意组件名称后缀是.vue,并且在组件文件中编写之前介绍过的基本组件语法,代码如下:
<template> </template> <script> export default { } </script> <style> </style>
具体操作如图所示:
最后我们只需要去ElementUI的官网,找到组件库,然后找到按钮组件,抄写代码即可,具体操作如下图所示:
然后找到按钮的代码,如下图所示:
紧接着我们复制组件代码到我们的vue组件文件中,操作如下图所示:
最后,我们需要在默认访问的根组件src/App.vue中引入我们自定义的组件,具体操作步骤如下:
然后App.vue组件中的具体代码如下,代码是我们通过上述步骤引入element-view组件时自动生成的。
<template> <div id="app"> <!-- {{message}} --> <element-view></element-view> </div> </template> <script> import ElementView from './views/Element/ElementView.vue' export default { components: { ElementView }, data(){ return { "message":"hello world" } } } </script> <style> </style>
然后运行我们的vue项目,浏览器直接访问之前的7000端口,展示效果如下图所示:
到此,我们ElementUI的入门程序编写成功
ElementUI的常用组件
接下来我们来学习一下ElementUI的常用组件,对于组件的学习比较简单,我们只需要参考官方提供的代码,然后复制粘贴即可。
1.Table表格
(1)组件演示
Table 表格:用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
接下来我们通过代码来演示。
首先我们需要来到ElementUI的组件库中,找到表格组件,如下图所示:
然后复制代码到我们之前的ElementVue.vue组件中(或者自己创建一个.vue组件文件),需要注意的是,我们组件包括了3个部分,如果官方有除了template部分之外的style和script都需要复制。具体操作如下图所示:
template模板部分:
script脚本部分
ElementView.vue组件文件整体代码如下:
<template> <div> <!-- Button按钮 --> <el-row> <el-button>默认按钮</el-button> <el-button type="primary">主要按钮</el-button> <el-button type="success">成功按钮</el-button> <el-button type="info">信息按钮</el-button> <el-button type="warning">警告按钮</el-button> <el-button type="danger">危险按钮</el-button> </el-row> <!-- Table表格 --> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="address" label="地址"> </el-table-column> </el-table> </div> </template> <script> export default { data() { return { tableData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄' }, { date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1516 弄' }] } } } </script> <style> </style>
此时回到浏览器,我们页面呈现如下效果:
(2)组件属性详解
那么我们的ElementUI是如何将数据模型绑定到视图的呢?主要通过如下几个属性:
data: 主要定义table组件的数据模型
prop: 定义列的数据应该绑定data中定义的具体的数据模型
label: 定义列的标题
width: 定义列的宽度
其具体示例含义如下图所示:
Element组件的所有属性都可以在组件页面的最下方找到,如下图所示:
2.Pagination分页
(1)组件演示
Pagination: 分页组件,主要提供分页工具条相关功能。其展示效果图下图所示:
首先在官网找到分页组件,我们选择带背景色分页组件,如下图所示:
然后复制代码到我们的ElementView.vue组件文件的template中,拷贝如下代码:
<el-pagination background layout="prev, pager, next" :total="100"> </el-pagination>
浏览器打开呈现如下效果:
(2)组件属性详解
对于分页组件我们需要关注的是如下几个重要属性(可以通过查阅官网组件中最下面的组件属性详细说明得到):
background: 添加北京颜色,也就是上图蓝色背景色效果。
layout: 分页工具条的布局,其具体值包含
sizes
,prev
,pager
,next
,jumper
,->
,total
,slot
这些值total: 数据的总数量
我们修改layout属性如下:
layout="sizes,prev, pager, next,jumper,total"
浏览器打开呈现如下效果:
(3)组件事件详解
对于分页组件,除了上述几个属性,还有2个非常重要的事件我们需要去学习:
size-change : pageSize 改变时会触发
current-change :currentPage 改变时会触发
对于这2个事件的参考代码,我们同样可以通过官方提供的完整案例中找到,如下图所示:
然后我们找到对应的代码,首先复制事件,复制代码如下:
@size-change="handleSizeChange" @current-change="handleCurrentChange"
此时Panigation组件的template完整代码如下:
<!-- Pagination分页 --> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" background layout="sizes,prev, pager, next,jumper,total" :total="1000"> </el-pagination>
紧接着需要复制事件需要的2个函数,需要注意methods属性和data同级,其代码如下:
methods: { handleSizeChange(val) { console.log(`每页 ${val} 条`); }, handleCurrentChange(val) { console.log(`当前页: ${val}`); } },
此时Panigation组件的script部分完整代码如下:
<script> export default { methods: { handleSizeChange(val) { console.log(`每页 ${val} 条`); }, handleCurrentChange(val) { console.log(`当前页: ${val}`); } }, data() { return { tableData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄' }, { date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1516 弄' }] } } } </script>
回到浏览器中,我们f12打开开发者控制台,然后切换当前页码和切换每页显示的数量,呈现如下效果:
3.Dialog对话框
(1)组件演示
Dialog: 在保留当前页面状态的情况下,告知用户并承载相关操作。其企业开发应用场景示例如下图所示:
首先我们需要在ElementUI官方找到Dialog组件,如下图所示:
然后复制如下代码到我们的组件文件的template模块中
<br><br> <!--Dialog 对话框 --> <!-- Table --> <el-button type="text" @click="dialogTableVisible = true">打开嵌套表格的 Dialog</el-button> <el-dialog title="收货地址" :visible.sync="dialogTableVisible"> <el-table :data="gridData"> <el-table-column property="date" label="日期" width="150"></el-table-column> <el-table-column property="name" label="姓名" width="200"></el-table-column> <el-table-column property="address" label="地址"></el-table-column> </el-table> </el-dialog>
并且复制数据模型script模块中:
gridData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }], dialogTableVisible: false,
然后我们打开浏览器,点击按钮,呈现如下效果:
(2)组件属性详解
那么ElementUI是如何做到对话框的显示与隐藏的呢?是通过如下的属性:
visible.sync :是否显示 Dialog
具体释意如下图所示:
visible属性绑定的dialogTableVisble属性一开始默认是false,所以对话框隐藏;然后我们点击按钮,触发事件,修改属性值为true,
然后对话框visible属性值为true,所以对话框呈现出来。
4.Form表单
(1)组件演示
Form 表单:由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。
表单在我们前端的开发中使用的还是比较多的,接下来我们学习这个组件,与之前的流程一样,我们首先需要在ElementUI的官方找到对应的组件示例:如下图所示:
我们的需求效果是:在对话框中呈现表单内容,类似如下图所示:
所以,首先我们先要根据上一小结所学习的内容,制作一个新的对话框,其代码如下:
<br><br> <!-- Dialog对话框-Form表单 --> <el-button type="text" @click="dialogFormVisible = true">打开嵌套Form的 Dialog</el-button> <el-dialog title="Form表单" :visible.sync="dialogFormVisible"> </el-dialog>
还需要注意的是,针对这个新的对话框,我们需要在data中声明新的变量dialogFormVisible来控制对话框的隐藏与显示,代码如下:
dialogFormVisible: false,
然后我们复制官网提供的template部分代码到我们的vue组件文件的Dialog组件中,但是,此处官方提供的表单项标签太多,所以我们只需要保留前面3个表单项组件,其他多余的删除,所以最终template部分代码如下:
<el-dialog title="Form表单" :visible.sync="dialogFormVisible"> <el-form ref="form" :model="form" label-width="80px"> <el-form-item label="活动名称"> <el-input v-model="form.name"></el-input> </el-form-item> <el-form-item label="活动区域"> <el-select v-model="form.region" placeholder="请选择活动区域"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="活动时间"> <el-col :span="11"> <el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker> </el-col> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">立即创建</el-button> <el-button>取消</el-button> </el-form-item> </el-form> </el-dialog>
观察上述代码,我们发现其中表单项标签使用了v-model双向绑定,所以我们需要在vue的数据模型中声明变量,同样可以从官方提供的代码中复制粘贴,但是我们需要去掉我们不需要的属性,通过观察上述代码,我们发现双向绑定的属性有4个,分别是form.name,form.region,form.date1,form.date2,所以最终数据模型如下:
form: { name: '', region: '', date1: '', date2:'' },
同样,官方的代码中,在script部分中,还提供了onSubmit函数,表单的立即创建按钮绑定了此函数,我们可以输入表单的内容,而表单的内容是双向绑定到form对象的,所以我们修改官方的onSubmit函数如下即可,而且我们还需要关闭对话框,最终函数代码如下:
onSubmit() { console.log(this.form); //输出表单内容到控制台 this.dialogFormVisible=false; //关闭表案例的对话框 }
5. 四个重要组件的演示代码
<template>
<div>
<!-- Button按钮 -->
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
<!-- Table表格 -->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
<br>
<!-- Pagination分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
background
layout="sizes,prev, pager, next,jumper,total"
:total="1000">
</el-pagination>
<br><br>
<!--Dialog 对话框 -->
<!-- Table -->
<el-button type="text" @click="dialogTableVisible = true">打开嵌套表格的 Dialog</el-button>
<el-dialog title="收货地址" :visible.sync="dialogTableVisible">
<el-table :data="gridData">
<el-table-column property="date" label="日期" width="150"></el-table-column>
<el-table-column property="name" label="姓名" width="200"></el-table-column>
<el-table-column property="address" label="地址"></el-table-column>
</el-table>
</el-dialog>
<br><br>
<!-- Dialog对话框-Form表单 -->
<el-button type="text" @click="dialogFormVisible = true">打开嵌套Form的 Dialog</el-button>
<el-dialog title="Form表单" :visible.sync="dialogFormVisible">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
export default {
methods: {
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
},
//表单案例的提交事件
onSubmit() {
console.log(this.form); //输出表单内容到控制台
this.dialogFormVisible=false; //关闭表案例的对话框
}
},
data() {
return {
//表单案例的数据双向绑定
form: {
name: '',
region: '',
date1: '',
date2:''
},
gridData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}],
dialogTableVisible: false,
dialogFormVisible: false, //控制form表单案例的对话框
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</script>
<style>
</style>
二、异步数据加载
1.异步加载数据
<!-- 表格 -->
<el-table :data="tableData">
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="image" label="图像" width="180"></el-table-column>
<el-table-column prop="gender" label="性别" width="140"></el-table-column>
<el-table-column prop="job" label="职位" width="140"></el-table-column>
<el-table-column prop="entrydate" label="入职日期" width="180"></el-table-column>
<el-table-column prop="updatetime" label="最后操作时间" width="230"></el-table-column>
<el-table-column label="操作" >
<el-button type="primary" size="mini">编辑</el-button>
<el-button type="danger" size="mini">删除</el-button>
</el-table-column>
</el-table>
对于上面element表格,我们只差最后的数据了,需要我们从后端加载数据,而数据的mock地址已经提供:http://yapi.smart-xwork.cn/mock/169327/emp/list
我们最后要做的就是异步加载数据,所以我们需要使用axios发送ajax请求。
在vue项目中,对于axios的使用,分为如下2步:
安装axios: npm install axios
需要使用axios时,导入axios: import axios 'axios'
接下来我们先来到项目的执行终端,然后输入命令,安装axios,具体操作如下图所示:
然后重启项目,来到我们的EmpView.vue组件页面,通过import命令导入axios,代码如下:
import axios 'axios';
那么我们什么时候发送axios请求呢?页面加载完成,自动加载,所以可以使用之前的mounted钩子函数,并且我们需要将得到的员工数据要展示到表格,所以数据需要赋值给数据模型tableData,所以我们编写如下代码:
mounted(){ axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list") .then(resp=>{ this.tableData=resp.data.data; //响应数据赋值给数据模型 }); }
到这里是不够完美的,性别是1和2,图像是一个地址,这两个地方需要处理
2.性别内容展示修复
首先我们来到ElementUI提供的表格组件,找到如下示例:
我们仔细对比效果和功能实现代码,发现其中涉及2个非常重要的点:
template : 用于自定义列的内容
slot-scope: 通过属性的row获取当前行的数据
所以接下来,我们可以通过上述的标签自定义列的内容即可,修改性别列的内容代码如下:
<el-table-column prop="gender" label="性别" width="140"> <template slot-scope="scope"> {{scope.row.gender==1?"男":"女"}} </template> </el-table-column>
此时打开浏览器,效果如下图所示:性别一列的值修复成功
3.图片内容展示修复
图片内容的修复和上述一致,需要借助template标签自定义列的内容,需要需要展示图片,直接借助img标签即可,并且需要设置图片的宽度和高度,所以直接修改图片列的代码如下:
<el-table-column prop="image" label="图像" width="180"> <template slot-scope="scope"> <img :src="scope.row.image" width="100px" height="70px"> </template> </el-table-column>
此时回到浏览器,效果如下图所示:图片展示修复成功
4.修复后完整代码
<template>
<div>
<!-- 设置最外层容器高度为700px,在加上一个很细的边框 -->
<el-container style="height: 700px; border: 1px solid #eee">
<el-header style="font-size:40px;background-color: rgb(238, 241, 246)">tlias 智能学习辅助系统</el-header>
<el-container>
<el-main>
<!-- 表格 -->
<el-table :data="tableData">
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="image" label="图像" width="180">
<template slot-scope="scope">
<img :src="scope.row.image" width="100px" height="70px">
</template>
</el-table-column>
<el-table-column prop="gender" label="性别" width="140">
<template slot-scope="scope">
{{scope.row.gender==1?"男":"女"}}
</template>
</el-table-column>
<el-table-column prop="job" label="职位" width="140"></el-table-column>
<el-table-column prop="entrydate" label="入职日期" width="180"></el-table-column>
<el-table-column prop="updatetime" label="最后操作时间" width="230"></el-table-column>
<el-table-column label="操作" >
<el-button type="primary" size="mini">编辑</el-button>
<el-button type="danger" size="mini">删除</el-button>
</el-table-column>
</el-table>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import axios 'axios'
export default {
data() {
return {
tableData: [
]
}
},
methods:{
onSubmit:function(){
console.log(this.searchForm);
}
},
mounted(){
axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list")
.then(resp=>{
this.tableData=resp.data.data;
});
}
}
</script>
<style>
</style>
三、Vue路由
1.作用
用于页面的跳转,类似于超链接a标签
2.需求
我们希望基于下面案例中的功能,实现点击侧边栏的部门管理,显示部门管理的信息,点击员工管理,显示员工管理的信息,效果如下图所示:
3.原理
前端Vue路由:URL中的hash(#号之后的内容)与组件之间的对应关系,如下图所示:
当我们点击左侧导航栏时,浏览器的地址栏会发生变化,路由自动更新显示与url所对应的vue组件。
而我们vue官方提供了路由插件Vue Router,其主要组成如下:
VueRouter:路由器类,根据路由请求在路由视图中动态渲染选中的组件
router-link:请求链接组件,浏览器会解析成a
router-view:动态视图组件,用来渲染展示与路由路径对应的组件
其工作原理如下图所示:
首先VueRouter根据我们配置的url的hash片段和路由的组件关系去维护一张路由表;
然后我们页面提供一个router-link组件,用户点击,发出路由请求;
接着我们的VueRouter根据路由请求,在路由表中找到对应的vue组件;
最后VueRouter会切换router-view中的组件,从而进行视图的更新
4.路由入门
首先我们需要先安装vue-router插件,可以通过如下命令
npm install vue-router@3.5.1但是我们不需要安装,因为当初我们再创建项目时,已经勾选了路由功能,已经安装好了。
然后我们需要在src/router/index.js文件中定义路由表,根据其提供的模板代码进行修改,最终代码如下:
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [ { path: '/emp', name: 'emp', component: ()=> import('../views/tlias/EmpView.vue') }, { path: '/dept', name: 'dept', component: () => import('../views/tlias/DeptView.vue') }, { path: '/', //redirect打开网址重定向到dept redirect:'/dept' }, ] const router = new VueRouter({ routes }) export default router
在main.js中,我们已经引入了router功能,如下图所示:
路由基本信息配置好了,路由表已经被加载,此时我们还缺少2个东西,就是router-lin和router-view,所以我们需要修改2个页面(EmpView.vue和DeptView.vue)我们左侧栏的2个按钮为router-link,其代码如下:
<el-menu-item index="1-1"> <router-link to="/dept">部门管理</router-link> </el-menu-item> <el-menu-item index="1-2"> <router-link to="/emp">员工管理</router-link> </el-menu-item>
然后我们还需要在内容展示区域即App.vue中定义route-view,作为组件的切换,其App.vue的完整代码如下:
<template> <div id="app"> <!-- {{message}} --> <!-- <element-view></element-view> --> <!-- <emp-view></emp-view> --> <router-view></router-view> </div> </template> <script> // import EmpView './views/tlias/EmpView.vue' // import ElementView './views/Element/ElementView.vue' export default { components: { }, data(){ return { "message":"hello world" } } } </script> <style> </style>
到这里,启动前端Vue项目就可以通过Vue路由进行页面跳转了。