[Vue] 05 - Front and rear separation
前后端分离,其实也就是关于前后端沟通的问题。
前端请求数据的模板
(1) vue-resource 官方提供的 vue的一个插件
(2) axios
(3) fetch-jsonp
一、引入vue-resource
Ref: https://github.com/pagekit/vue-resource
Vue 要实现异步加载需要使用到 vue-resource 库。
Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。
package.json
main.js
官方插件的用法:
二、GET 范例
菜鸟教程:https://www.runoob.com/vue2/vuejs-ajax.html
GET, POST 两种策略。以下仅介绍了GET例子。重点放在axios上。
服务器的消息源:一段json内容。
{"result":[{"aid":"499","catid":"20","username":"admin","title":"\u3010\u56fd\u5185\u9996\u5bb6\u3011\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u89c6\u9891\u6559\u7a0b\u514d\u8d39\u4e0b\u8f7d","pic":"portal\/201610\/13\/211832yvlbybpl3rologrr.jpg","dateline":"1476364740"},{"aid":"498","catid":"20","username":"admin","title":"ionic\u57df\u8d44\u6e90\u5171\u4eab CORS \u8be6\u89e3","pic":"","dateline":"1472952906"},{"aid":"497","catid":"20","username":"admin","title":"\u79fb\u52a8\u7aef\u89e6\u6478\u6ed1\u52a8js\u63d2\u4ef6_html5\u624b\u673a\u7aef\u8f6e\u64ad\u63d2\u4ef6","pic":"portal\/201606\/28\/211604ullzo5arr4iurnum.jpg","dateline":"1467119820"},{"aid":"496","catid":"20","username":"admin","title":"\u672a\u6765\u7a0b\u5e8f\u5458\u4f1a\u88ab\u673a\u5668\u4eba\u53d6\u4ee3\u5417\uff1f","pic":"portal\/201606\/02\/221818eafffffm4srfdf4s.jpg","dateline":"1464874140"},{"aid":"495","catid":"20","username":"admin","title":"\u9524\u5b50\u5b89\u5168\u9524_\u9524\u5b50\u771f\u7684\u51fa\u4e86\u4e2a\u201c\u9524\u5b50\u201d\uff1a\u8f66\u5145\uff0b\u5b89\u5168\u9524","pic":"portal\/201605\/20\/213752f6i56f1e0hbfzhkb.jpg","dateline":"1463751505"},{"aid":"494","catid":"20","username":"admin","title":"html5\u80fd\u505a\u4ec0\u4e48_html5\u80fd\u505a\u54ea\u4e9b\u5f00\u53d1\uff1f","pic":"","dateline":"1463664540"},{"aid":"493","catid":"20","username":"admin","title":"\u5e73\u5b89\u53e3\u888b\u94f6\u884cApp\u91c7\u7528-Cordova\u6df7\u5408\u5f00\u53d1","pic":"","dateline":"1463294580"},{"aid":"492","catid":"20","username":"admin","title":"JavaScript Emoji \u8868\u60c5\u5e93_js \u7c7b\u4f3c\u4e8eqq\u5fae\u4fe1\u7684\u8868\u60c5\u5e93","pic":"portal\/201604\/25\/084907r2e3im3dvd1q3f7z.jpg","dateline":"1461545392"},{"aid":"491","catid":"20","username":"admin","title":"cordova\u70ed\u66f4\u65b0\u63d2\u4ef6-\u4e0d\u53d1\u5e03\u5e94\u7528\u5e02\u573a\u52a8\u6001\u66f4\u65b0APP\u6e90\u7801","pic":"portal\/201604\/12\/152638zaxz5xz3t58bfts2.png","dateline":"1460446140"},{"aid":"490","catid":"20","username":"admin","title":"\u592e\u884c\u65b0\u89c4\uff01\u652f\u4ed8\u5b9d\u3001\u5fae\u4fe1\u7528\u6237\u522b\u5fd8\u505a\u8fd9\u4ef6\u4e8b","pic":"portal\/201603\/29\/144942tcnnenueefagukfk.jpg","dateline":"1459234206"},{"aid":"471","catid":"20","username":"admin","title":"HTML5 \u79fb\u52a8app\u5f00\u53d1\u6846\u67b6\u8be5\u5982\u4f55\u9009\u62e9","pic":"portal\/201511\/15\/163112q4kz6k2rgcgpi1tc.jpg","dateline":"1457771160"},{"aid":"488","catid":"20","username":"admin","title":"\u7eafCSS3\u52a8\u753b\u6309\u94ae\u6548\u679c,\u53ef\u7528\u4e8e\u79fb\u52a8wap app\u5f00\u53d1","pic":"portal\/201603\/09\/202742r1kngyt17na7n1nk.jpg","dateline":"1457526780"},{"aid":"487","catid":"20","username":"admin","title":"\u4eac\u4e1c\u6bcf\u5929\u4e8f\u4e0a\u4ebf_\u4e0d\u4f1a\u6284\u88ad\u3001\u527d\u7a83?\u5fc5\u5c06\u6b7b\u5728\u4e92\u8054\u7f51\u4e0b\u4e00\u7ad9\u7684\u8d77\u70b9\u4e0a! ...","pic":"portal\/201603\/02\/155825h28zxs2vsxjccv4c.jpg","dateline":"1456905746"},{"aid":"486","catid":"20","username":"admin","title":"ionic react-native\u548cnative\u5f00\u53d1\u79fb\u52a8app\u90a3\u4e2a\u597d","pic":"portal\/201602\/25\/193433dtzfvlzl1oavhljy.jpg","dateline":"1456398960"},{"aid":"484","catid":"20","username":"admin","title":"\u8fd912\u884c\u4ee3\u7801\u5206\u5206\u949f\u8ba9\u4f60\u7535\u8111\u5d29\u6e83\u624b\u673a\u91cd\u542f","pic":"","dateline":"1453426595"},{"aid":"483","catid":"20","username":"admin","title":"\u7f57\u632f\u5b87\u7f57\u6c38\u6d69\u96f7\u519b\u4eec\u7684\u6f14\u8bb2 \u4f60\u559c\u6b22\u54ea\u4e00\u4e2a","pic":"","dateline":"1452226800"},{"aid":"482","catid":"20","username":"admin","title":"ionic-native-transitions\u8ba9\u4f60\u7684Ionic\u5e94\u7528\u6bd4\u539f\u751f\u8fd8\u5feb","pic":"portal\/201601\/07\/135529z4r7gwglv4rw8l74.jpeg","dateline":"1452145500"},{"aid":"481","catid":"20","username":"admin","title":"ionic 1.2.4 \u53d1\u5e03\uff0c\u6700\u597d\u7684html5\u79fb\u52a8app\u5f00\u53d1\u6846\u67b6","pic":"portal\/201601\/05\/132107h9bllr7li74zoh49.jpg","dateline":"1451971293"},{"aid":"480","catid":"20","username":"admin","title":"phonegap\u53d1\u5e03\u5e94\u7528\u5230appstore","pic":"portal\/201601\/05\/122115yhh22i77sqn2ijc6.jpg","dateline":"1451967910"},{"aid":"479","catid":"20","username":"admin","title":"HTML5\u4eff\u82f9\u679c\u5e94\u7528\u7684\u52a8\u753b","pic":"portal\/201601\/04\/220252ycyddectvivr55pq.png","dateline":"1451916189"}]}
View Code
客户端接收消息:
<template><!-- 所有的内容要被根节点包含起来 -->
<div id="home">
首页组件
<button @click="getData()">请求数据</button>
<hr>
<br>
<ul>
<li v-for="item in list">
{{item.title}}
</li>
</ul>
</div>
</template>
<script>
/*
请求数据的模板
vue-resource 官方提供的 vue的一个插件
axios
fetch-jsonp
*/
export default{
data() {
return {
msg:'我是一个首页组件msg',
flag:true,
list:[]
}
},
methods:{
getData(){
//请求数据
var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1';
this.$http.get(api).then((response)=>{
console.log(response);
//注意this指向
this.list=response.body.result;
},function(err){
console.log(err);
})
}
},
mounted() { /*生命周期函数*/
this.getData();
}
}
</script>
<style lang="scss" scoped>
/*css 局部作用域 scoped*/
h2{
color:red
}
</style>
axios
一、安装
Ref: https://github.com/axios/axios (安装命令)
Promise based HTTP client for the browser and node.js
$ npm install axios
什么是 ajax 请求
Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。
Ajax原理一篇就够了
异步请求数据的web开发技术,减少网络数据的传输量:Asynchronous Javascript And XML。
GET和POST请求数据区别
二、GET方法
Ref: Vue.js Ajax(axios)
<!DOCTYPE html><html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
</head>
<body>
<div id="app">
<h1>网站列表</h1>
<div v-for="site in info" >
{{ site.name }}
</div>
</div>
<script type = "text/javascript">
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get('https://www.runoob.com/try/ajax/json_demo.json')
.then(response => (this.info = response.data.sites))
.catch(function (error) { // 请求失败处理
console.log(error);
});
}
})
</script>
</body>
</html>
response 或是 response.data,返回的是raw的内容。要跟详细的内容,则需要.sites进一步提取。
{"name":"网站",
"num":3,
"sites": [
{ "name":"Google", "info":[ "Android", "Google 搜索", "Google 翻译" ] },
{ "name":"Runoob", "info":[ "菜鸟教程", "菜鸟工具", "菜鸟微信" ] },
{ "name":"Taobao", "info":[ "淘宝", "网购" ] }
]
}
显示结果:
另一端代码:通过 axios.get(URL) 获取资源。
<script>/*
请求数据的模板
axios 的使用
1、安装 cnpm install axios --save
2、哪里用哪里引入axios
*/
import Axios from 'axios';
export default{
data(){
return {
list:[]
}
},
methods:{
getData(){
var api='http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1';
axios.get(api).then((response)=>{
this.list=response.data.result;
}).catch((error)=>{
console.log(error);
})
}
},
mounted(){ /*生命周期函数*/
this.getData();
}
}
</script>
<style lang="scss" scoped>
/*css 局部作用域 scoped*/
h2{
color:red
}
</style>
View Code
前端路由 ?
GET 方法传递参数格式如下:
// 直接在 URL 上添加参数 ID=12345axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
----------------------------------
// 也可以通过 params 设置参数:axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Ref: 前端路由是什么东西?
不刷新页面,改变页面内容。
单页应用
Ref:【Vue17】单页应用和多页应用
三、POST 方法
new Vue({el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.post('https://www.runoob.com/try/ajax/demo_axios_post.php')
.then(response => (this.info = response))
.catch(function (error) { // 请求失败处理
console.log(error);
});
}
})
参数不太一样。(firstName, lastName)
axios.post('/user', {firstName: 'Fred', // 参数 firstName
lastName: 'Flintstone' // 参数 lastName
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
四、执行多个并发请求
同时等待两个请求完成。
并发
处理并发请求的助手函数:
axios.all(iterable)axios.spread(callback)
例子:
function getUserAccount() {return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()]).then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
}));
fetch-jsonp
一、安装
npm install fetch-jsonp
Ref: fetch 如何请求常见数据格式
Ref: https://github.com/camsong/fetch-jsonp
Make JSONP request like window.fetch
fetch-jsonp 不受跨域限制
Ref: JS中的跨域问题
跨域:比如从www.baidu.com 页面去请求 www.google.com 的资源。
概念:只要协议、域名、端口有任何一个不同,都被当作是不同的域。
http://www.123.com/index.html 调用 http://www.123.com/server.PHP (非跨域)
http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)
http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)
http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)
请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
浏览器执行 javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。
对于端口和协议的不同,只能通过后台来解决。
(1) 跨域资源共享(CORS)- 推荐!
服务器端对于CORS
的支持,主要就是通过设置Access-Control-Allow-Origin
来进行的。
如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
(2) 通过jsonp跨域
在js中,我们直接用XMLHttpRequest
请求不同域上的数据时,是不可以的。
但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。
二、使用
Fetch JSONP in simple way
fetchJsonp('/users.jsonp').then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
前后端分离
文章:Developing a Single Page App with Flask and Vue.js
代码:https://github.com/testdrivenio/flask-vue-crud
一、删除一项
分析一个流程即可。
点击按钮 --> 触发 onDeleteTask() --> 服务器端“删除”的过程。
removeTask(taskID) {const path = `http://localhost:5000/tasks/${taskID}`;
axios.delete(path)
.then(() => {
this.getTasks();
this.message = 'Task removed!';
this.showMessage = true;
})
.catch((error) => {
// eslint-disable-next-line
console.error(error);
this.getTasks();
});
},
onDeleteTask(task) {
this.removeTask(task.id);
},
二、添加一项
新增加的项采用post,参数不在url中,而是作为了payload。
addTask(payload) {const path = 'http://localhost:5000/tasks';
axios.post(path, payload)
.then(() => {
this.getTasks();
this.message = 'Task added!';
this.showMessage = true;
})
.catch((error) => {
// eslint-disable-next-line
console.log(error);
this.getTasks();
});
},
End.
以上是 [Vue] 05 - Front and rear separation 的全部内容, 来源链接: utcz.com/z/380565.html