一. 脚手架搭建webpack项目
1.创建工程
创建一个JavaScript工程
注意:要使用vue-cli搭建webpack项目,项目名不能有大写
2. 脚手架搭建webpack项目
-
vue init webpack - 使用Vue的脚手架工具【vue-cli】初始化一个webpack项目
-
路由之前全部选y或者按回车(视情况而定),路由之后全部选n
-
最后选npm管理工程
3. 运行并访问
-
启动项目:npm run dev
-
访问:localhost:8080
4. 回顾脚手架项目执行流程
1. 当执行npm run dev时,
package.json
webpack.dev.conf.js
webpack.base.conf.js
2. 找到打包入口main.js,打包以后将这个文件放到index.html自动注入进来
3. main.js中引入了vue,和根组件App,还用了路由
el用于挂载,挂载到了index.html中的div上
相当于在div中调用了这个App组件
4. 所以当访问index.html时,就是展示组件App的内容
logo要展示
路由匹配上的组件渲染到<router-view></router-view>
后面可以根据请求访问其他的组件
小结:
当访问localhost:8080,访问的是index.html。地址栏会变成:localhost:8080/#/
index.html展示的内容就是App组件中的内容 - main.js中定义了一个Vue实例挂载到index.html中
上半部分就是logo
下半部分就是请求匹配上的组件【在路由中配置的】
5. 单文件/页面组件
定义:又称单页面组件【single-file components】,以.vue结尾的文件
优势:实现了模块化,支持在组件中编写样式
包含:三个部分【结构,样式,行为【事件】】:
//html:模板template //有且仅有一个根元素
//js:导出组件
export default {
data () {//模型数据
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods:{}, //可以用来绑定事件的
mouted(){}, //钩子函数 - 页面一加载就自动执行
watch:{}, //监听模型数据
compted:{} //计算属性 - 计算模型数据的值
}
//后面会把Vue实例里面写的内容写到单页面组件中
/* css:模板中定义样式的 */
/* Add "scoped" attribute to limit CSS to this component only */
<style scoped>
</style>
开发步骤:
1. 写一个组件:拷贝并编辑
2. 配置路由:router/index.js
3. 通过组件所对应的请求地址测试访问
二. ElementUI
1. 概述
Element是一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库,类似于easyui一样,提供了很多的ui组件。
Element是一个基于vue的前端UI【图形界面】框架。是由饿了么团队开发的一套桌面UI组件库。 官网:http://element-cn.eleme.io/#/zh-CN
中文文档:Element - The world's most popular Vue UI framework
2.入门
2.1. 安装ElementUI
中文安装文档:Element - The world's most popular Vue UI framework
Element UI 可以使用cdn方式和npm方式进行安装,我们使用npm ,推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用
npm i element-ui -S
2.2. 导入ElementUI
在main.js中导入ElementUI
import ElementUI from 'element-ui' // 引入element-ui
import 'element-ui/lib/theme-chalk/index.css' // 引入element-ui的核心样式
// 使用ElementUI
Vue.use(ElementUI)
2.3. 使用ElementUI
2.3.1. 创建单文件/页面组件
拷贝HelloWorld.vue重命名为ElementUI.vue ,内容如下:
<template>
<div>
<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>
</div>
</template>
2.3.2. 配置路由
import ElementUI from '@/components/ElementUI'
//import ElementUI from '../components/ElementUI.vue' //同上
{
path: '/ele',
component: ElementUI
}
3. 常用组件
3.1. 布局Layout
类似于Bootstrap的栅格布局,ElementUI也将一行分为 24 分栏,以迅速简便地创建布局。
通过 row (行)和 col(列、栏) 组件,并通过 col 组件的 span 属性我们就可以自由地组合布局。
<template>
<div>
<el-row>
<el-col :span="24"><div class="grid-content bg-purple-dark"></div></el-col>
</el-row>
<el-row>
<el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="12"><div class="grid-content bg-purple-light"></div></el-col>
</el-row>
<!-- row组件提供 gutter 属性来指定每一栏之间的间隔,默认间隔为 0。 -->
<el-row :gutter="20">
<el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="8"><div class="grid-content bg-purple-light"></div></el-col>
<el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
</el-row>
<!-- 通过 col 组件的 offset 属性可以指定分栏偏移的栏数。 -->
<el-row>
<el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
<!-- 这个 col 组件向右偏移了6个栏数,其实就是在左边产生了6个栏数的外边距 -->
<el-col :span="6" offset="6"><div class="grid-content bg-purple"></div></el-col>
</el-row>
<!--
将 col 组件的 type 属性赋值为 'flex',可以启用 flex 布局,并可通过 justify 属性的值来指定定义子元素的排版方式,
可选值为:
start:水平方向靠左对齐
center:水平方向居中对齐
end:水平方向靠右对齐
space-between:水平方向两端对齐
space-around:在水平方向上,平分剩余盒子空间 两边和中间比例为1:2
-->
<el-row type="flex" justify="space-between">
<el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="4"><div class="grid-content bg-purple-light"></div></el-col>
<el-col :span="4"><div class="grid-content bg-purple"></div></el-col>
</el-row>
</div>
</template>
<script>
export default {
name: "TestLayout"
}
</script>
<style scoped>
.el-row {
margin-bottom: 20px;
/*&:last-child {*/
/* margin-bottom: 0;*/
/*}*/
}
/* 上面的&:last-child是less、sass的语法,代表上一级选择器,等同于以下选择器 */
.el-row:last-child {
margin-bottom: 0;
}
.el-col {
border-radius: 4px;
}
.bg-purple-dark {
background: #99a9bf;
}
.bg-purple {
background: #d3dce6;
}
.bg-purple-light {
background: #e5e9f2;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.row-bg {
padding: 10px 0;
background-color: #f9fafc;
}
</style>
3.2. 表格Table
<!-- 当el-table元素中注入data对象数组后,在el-table-column中用prop属性来对应对象中的键名即可填入数据,用label属性来定义表格的列名。可以使用width属性来定义列宽 -->
<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>
<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>
3.3. 按钮Button
<!-- 使用type、plain、round和circle属性来定义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>
<el-row>
<el-button plain>朴素按钮</el-button>
<el-button type="primary" plain>主要按钮</el-button>
<el-button type="success" plain>成功按钮</el-button>
<el-button type="info" plain>信息按钮</el-button>
<el-button type="warning" plain>警告按钮</el-button>
<el-button type="danger" plain>危险按钮</el-button>
</el-row>
<el-row>
<el-button round>圆角按钮</el-button>
<el-button type="primary" round>主要按钮</el-button>
<el-button type="success" round>成功按钮</el-button>
<el-button type="info" round>信息按钮</el-button>
<el-button type="warning" round>警告按钮</el-button>
<el-button type="danger" round>危险按钮</el-button>
</el-row>
<el-row>
<el-button icon="el-icon-search" circle></el-button>
<el-button type="primary" icon="el-icon-edit" circle></el-button>
<el-button type="success" icon="el-icon-check" circle></el-button>
<el-button type="info" icon="el-icon-message" circle></el-button>
<el-button type="warning" icon="el-icon-star-off" circle></el-button>
<el-button type="danger" icon="el-icon-delete" circle></el-button>
</el-row>
3.4. 分页Pagination
<el-pagination
background
layout="prev, pager, next"
:total="1000">
</el-pagination>
3.5. 表单Form
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="审批人">
<el-input v-model="formInline.user" placeholder="审批人"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="formInline.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>
<script>
export default{
data() {
return {
formInline: {
user: '',
region: ''
}
}
},
methods: {
onSubmit() {
console.log('submit!');
}
}
}
</script>
3.6. 消息框Message
<!-- 默认的 Message 是不可以被人工关闭的,如果需要可手动关闭的 Message可以使用showClose字段。此外,和 Notification 一样,Message 拥有可控的duration,设置0为不会被自动关闭,默认为 3000 毫秒 -->
<template>
<el-button :plain="true" @click="open1">消息</el-button>
<el-button :plain="true" @click="open2">成功</el-button>
<el-button :plain="true" @click="open3">警告</el-button>
<el-button :plain="true" @click="open4">错误</el-button>
</template>
<script>
export default {
methods: {
open1() {
this.$message({
showClose: true,
message: '这是一条消息提示'
});
},
open2() {
this.$message({
showClose: true,
message: '恭喜你,这是一条成功消息',
type: 'success'
});
//this.$message.success("恭喜你,这是一条成功消息");
},
open3() {
this.$message({
showClose: true,
message: '警告哦,这是一条警告消息',
type: 'warning'
});
},
open4() {
this.$message({
showClose: true,
message: '错了哦,这是一条错误消息',
type: 'error'
});
}
}
}
</script>
3.7. 对话框Dialog
<!-- 需要设置visible属性,它接收Boolean,当为true时显示 Dialog。Dialog 分为两个部分:body和footer,footer需要具名为footer的slot。title属性用于定义标题,它是可选的,默认值为空。最后,本例还展示了before-close的用法 -->
<el-button type="text" @click="dialogVisible = true">点击打开 Dialog</el-button>
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%"
:before-close="handleClose">
<span>这是一段信息</span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
<script>
export default {
data() {
return {
dialogVisible: false
};
},
methods: {
handleClose(done) {
this.$confirm('确认关闭?').then(_ => {
done();
}).catch(_ => {});
}
}
}
</script>
3.8. 图标Icon
<i class="el-icon-edit"></i>
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
<el-button type="primary" icon="el-icon-search">搜索</el-button>
ElementUI简单的组件这个不 一 一 做演示,可以去根据官网文档去尝试
三. ElementUI综合案例
1. 效果展示
2. 基础框架
1. 编写单文件组件:User.vue
2. 配置路由:
import User from '@/components/User'
{
path: '/user',
component: User
}
3. 访问测试:http://localhost:8080/#/user
可以去掉logo图标
3. 表格的使用
<template>
<!--
el-table:定义表格
:data="tableData":相当于以前的v-bind:data="tableData",
模板中的数据必须在组件【这里是单文件组件】,而且必须在data()中申明,
并且返回值必须是json对象
style="width: 100%":指定表格占屏幕宽度的100%
border:边框
stripe:斑马纹,隔行换色
-->
<el-table :data="tableData" border stripe style="width: 100%">
<!--
el-table-column:定义表格的列
prop="date":指定展示什么样的数据,与数据中的属性名保持一致
label="日期":表头显示的文本
width="180":指定当前列的宽度
type="selection":显示多选样式
-->
<el-table-column
type="selection"
width="55">
</el-table-column>
<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-column fixed="right" label="操作">
<template slot-scope="scope">
<el-button type="text" size="small">删除</el-button>
<el-button type="text" size="small">编辑</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
name: 'user',
data(){
return {
tableData: [] //一开始是没有数据的
}
},
mounted(){//页面被加载后,等到Vue实例挂载完毕之后再去获取实例,这个方法会自动触发
this.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>
4. mock模拟动态数据
4.1. mockjs介绍
引入:刚刚的数据写死的,数据是不应该写死的。真实情况是我们应该发请求到后端去拿数据的。但是现在是前后端并行开发,现在还没有后端,只有接口的描述。所以前端要去模拟假数据来进行测试
Mock.js (官网Mock.js)是一款数据模拟生成器,旨在帮助前端攻城师独立于后端进行开发,模拟假数据进行测试。
官方文档:Home · nuysoft/Mock Wiki · GitHub
4.2. mockjs作用
1. 根据数据模板生成模拟数据
2. 模拟后端接口,响应数据
4.3. 快速入门
4.3.1. 安装mockjs
npm install mockjs
4.3.2. 新建mockDemo.js
在当前项目下直接新建mockDemo.js
// 引入mokejs
let Mock = require("mockjs")
// 生成数据
let data = Mock.mock({
/*
* 定义生成数据的数据模板
* 格式:'name|rule': value
* 具体说明如下:
* (1)name表示属性值
* (2)rule表示生成规则
* (3)value表示属性值
*/
'abc|5':[{
'id':1,
'name':'测试'
}]
})
// 输出刚刚生成的数据
console.log(JSON.stringify(data))
4.3.3. 测试
node mockDemo.js
4.3.4. 其他规则
// 引入mockjs
let Mock = require("mockjs")
// 生成数据
// 生成一条数据
let data1 = Mock.mock({
/*
* 定义生成数据的数据模板
* 格式:'name|rule': value
* 具体说明如下:
* (1)name表示属性值
* (2)rule表示生成规则,不写则按照数据模板生成一条数据
* (3)value表示属性值
*/
'id':1,
'name':'测试'
})
// 生成一个数据集合
let data2 = Mock.mock({
'abc|5':[{
'id':1,
'name':'测试'
}]
})
// 生成多条复杂的数据
let users = Mock.mock({
'resultCode': 200,
'msg': 'success',
'totals': 20,
/*
* 数据占位符
* 占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中。
* 占位符 的格式为:
* @占位符
* @占位符(参数 [, 参数])
* 注意:
* (1)用 @ 来标识其后的字符串是 占位符。
* (2)占位符 引用的是 Mock.Random 中的方法。
* (3)通过 Mock.Random.extend() 来扩展自定义占位符。
* (4)占位符 也可以引用 数据模板 中的属性。
* (5)占位符 会优先引用 数据模板 中的属性。
*/
'data|20':[{
'id': '@increment',
'name': '@cname',
'phone': /^1[0-9]{10}$/,
'email': '@email',
'address': '@county(true)',
'createTime': '@date("yyyy-MM-dd")'
}]
})
// 输出刚刚生成的数据
console.log(JSON.stringify(users))
5. mock模拟接口
引入:虽然数据出来了,但是数据应该是通过请求调用而产生的
5.1. 接口文件user.js
在当前项目下创建一个mock的文件夹,然后在该文件夹中创建user.js
//import Mock from 'mockjs' // 引入mock方式一
let Mock=require('mockjs') // 引入mock方式二
//构建集合数据
var dataList = []
for (var i = 0; i < 53; i++) {
dataList.push(Mock.mock({
'id': '@increment',
'name': '@cname',
'phone': /^1[0-9]{10}$/,
'email': '@email',
'address': '@county(true)',
'createTime': '@date("yyyy-MM-dd")'
}))
}
//参数1:当前页 参数2:每页显示的条数 参数3:集合数据
//返回值:当前页的分页数据
function pagination(currentPage, pageSize, list) {
console.log(list);
console.log(currentPage, pageSize);//1 5
//js的slice(开始索引,结束下标)是数组的截取方法,相当于字符串的substring,也是左闭右开的
//例子:[1,2,3,4].slice(1,3) => [2,3]
//假如集合有53条数据,当前页currentPage为1,每页pageSize5条,那么就是list.slice(0,5) - 就是前5条[第一条数据,第6条数据)
//假如集合有53条数据,当前页currentPage为2,每页pageSize5条,那么就是list.slice(5,10) - 就是5-10条,就是第二页
return list.slice((currentPage-1)*pageSize, currentPage*pageSize)
}
// 获取当前页的分页数据
//参数1:发送的请求地址 参数2:发送的请求方式 参数3中opts接收调用时传递的参数
//参数3即为.vue中调用是传递的参数:{"currentPage":1,"pageSize":5}
//返回值为totals【数据总量】和 data【当前页的分页数据】
Mock.mock(new RegExp('/user/list'), 'post', (opts) => {
var list =dataList;
console.log("=======================user.js=====================");
console.log(opts);//Object { url: "/user/list", type: "POST", body: " {\"currentPage\":1,\"pageSize\":5}" }
console.log(opts.body);//{"currentPage":1,"pageSize":5} - json格式的字符串
var currentPage = JSON.parse(opts.body).currentPage;
var pageSize = JSON.parse(opts.body).pageSize;
var totals = list.length;
list = pagination(currentPage, pageSize, list)
return {
'resultCode': 200,
'msg': 'success',
'totals': totals,
'data': list
}
})
5.2. 引入user.js
//在main.js中导入该js
import user from '../mock/user.js'
6. axios调用接口
上面只是模拟了一个接口,但是这个接口还必须得调用。vue更新到2.0之后,官方推荐使用axios请求服务器数据。axios和其他的ajax库都很类似,他是基于promise的http库,可以用在浏览器和node.js中
6.1. 安装axios
npm install axios --save
或者
npm install axios -S
6.2. 使用axios调用接口
//User.vue中使用功能axios调用user.js中模拟的接口
<script>
//引入axios
import axios from "axios";
export default {
name: 'User',
data(){
return {
tableData: [] //一开始是没有数据的
pageSize: 5, //这里必须与模拟接口中的pageSize一致
currentPage: 1, // 默认为第1页
totals: 5 // 默认数据量为5
}
},
mounted(){//页面被加载后,等到Vue实例挂载完毕之后再去获取实例,这个方法会自动触发
axios.post("/user/list",{"currentPage":this.currentPage,"pageSize":this.pageSize})
.then((result)=>{
console.log(result);
// 如果结果编码为200,则表示获取数据成功
if (result.data.resultCode == 200){
// 获取数据并给tableData赋值
this.tableData = result.data.data;
// 获取实际的数据总量并给totals赋值,这样分页组件才能正确分页
this.totals = result.data.totals;
}
})
.catch((result)=>{
alert("获取数据失败!!!")
})
}
}
</script>
7. FastMock在线模拟接口
引入:使用mockjs时,每一个domain都需要一个对应的mock文件,很麻烦。而且这个文件对于后端开发工程师是比较难写的
7.1. 概述
定义:FastMock是一个提供在线模拟数据和模拟接口的工具是一个开源项目
地址:https://www.fastmock.site
在线文档:https://marvengong.gitee.io/fastmock
7.2. 基本使用
-
登录或注册:浏览器打开网址并输出用户名和密码,没有账户就注册一个
-
登录后进入主界面
-
创建项目:点击创建项目
填写项目名称,带*是必须要填写的,点击提交按钮
创建完成后可以在列表中看到刚刚创建的项目
-
创建接口,点击列表中的项目,进入项目工作台页面
点击新增接口,左侧区域定义接口名、类型 、Url 、描述等信息,右侧使用json格式定义模拟接口的返回数据
{
'resultCode': 200,
'msg': 'success',
'totals': 53,
'data|5':[{
'id': '@increment',
'name': '@cname',
'phone': /^1[0-9]{10}$/,
'email': '@email',
'address': '@county(true)',
'createTime': '@date("yyyy-MM-dd")'
}]
}
保存之后 出现下图:
注意:在操作下的四个图标可以修改,复制完整地址,可以删除,还可以测试接口
-
访问路径:BaseURL+URL
https://www.fastmock.site/mock/4a44750ca19c7a557c52ca933519ea70/pethome/user/list
7.3. axios调用在线接口
7.3.1. 注释mockjs
在main.js中注释掉mockjs模拟接口,避免测试冲突
7.3.2. 调用在线接口
//User.vue中使用功能axios调用user.js中模拟的接口
<script>
//引入axios
import axios from "axios";
export default {
name: 'User',
data(){
return {
tableData: [] //一开始是没有数据的
pageSize: 5, //这里必须与模拟接口中的pageSize一致
currentPage: 1, // 默认为第1页
totals: 5 // 默认数据量为5
}
},
mounted(){//页面被加载后,等到Vue实例挂载完毕之后再去获取实例,这个方法会自动触发
axios.post("https://www.fastmock.site/mock/89a7a85f87e3fbd775e62cf01ae96d9f/pethome/user/list", {"currentPage":this.currentPage,"pageSize":this.pageSize}).then((result)=>{
console.log(result);
// 如果结果编码为200,则表示获取数据成功
if (result.data.resultCode == 200){
// 获取数据并给tableData赋值
this.tableData = result.data.data;
// 获取实际的数据总量并给totals赋值,这样分页组件才能正确分页
this.totals = result.data.totals;
}
})
.catch((result)=>{
alert("获取数据失败!!!")
})
}
}
</script>
<!-- 注意:此刻这个currentPage和pageSize实际上是没用的,因为fastmock并没有去接收。人家给你返回什么数据,你就显示显示什么样的数据 -->
8. axios的全局使用
以上代码的问题:
1. 每写一个单文件组件都需要导入axios
//引入axios
import axios from "axios";
2. faseMock的地址太长
https://www.fastmock.site/mock/bcf5677fa589576daed7671fdea0c6aa/pethome/user/list
https://www.fastmock.site/mock/bcf5677fa589576daed7671fdea0c6aa/pethome/user/add
8.1. axios全局配置和基础路径
在mian.js中:
//引入axios
import axios from 'axios'
//配置axios的全局基本路径
axios.defaults.baseURL='https://www.fastmock.site/mock/bcf5677fa589576daed7671fdea0c6aa/pethome'
//全局属性配置:在任意组件内可以使用this.$http获取axios对象
Vue.prototype.$http = axios
8.2. User.vue修改路径
<script>
export default {
data(){
return {
tableData: [] //一开始是没有数据的
pageSize: 5, //这里必须与模拟接口中的pageSize一致
currentPage: 1, // 默认为第1页
totals: 5 // 默认数据量为5
}
},
mounted(){//页面被加载后,等到Vue实例挂载完毕之后再去获取实例,这个方法会自动触发
this.$http.post("/user/list",{"currentPage":this.currentPage,"pageSize":this.pageSize})
.then((result)=>{
console.log(result);
// 如果结果编码为200,则表示获取数据成功
if (result.data.resultCode == 200){
// 获取数据并给tableData赋值
this.tableData = result.data.data;
// 获取实际的数据总量并给totals赋值,这样分页组件才能正确分页
this.totals = result.data.totals;
}
})
.catch((result)=>{
alert("获取数据失败!!!")
})
}
}
</script>
<!-- 注意:此刻这个currentPage和pageSize实际上是没用的,因为fastmock并没有去接收。人家给你返回什么数据,你就显示显示什么样的数据 -->
9. 分页
9.1. 添加分页栏
<el-pagination
background
align="right"
layout="prev, pager, next"
:total="1000">
</el-pagination>
<!-- 注意:模板中有且有且仅有一个根元素 -->
9.2. 设置分页参数
<span style="background-color:#333333"><span style="color:#b8bfc6"><el-pagination
background
align="right"
layout="prev, pager, next"
:total="totals"
:current-page="currentPage",
:page-size="pageSize">
</el-pagination></span></span>
<script>
data(){
return {
tableData: [],
pageSize: 5, //这里必须与模拟接口中的pageSize一致
currentPage: 1, // 默认为第1页
totals: 5 // 默认总数据量为5
}
},
methods:{
},
mounted(){//页面被加载后,等到Vue实例挂载完毕之后再去获取实例,这个方法会自动触发
this.$http.post("/user/list",{"currentPage":this.currentPage,"pageSize":this.pageSize}).then((result)=>{
console.debug(result);
//成功之后给数组赋值
this.tableData = result.data.data;
this.totals = result.data.totals;
}).catch((result)=>{
alert("获取数据失败!");
})
}
</script>
9.3. 点击分页栏实现分页
//:current-page="currentPage" - currentPage 改变时会触发
<el-pagination
background
align="right"
layout="prev, pager, next"
@current-change="handlerCurrent"
:total="totals"
:current-page="currentPage"
:page-size="pageSize">
</el-pagination>
<script>
export default {
name: "UserList",
data(){
return {
tableData: [], //一开始是没有数据的
pageSize: 5, //这里必须与模拟接口中的pageSize一致
currentPage: 1, // 默认为第1页
totals: 5 // 默认总数据量为5
}
},
methods: {
handlerCurrent(currentPage){
// currentPage是分页组件传递过来的当前页
// console.log(currentPage);
// 获取当前页
this.currentPage = currentPage;
// 根据当前页,重新获取分页数据
this.getUsersByPage()
},
getUsersByPage(){
this.$http.post("/user/list",{"currentPage":this.currentPage,"pageSize":this.pageSize})
.then((result)=>{
console.log(result);
// 如果结果编码为200,则表示获取数据成功
if (result.data.resultCode == 200){
// 获取数据并给tableData赋值
this.tableData = result.data.data;
// 获取实际的数据总量并给totals赋值,这样分页组件才能正确分页
this.totals = result.data.totals;
}
})
.catch((result)=>{
alert("获取数据失败!!!")
})
}
},
mounted(){//页面被加载后,等到Vue实例挂载完毕之后再去获取实例,这个方法会自动触发
this.getUsersByPage();
}
}
</script>
四. 总结
1. 课程中的命令
vue init webpack - 使用Vue的脚手架工具初始化一个webpack项目
npm run dev - 开启服务
npm i element-ui -S - 安装elementUI
//引入elementUi
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
npm i axios - 安装axios
//引入axios
import axios from "axios";
//为axios配置全局基础路径
axios.defaults.baseURL="https://www.fastmock.site/mock/9304aaccec7ebe/pethome"
//为axios配置全局属性
Vue.prototype.$http = axios
npm i mockjs - 安装mockjs
五. 常见问题
1. axios全局配置时,axios.defaults.baseURL地址没有改
2. 成功之后的回调函数then()中写法不对
错误写法1:this.tableDate = res.data().data
错误写法2:this.tableDate = res.data.data()
3. 单文件组件中export default{}中格式写错
4. 前台页面报错【不用管,也能运行成功】
a. “Invalid prop: type check failed for prop “model”. Expected Object, got Array
分析:错误是:期望对象,得到的是数组
在定义时要定义成成数组:
tableData: {} - 对象
tableData: [] - 数组
b. [WDS] Disconnected! - 网上的各种方法都试过,没用
扩展
1.Restful是http协议的扩展使用,以前我们用http只用了get和post请求,
其实put,delete请求,Restful以资源为核心,
针对资源要做crud. 定位资源(url),做什么操作(通过http不同请求区分),
Put表示添加,Post表示修改,Get查询,Delete删除
Put http://127.0.0.1/user
{
id:1,
“name”:”zs”
}
Delete http://127.0.0.1/user/1
Post http://127.0.0.1/user/1
{
“name”:”ls”
}
Get http://127.0.0.1/user/1
Get http://127.0.0.1/users