目录
Vue - 4 Vue中与后端交互
1.购物车案例
只要js的变量发生变化,html页面中使用该变量的地方就会重新渲染
购物车实现步骤:
1.先搭出框架,给每个商品增加选择按钮,点击后将其增加到已选择的数组中,并计算出价格
2.增加全选按钮,当点击后选中全部商品;并且在其中取消单个商品的时候,也取消全选框的选中状态
3.增加 加减商品数量的按钮,并且使得商品数量不可以为0
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<!-- vue 文件 -->
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h4 class="text-center">购物车</h4>
<table class="table">
<thead>
<tr>
<th>编号</th>
<th>商品名</th>
<th>价格</th>
<th>商品数量</th>
<th>选择/全选
<input type="checkbox" v-model="checkAll" @change="handleAll">
</th>
</tr>
</thead>
<tbody>
<tr v-for="item of goodList" >
<th scope="row">{{item.id}}</th>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td><button @click="handleMinus(item)">-</button>
{{item.num}}
<button @click="item.num++">+</button> </td>
<td><input type="checkbox" v-model="checked" :value="item" @change="handleOne"></td>
</tr>
</tbody>
</table>
<p>选中商品:{{checked}}</p>
<p>总价格:{{getPrice()}}</p>
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '.app',
data: {
name: 'lqz',
goodList: [
{id: 1, name: '钢笔', price: 1, num: 3},
{id: 2, name: '水杯', price: 32, num: 3},
{id: 3, name: 'ps5', price: 3999, num: 1},
],
// 复选框选中的商品绑定给数组
checked: [],
// 复选框 单选时候绑定给布尔值
checkAll:false,
},
methods: {
// 计算价的函数,通过for循环拿到数组中的 单条商品的数据并计算其价格
getPrice() {
let total = 0
for (item of this.checked) {
total += item.price * item.num
}
// 获得的结果一定要return出去
return total
},
// 全选框:全部选中的逻辑就是,当单选框绑定的布尔值为true时,
// 也就是选中的状态下,将所有商品都添加到选中的数组中,
// 否则,也就是布尔值为false时,全部不选也就是数组内没有商品对象
handleAll(){
if(this.checkAll){
this.checked=this.goodList
}else {
this.checked=[]
}
},
// 选一个是全选框不再选中,也就是增加判断,当复选空绑定的数组和商品列表长度一致时,
// 全选框才选中也就是对应的布尔值为true
handleOne(){
this.checkAll = this.checked.length === this.goodList.length;
},
// 减少商品的按钮:当商品数量为1时不可减少,并弹出警告窗
handleMinus(item){
if(item.num>1){
item.num--
}else {
alert('不可以为0')
}
},
},
})
</script>
</html>
2.v-model的修饰符
修饰符 | 作用 |
---|---|
.lazy | 等待input框的数据绑定时区焦点之后再变化 |
.number | 数字开头,只保留数字,后面的字母不保留;字母开头,都保留 |
.trim | 去除首位的空格 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- vue 文件 -->
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<p><input type="text" v-model.lazy="myText" >{{myText}}</p>
<p><input type="text" v-model.number="myNumber" >{{myNumber}}</p>
<p><input type="text" v-model.trim="myTrim" >{{myTrim}}</p>
</div>
</body><!-- vue 文件 -->
<script src="./js/vue.js"></script>
<script>
var vm = new Vue({
el: '.app',
data: {
myText: '',
myNumber: '',
myTrim: ''
},
})
</script>
</html>
3.什么是跨域问题
浏览器的原因,只要向不是地址栏中的 [域:地址和端口]发送请求,拿的数据,浏览器就给拦截了
跨域问题
跨域问题(Cross-Origin Resource Sharing,CORS)是指在浏览器端,通过ajax、fetch等方式发起跨域请求时,由于同源策略(Same-Origin Policy)的限制,请求会被浏览器拦截,因此不能正常完成。
同源策略
同源策略是一种浏览器的安全机制,它要求浏览器只能从同一个源(协议、域名、端口)加载页面和资源。如果两个不同域名下的网页需要相互通信,就必须通过跨域请求来完成。
在跨域请求中,浏览器会在请求头中添加一个Origin字段,服务器端会在响应头中添加一个Access-Control-Allow-Origin字段,指示哪些域名的请求可以访问该资源。如果服务器端设置了Access-Control-Allow-Origin字段的值为"*",则表示任何域名的请求都可以访问该资源。此外,服务器端还可以设置其他的响应头字段,如Access-Control-Allow-Methods、Access-Control-Allow-Headers等,来限制跨域请求的访问权限。
跨域问题解决思路
在实际开发中,为了避免跨域问题,可以通过以下几种方式进行解决:
- 使用代理:在同一个域名下搭建一个代理服务器,将跨域请求发送到代理服务器,再由代理服务器将请求发送到目标服务器。这种方式需要服务器端的支持,不适合纯前端项目。
- JSONP:利用script标签没有跨域限制的特性,通过在前端页面动态创建一个script标签,指向目标服务器的接口地址,并在URL参数中携带一个回调函数的名称,服务器端返回的数据会被包裹在回调函数中,前端页面通过该回调函数来处理数据。
- CORS:在服务器端设置Access-Control-Allow-Origin等响应头字段,允许跨域请求访问资源。这种方式是目前最常用的解决跨域问题的方式。
4.Vue中与后端交互
1.使用JQuery中的ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- jquery 文件 -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<!-- Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<!-- vue 文件 -->
<script src="./js/vue.js"></script>
</head>
<body>
<div class="app">
<h2>使用jq的ajax与后端交互</h2>
<button @click="handleGet">点击获取用户信息</button>
<p>用户名:{{name}}</p>
<p>年龄: {{age}}</p>
<p>性别: {{gender}}</p>
</div>
</body>
<script>
let vm = new Vue({
el: '.app',
data: {
name: '',
age: '',
gender: '',
},
methods: {
handleGet() {
$.ajax({
// url:'http://127.0.0.1:8000/getData/',
url:'http://127.0.0.1:8000/user/get/',
type:'get',
success:data=>{
this.name=data.name
this.age=data.age
this.gender=data.gender
}
})
}
},
})
</script>
</html>
(1)flask
from flask import Flask, jsonify, make_response
app = Flask(__name__)
@app.route('/')
def index():
print('执行了')
res = make_response(jsonify({'name': '彭于晏', 'age': 19, 'gender': 'male'}))
res.headers['Access-Control-Allow-Origin'] = '*' # 把这个key和value加入到响应头,就没有跨域问题了
return res
if __name__ == '__main__':
app.run()
(2)django
(3)drf
2.fetch
- fetch 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应
-新的发送ajax 接口
-用起来比较方便
-支持promise写法[最新的异步写法]
-解决了原生的XMLHttpRequest兼容性的问题
-不是所有浏览器都支持
-主流现在是用axios[第三方]发送请求
- XMLHttpRequest: 原生js提供的
-比较老,不同浏览器需要做一些兼容性的处理,写起来比较麻烦
-jq基于它做了封装
案例
<script>
var vm = new Vue({
el: '.app',
data: {
name: '',
age: 0,
gender: '未知'
},
methods: {
handleClick() {
//1 fetch
fetch('http://127.0.0.1:5000/').then(response => response.json()).then(res => {
// 对象
console.log(res)
this.name = res.name
this.age = res.age
this.gender = res.gender
})
}
}
})
</script>
3.axios发送ajax请求
(1)简介
① Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中
② axios官网:http://www.axios-js.com/
③ 使用axios时,需要导入cdn或者本地链接
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
(2)实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- jquery 文件 -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<!-- Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<!-- vue 文件 -->
<script src="./js/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<div class="app">
<h2>使用jq的ajax与后端交互</h2>
<button @click="handleGet">点击获取用户信息</button>
<p>用户名:{{name}}</p>
<p>年龄: {{age}}</p>
<p>性别: {{gender}}</p>
</div>
</body>
<script>
let vm = new Vue({
el: '.app',
data: {
name: '',
age: '',
gender: '',
},
methods: {
handleGet() {
axios.get('http://127.0.0.1:8000/getData/').then(res=>{
// res 是对象,有点特殊,真正的数据放在res.data中
console.log(res)
this.name=res.data.name
this.age=res.data.age
this.gender=res.data.gender
})
}
},
})
</script>
</html>
4.电影数据显示案例
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- jquery 文件 -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<!-- Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<!-- vue 文件 -->
<script src="./js/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<div class="app">
<h2>电影</h2>
<button @click="handleGet">点击获取用户信息</button>
<ul>
<li v-for="item in dataList">
<p>
<h2>电影名:{{item.name}}</h2></p>
<p>
<h3>导演:{{item.director}}</h3></p>
<p>
<h3>电影分类:{{item.name}}</h3></p>
<p>电影简介:{{item.synopsis}}</p>
<img :src="item.poster" alt="" width="300px">
</li>
</ul>
</div>
</body>
<script>
let vm = new Vue({
el: '.app',
data: {
dataList: []
},
methods: {
handleGet() {
// axios.get('http://127.0.0.1:8000/getData/').then(res=>{
axios.get('http://127.0.0.1:5000/movie').then(res => {
// res 是对象,有点特殊,真正的数据放在res.data中
this.dataList = res.data.data.films
})
}
},
})
</script>
</html>
后端:flask
from flask import Flask, jsonify, make_response
import json
app = Flask(__name__)
# @app.route('/')
# def hello_world(): # put application's code here
# return 'Hello World!'
# 需要配置路由
@app.route('/movie')
def movie():
# 1.打开保存在文件中的 json数据
with open('./movie.json','r') as f:
res = json.load(f)
response_obj = make_response(jsonify(res))
response_obj.headers['Access-Control-Allow-Origin'] = '*'
return response_obj
if __name__ == '__main__':
app.run()
标签:Vue,name,res,data,item,交互,跨域
From: https://www.cnblogs.com/DuoDuosg/p/17128774.html