前端与移动开发----Vue---- json-server-安装及基本使用,axios基本使用,侦听器
目标:
- 从模拟接口处获取数据
- 掌握axios的使用
理解写接口
在开发过程中,经常会遇到后端接口滞后的情况:前端页面写完了,后端的接口没有就绪(意味着前端没有数据可用),此时,我们就可以自己先准备接口(接口的功能是真的,数据是假的)。
有两种方式:
- 自己写
- nodejs写接口(利用express框架)
- 采用现成的工具json-server生成接口
- 第三方的公开的mock api工具 (非常多)
- https://www.fastmock.site/#/
mock: 假的,
json-server-安装及基本使用
参考:教程
官网: npm
作用
能json-server快速地根据已有json文件,生成接口
json ----json-server-----> 接口
使用步骤
全局安装json-server
以前安装过的全局包:
nodemon
,nrm
它是依赖于nodejs的第三方包,它是一个独立的工具,并不限于某个项目,可以全局安装。
npm i json-server -g
如果是mac本,可能需要加sudo,即:sudo npm i json-server -g
准备空文件夹
在任意目录下,准备一个空文件夹,取名mock-server(可改成其它名字)
创建json文件
在文件夹中新建一个名为db.json文件(可改其它名称,注意名字是是英文)
初始化结构
在db.json文件中,按json格式的要求,去定义一个对象:
- 键值对格式
- 用双引号括起来
{
"assets": [
{ "id": 1, "name": "外套", "price": 99 },
{ "id": 2, "name": "裤子", "price": 34 },
{ "id": 3, "name": "鞋", "price": 25.4 },
{ "id": 4, "name": "头发", "price": 19900 }
]
}
启动接口服务
根据上面创建的db.json自动地生成接口。
进入到上一步创建的文件夹下,
在此文件夹下,打开命令行窗口,输入命令json-server db.json
(json-server后有空格)
如果没有错误,则运行结果如下:
测试
在浏览器中访问上面地址
注意:
- 产生的接口地址中的
assets
是与db.json中的属性名是对应的。 - db.json的内容必须是json格式。
- 属性名 —> 接口的地址
- 属性值 —> 接口返回数据 (数组|对象)
原理图
注意
- 小黑窗不要关!
- 小黑窗上不要用鼠标选中任何内容!
json-server-RESTful接口
json-server提供的接口是符合RESTful接口规范的。
问题导入
在写接口时,每个程序员都有自己的写法:取不同的名字,例如:实现添加资产
A同学: localhost:3000/addAsset | delAsset
B同学: localhost:3000/insertAsset | deleteAsset
C同学: localhost:3000/tjzj | sczj
RESTful接口
针对上述问题,提出一套约定:
RESTful接口的规范是通过
- 请求方式来决定操作类别(添加,删除,修改,查询)
- 用名词来表示要操作的目标
测试
以上面启动的服务为例:一旦服务启动成功,就会自动生成如下接口地址。
接口地址 | 请求方式 | 操作类型 |
---|---|---|
/assets | GET | 获取全部数据 |
/assets/1 | GET | 获取单个数据 |
/assets | POST | 添加操作 {name,price} |
/assets/1 | DELETE | 删除操作 |
/assets/1 | PUT | 完整修改{name,price} |
/assets/1 | PATCH | 局部修改{name} |
以上接口规则,就是restful规则。
json-server提供的就是符合restful规则的接口。
json-server-postman测试
postman是用来测试后端给的接口是否正常工作。
类似的工具还有:apipost, postwoman
使用postmant来测试json-server提供的接口。
获取全部数据 - 列表
GET: http://localhost:3000/assets
获取单个数据 - 详情
以id为查询依据
GET: http://localhost:3000/assets/1
根据条件查询数据
json-server服务器提供了条件查询的功能
格式: ? 字段**_like**=值
头这个关键字前后,不要加引号!
添加操作
以json格式传递参数,id会自动增加。
POST:http://localhost:3000/assets/
{"name": "电脑", "price": 6880}
另一个操作示例:
删除操作
以id为查询依据
DELETE: http://localhost:3000/assets/1
上面的地址中,1就表示要删除的数据的id。
完整修改
以json格式传递参数
PUT: http://localhost:3000/assets/3
要求必须传入一个完整的对象(如果这一条记录中有100个属性,则要传入100个属性),因为它会整体覆盖这条数据。
局部修改
以json格式传递参数
PATCH: http://localhost:3000/assets/3
只需要传入要更改的字段(要修改哪个属性就传入哪个属性 )。
axios基本使用
我们发ajax请求接口,有如下方式:
- 原生的。纯手写:XMLHttpRequest…
- . a j a x ( ) 。 j q u e r y 中 的 a j a x ( .ajax()。jquery中的ajax( .ajax()。jquery中的ajax(.get, $.post …)
- axios。它是一个专业的,只发ajax请求的工具。它可以在nodejs中和浏览器使用。
下载并使用
axios是一个js库,是前端通用的工具,专门用来发ajax。要想使用,就要先下载。
下载地址:https://unpkg.com/axios/dist/axios.min.js
文档地址:http://www.axios-js.com/docs/
格式
完整写法
axios({
// 请求方式 get|post|put|patch|delete 大小写不区分
method: 'get',
// 路径上传参在url后进行拼接
url: 'http://localhost:3000/brands/1',
// ?后键值对传参
params: {},
// 请求体传参
data: {},
// 请求头传参
headers: {}
}).then(res=>{
console.log('成功')
}).catch(err=>{
console.log('失败')
})
简写格式
对于比较简单的接口调用,可以采用简写格式:
格式:
axios.请求方式(url, .......).then().catch()
示例:
// get类型的 参数要放在写params中
axios.get(url,params: {}).then(res=>{console.log('成功')})
.catch(err=>{
console.log('失败')
})
// post类型 直接写参数
axios.post(url,{}).then(res=>{console.log('成功')})
.catch(err=>{
console.log('失败')
})
示例
通过json-server启动接口服务器,然后再写axios代码来进行调用测试
查询
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js"></script>
<script>
// console.log(axios)
// 格式:
// axios({
// // 请求方式 get|post|put|patch|delete 大小写不区分
// method: 'GET',
// // 路径上传参在url后进行拼接
// url: 'http://localhost:3000/brands/1',
// // ?后键值对传参
// params: {},
// // 请求体传参
// data: {},
// // 请求头传参
// headers: {}
// }).then(res=>{
// console.log('成功')
// console.log(res)
// }).catch(err=>{
// console.log('失败')
// console.log(err)
// })
// 1. 测试添加新资产
// axios({
// method: 'POST',
// url: 'http://localhost:3000/assets',
// data: {
// name: '测试axios',
// price: 1
// }
// }).then(res => {
// console.log('成功')
// console.log(res.data);
// }).catch(err => {
// console.log('失败')
// console.log(err)
// })
// 2. 测试获取所有的资产
// axios({
// method: 'get',
// url: 'http://localhost:3000/assets'
// }).then(res => {
// console.log('成功')
// console.log(res.data);
// }).catch(err => {
// console.log('失败')
// console.log(err)
// })
// 3. 测试 根据关键字查询
// axios({
// method: 'get',
// url: 'http://localhost:3000/assets?name_like=测'
// }).then(res => {
// console.log('成功')
// console.log(res.data);
// }).catch(err => {
// console.log('失败')
// console.log(err)
// })
// 4. 测试 删除
let id = 2
axios({
method: 'DELETE',
url: 'http://localhost:3000/assets/' id
}).then(res => {
console.log('删除成功')
console.log(res.data);
}).catch(err => {
console.log('失败')
console.log(err)
})
</script>
</body>
</html>
添加
// 2. 添加
// 除去get请求外,函数的第二个参数都是请求体传参,是对象类型。
axios.post('http://localhost:3000/assets',{name:"宝马",price:500000}).then(res=>{
console.log('成功')
})
删除
// 3. 删除
axios.delete('http://localhost:3000/assets/2').then(res=>{
console.log('成功')
})
修改
// 4. 修改 完整
// axios.put('http://localhost:3000/assets/3',{name:"长安奔奔",price:36000}).then(res=>{
// console.log('成功')
// })
// 5. 修改 局部
axios.patch('http://localhost:3000/assets/3',{name:"奔奔"}).then(res=>{
console.log('成功')
})
总结:不同方式的参数怎么传递给后台。
案例-资产列表-目标说明
目标:
- 用json-server启动后端接口服务器;
- axios发请求
- 用vue管理视图
- v-for
- 计算属性算总价
- v-if 显示空数据的情况
- 过滤器处理价格
案例-资产列表-渲染列表
目标:在给定的静态页的基础上,通过引入vue对列表数据进行渲染
准备静态页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<div class="container">
<!-- 搜索 -->
<form class="form-inline" style="padding: 20px 0">
<input type="text" class="form-control" placeholder="输入关键字进行搜索">
</form>
<!-- 表格 -->
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>编号</th>
<th>资产名称</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>xxx</td>
<td>xxxx</td>
<td><a href="#">删除</a></td>
</tr>
</tbody>
</table>
<!-- 添加资产 -->
<form class="form-inline">
<input type="text" class="form-control" placeholder="资产名称">
<button class="btn btn-primary">添加资产</button>
</form>
</div>
</div>
</body>
</html>
创建vue实例,实现列表渲染
实现渲染列表,大致步骤:
- 在data配置项中,声明一个列表数据list,先设置一些假数据。
- 在模板当中根据list和数据中的字符段进行渲染
- 使用v-for指令
- 注意处理无数据的情况。
对应代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<div class="container">
<!-- 搜索 -->
<form class="form-inline" style="padding: 20px 0">
<input type="text" class="form-control" placeholder="输入关键字进行搜索">
</form>
<!-- 表格 -->
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>编号</th>
<th>资产名称</th>
<th>价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, idx) in list">
<td>{{idx}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td><a href="#">删除</a></td>
</tr>
<tr v-if="list.length==0">
<td colspan="4">没有数据</td>
</tr>
</tbody>
</table>
<!-- 添加资产 -->
<form class="form-inline">
<input type="text" class="form-control" placeholder="资产名称">
<input type="text" class="form-control" placeholder="价格">
<button class="btn btn-primary">添加资产</button>
</form>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// [{id:1,name:'t',price:1}]
// 1. 引用vue,把本地的数据渲染到页面上
new Vue({
el: '#app',
data: {
list: [
{id:1,name:'商品1',price:1}
]
}
})
</script>
</html>
案例-资产列表-ajax请求真数据
准备接口服务器
按前面的介绍的json-server的使用方式,把json服务器启动;
用postman提前做好接口测试;
在created配置项中发ajax请求
现在一切就绪,只需在某个时间点,向后台接口发请求,拿回数据,给list重新赋值即可
以前:window.onload = function(){} 默认渲染,页面加载完成之后
或者:$(function(){}) 默认渲染,页面文章加载完成之后
在vue中,需要默认渲染,vue实例初始化完毕后,发请求获取数据进行渲染。
vue提供一个配置选项
created
, 类型是函数,它会vue实例化后在被自动执行。
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
// 它是一个配置项,它是一个函数。它会在vue实例创建完成后, 被自动调用一次(只调用一次)
// 我们可以在这里,去发 ajax请求
created () {
console.log('created....')
// 1. 发ajax请求,获取全部的数据
// 2. 把数据保存到data中的对应的数据项list中
axios({
method: 'GET',
url: 'http://localhost:3000/assets'
}).then(res => {
console.log(res.data)
// 数据变化了,视图也自动变化
this.list = res.data
})
}
总结:一般在created函数中获取页面需要的初始化数据。
案例-资产管理-删除资产
目标
点击页面上的删除按钮,把对应的数据删除掉。
步骤
给a标签绑定点击事件(注意阻止默认行为)
定义处理函数,给函数传入资产ID
在函数中
弹出确认框提示
点击确认框之后,发删除请求
如果成功之后,更新列表(移除删除的行)
代码
<tbody>
<tr v-for="(item, idx) in list">
<td>{{idx}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td><a href="#" @click.prevent="hDelete(item.id)">删除</a></td>
</tr>
<tr v-if="list.length==0">
<td colspan="4">没有数据</td>
</tr>
</tbody>
<script>
// [{id:1,name:'t',price:1}]
// 1. 引用vue,把本地的数据渲染到页面上
// 2. ajax请求数据
// 3. 删除 (用户确认)
// (1)点击事件
// (2) 获取当前要删除的资产的id
// (3)调用接口,发请求
// (4) 删除成功之后,要重新请求数据,以更新页面
new Vue({
el: '#app',
data: {
list: [
// {id:1,name:'商品1',price:1}
]
},
computed: {
// xx () {
// console.log(this.xxxx)
// }
},
// 它是一个配置项,它是一个函数。它会在vue实例创建完成后, 被自动调用一次(只调用一次)
// 我们可以在这里,去发 ajax请求
created () {
console.log('created....')
this.loadData()
},
methods: {
loadData () {
// 1. 发ajax请求,获取全部的数据
// 2. 把数据保存到data中的对应的数据项list中
axios({
method: 'GET',
url: 'http://localhost:3000/assets'
}).then(res => {
console.log(res.data)
// 数据变化了,视图也自动变化
this.list = res.data
})
},
hDelete (id) {
if(!window.confirm('你确定要删除吗?')) {
return
}
// alert(id)
// 调用接口,发请求
axios({
method: 'DELETE',
url: 'http://localhost:3000/assets/' id
}).then(res => {
// 重新请求数据
this.loadData()
})
}
}
})
</script>
注意:
- 代码要封装。获取数据这个操作用到了多次,需要封装成成函数。
- 关于的函数的名字:
loadData
,hDel
如果一个函数是需要用户交互(点击事件,hover…)才会被执行的,就会在前面加 ‘h == handler’;如果不是,则不要加h。 - 在函数的内部要访问其它的属性或者数据,要在前面加
this
案例-资产管理-添加资产
目标
在点击页面上的添加时,可以实现添加新资产的功能
步骤
- 双向数据绑定,输入资产的表单元素
- 绑定表单的提交事件,阻止默认行为
- 在methods中定义一个事件函数,在函数中:
- 组织需要提交给后台的数据,{name,price},id后台不需要,自动自增。
- 提交数据前,对name进行校验
- 发起添加请求,如果成功,重新获取后台列表数据即可。
- 之前输入的内容清空
在案例中落地的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<div class="container">
<!-- 搜索 -->
<form class="form-inline" style="padding: 20px 0">
<input type="text" class="form-control" placeholder="输入关键字进行搜索">
</form>
<!-- 表格 -->
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>编号</th>
<th>资产名称</th>
<th>价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, idx) in list">
<td>{{idx}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td><a href="#" @click.prevent="hDelete(item.id)">删除</a></td>
</tr>
<tr v-if="list.length==0">
<td colspan="4">没有数据</td>
</tr>
</tbody>
</table>
<!-- 添加资产
向后端接口中传入数据时,建议按接口文档中的要求去取变量名。
-->
<form class="form-inline">
<input type="text" v-model.trim="asset.name" class="form-control" placeholder="资产名称">
<input type="text" v-model.number="asset.price" class="form-control" placeholder="价格">
<button class="btn btn-primary" @click.prevent="hAdd">添加资产</button>
</form>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
// [{id:1,name:'t',price:1}]
// 1. 引用vue,把本地的数据渲染到页面上
// 2. ajax请求数据
// 3. 删除 (用户确认)
// (1)点击事件
// (2) 获取当前要删除的资产的id
// (3)调用接口,发请求
// (4) 删除成功之后,要重新请求数据,以更新页面
new Vue({
el: '#app',
data: {
list: [
// {id:1,name:'商品1',price:1}
],
asset: {
name: '',
price: ''
}
},
computed: {
// xx () {
// console.log(this.xxxx)
// }
},
// 它是一个配置项,它是一个函数。它会在vue实例创建完成后, 被自动调用一次(只调用一次)
// 我们可以在这里,去发 ajax请求
created () {
console.log('created....')
this.loadData()
},
methods: {
// 用户点击了添加按钮
hAdd () {
console.log(this.asset)
// 1. 解构赋值
const { name, price } = this.asset
// 2. if (用户的输入不合法,提示一下用户
if (name === '') {
alert('名字不能为空')
return
}
if (price <= 0) {
alert('价格不能是负数')
return
}
// 3. 发请求
axios({
method: 'POST',
url: 'http://localhost:3000/assets',
data:{
name: name,
price: price
}
}).then(res => {
console.log('添加成功')
// 1. 重新请求数据
this.loadData()
// 2. 清空表单数据
this.asset.name = ''
this.asset.price = ''
})
},
loadData () {
// 1. 发ajax请求,获取全部的数据
// 2. 把数据保存到data中的对应的数据项list中
axios({
method: 'GET',
url: 'http://localhost:3000/assets'
}).then(res => {
console.log(res.data)
// 数据变化了,视图也自动变化
this.list = res.data
})
},
hDelete (id) {
if(!window.confirm('你确定要删除吗?')) {
return
}
// alert(id)
// 调用接口,发请求
axios({
method: 'DELETE',
url: 'http://localhost:3000/assets/' id
}).then(res => {
// 重新请求数据
this.loadData()
})
}
}
})
</script>
</html>
要点:
根据接口中字段的要求来定data中的数据项叫什么名字
如果数据项之间有关联 ,可以把它们统一加在一个对象中
案例-资产管理-搜索资产
目标
在搜索框中输入内容,获得以此为关键字的搜索结果。
思路
双向绑定 搜索框 这样可以获取到输入的关键字(keyword)数据。
实时进行搜索,筛选出列表需要的数据。
监听到输入内容的改变,根据输入的内容向后台发请求(有异步操作),响应成功后才可拿到列表数据。
监听keyword数据的变化,vue提供了侦听器,可以监听任何数据(this能够访问的数据)的变化。
难点:如何得知key数据变化?
侦听器
功能
对数据项进行侦听:当数据变化时,立即被感知到,调用函数(在函数内就可以做任意业务)。
格式
new Vue({
// .....
watch: {
// 属性名: 就是你要监听的数据项
// 属性值:一个函数,当这要监听的数据项变化时,要执行的函数。
// 它会自动传入新值和旧值
// 正常使用this
// 第一个参数是更新后的值,第二个参数是更新前的值
属性名1: function(新值,旧值) {
// 你要做什么.....
},
属性名2: function(新值,旧值) {
// 你要做什么.....
}
}
})
基本案例
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>html页面</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
body{
background-color: #eee;
}
#app{
background-color:#fff;
width: 500px;
margin: 50px auto;
box-shadow: 3px 3px 3px rgba(0 , 0, 0, 0.5);padding:2em;
}
.btn{
float:right;
cursor: pointer;
}
.box{
padding: 1em;
border:1px solid #ccc;
margin:1em;
}
</style>
</head>
<body>
<div id="app">
{{num}}, {{asset.price}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
num: 10,
asset: {
price: 100
}
},
// 目标: 当用户把num的值修改了,我们要能感知到!!!
watch: {
// 只要当num变化时,就会自动执行这个函数
// newNum 变化之后的新值
// oldNum 变化之前的旧值
"num": function(newNum, oldNum) {
console.log('num从', oldNum, '变成了', newNum)
},
"asset.price": function(newNum, oldNum) {
console.log('asset.price从', oldNum, '变成了', newNum)
}
}
})
</script>
</body>
</html>
- 侦听器用来对数据变化进行监控
侦听器与计算属性
共同点:
- 如果它们都侦听(依赖)同一个数据项,当数据项变化时,会去执行函数。
- 它们表现格式都是:
{ xx1(){}, xx2(){} }
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过
watch
选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
- 计算属性:本质是一个函数。如果这个函数中依赖的数据项变化时,这个函数就会重新执行,它必须要有返回结果。
- 侦听器:本质是一个函数。当侦听到某个数据变化时,这个函数就会重新执行,但不一定是依赖这个数据直接得到你想要的数。从函数内的代码逻辑来说:侦听器的逻辑一般会更加复杂。侦听器的返回值是没有意义的。
优先级: 计算属性 > 侦听器
秒懂案例:侦听器是人工服务台;计算属性是查询话费余额的快捷键 1008611
案例-资产管理-搜索资产-侦听器
用侦听器实现上述的功能
<!-- 搜索 -->
<form class="form-inline" style="padding: 20px 0">
<input v-model="keyword" type="text" class="form-control" placeholder="输入关键字进行搜索">
</form>
data: {
// 搜索关键字
keyword: ''
},
watch: {
keyword: function(newVal, oldVal) {
console.log(this.keyword)
// 获取到用户要搜索的关键字
// 如果关键字为空,就相当于是找全部的
axios({
method: 'GET',
url: 'http://localhost:3000/assets',
params: {
name_like: this.keyword
}
}).then(res => {
// 把查询到的数据更新到数据项中
this.list = res.data
})
}
}
案例-资产管理-完成后的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<div class="container">
<!-- 搜索 -->
<form class="form-inline" style="padding: 20px 0">
<!-- @input="hKeywordChange" -->
搜索:
<input
v-model.trim="keyword" type="text" class="form-control" placeholder="输入关键字进行搜索">
</form>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>编号</th>
<th>资产名称</th>
<th>价值</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in list">
<td>{{index 1}}</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<!-- 做删除,传入id -->
<td><a href="#" v-on:click.prevent="hDel(item.id)">删除</a></td>
</tr>
</tbody>
</table>
<!-- 添加资产 -->
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<input type="text" v-model.trim="asset.name" class="form-control" placeholder="资产名称">
</div>
<div class="input-group">
<input type="text" v-model.trim.number="asset.price" class="form-control" placeholder="价值">
</div>
<button class="btn btn-primary" @click.prevent="hAdd">添加资产</button>
</div>
</form>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.js"></script>
<!-- 引入axios -->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js"></script>
<script>
// 0. 数据要从接口处获取
// 1. v-if, v-else. 是否显示表格内容,或者是提示。
// 2. v-for. 循环列表
// 3. {{ }} 显示数据
// 4. @click.prevent
// 5. 计算属性算总价
// 6. 过滤器,处理货币金额
// 7. 列表数据筛选
// 通过设计计算属性,让它来决定表格区域的数据。
// 8. 自定义指令
const vm = new Vue({
el: '#app',
data:{
keyword: '', // 搜索关键字
asset: {
name: '',
price: ''
},
list: []
},
computed: {},
methods: {
loadData () {
axios({
method: 'get',
url: 'http://localhost:3000/assets'
}).then(res => {
console.log('成功')
// console.log(res.data);
// 将请求回来的数据保存到list中
this.list = res.data
console.log(this.list)
}).catch(err => {
console.log('失败')
console.log(err)
})
},
hDel (id) {
if(confirm('你确认要删除吗?')) {
axios({
method: 'DELETE',
url: 'http://localhost:3000/assets/' id
}).then(res => {
// alert('删除成功')
// 重新获取数据,以更新页面
this.loadData()
}).catch(err => {
alert('删除失败,请与管理员联系')
})
}
// alert('删除')
},
hAdd () {
const {name, price} = this.asset
// 1. 判断数据是否为空
if (name === '' || price === '') {
return
}
// 2. 发ajax
axios({
method: 'POST',
url:'http://localhost:3000/assets',
data: {
name,
price
}
}).then(res => {
// 3. 根据ajax执行结果,给出后续动作
console.log('ok')
// (1) 清空表单区域的内容
this.asset.name = this.asset.price = ''
// (2) 重发请求
this.loadData()
}).catch(err => {
console.log('error')
})
},
// hKeywordChange () {
// console.log(Date.now(), 'input事件,....')
// }
},
watch: {
keyword(newVal, oldVal) {
console.log(Date.now(), 'keyword变化了........', newVal)
// 去发出ajax请求,获取新数据
axios({
method: 'GET',
url: 'http://localhost:3000/assets',
params: {
name_like: newVal
}
}).then(res => {
this.list = res.data
}).catch(err => {
this.list = []
})
}
},
// 当vue实例被创建时,会自动去执行created函数--钩子函数(这个函数钩在vue上,当vue创建时,这个函数会自动执行)
// 1. 可以在这里里面去发ajax
// 2. 可以在这个函数中去通过this来访问数据项
created () {
// alert(1)
this.loadData()
}
})
</script>
</body>
</html>
如有不足,请多指教,
未完待续,持续更新!
大家一起进步!