[Vue] 05 - Front and rear separation

前后端分离,其实也就是关于前后端沟通的问题。

前端请求数据的模板

(1) vue-resource 官方提供的 vue的一个插件

(2) axios

(3) fetch-jsonp

 

 

 

vue-resource


一、引入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 请求。 

Ref: 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=12345
axios.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.

posted @ 2020-08-15 08:35  郝壹贰叁  阅读(150)  评论(0编辑  收藏  举报