本教程为入门教程,如有错误,请各位前端大佬指出。
1.axiox简介
jquery时代,我们使用ajax向后台提交数据请求,Vue时代,Axios提供了前端对后台数据请求的各种方式。
优缺点:
- 从 node.js 创建 http 请求
- 支持 Promise API
- 客户端支持防止CSRF
- 提供了一些并发请求的接口(重要,方便了很多的操作)
2.axios的跨域
由于前后端的端口号不同,那么会又跨域的问题。而解决跨域有很多总方法,比如使用后台配置或者nginx,以下是我做过的demo。
1.nginx配置跨域
1. #user nobody; 2. worker_processes 1; 3. 4. #error_log logs/error.log; 5. #error_log logs/error.log notice; 6. #error_log logs/error.log info; 7. 8. #pid logs/nginx.pid; 9. daemon off; 10. events { 11. worker_connections 65535; 12. multi_accept on; 13. } 14. 15. http { 16. include mime.types; 17. default_type application/octet-stream; 18. 19. #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 20. # '$status $body_bytes_sent "$http_referer" ' 21. # '"$http_user_agent" "$http_x_forwarded_for"'; 22. 23. #access_log logs/access.log main; 24. 25. sendfile on; 26. tcp_nopush on; 27. tcp_nodelay on; 28. 29. #keepalive_timeout 0; 30. keepalive_timeout 65; 31. 32. server { 33. listen 8080; 34. server_name localhost; 35. ## = /表示精确匹配路径为/的url,真实访问为http://localhost:8088 36. location = / { 37. proxy_pass http://localhost:8088; 38. } 39. ## /no 表示以/no开头的url,包括/no1,no/son,或者no/son/grandson 40. ## 真实访问为http://localhost:5500/no开头的url 41. ## 若 proxy_pass最后为/ 如http://localhost:3000/;匹配/no/son,则真实匹配为http://localhost:3000/son 42. location /no { 43. proxy_pass http://localhost:8088; 44. } 45. ## /ok/表示精确匹配以ok开头的url,/ok2是匹配不到的,/ok/son则可以 46. location /Demo/testDemoTranNew { 47. proxy_pass http://localhost:8088; 48. } 49. } 50. } 51. 复制代码
2.axios配置跨域
同时在axios中也可以配置跨域,方式如下:
1.修改config/index.js文件
//增加跨域 proxyTable: { "/api": { //目标地址 target: "http://localhost:8088", changeOrigin: true, pathRewrite: { '^/api': '' } } }, 复制代码
2.main.js中增加变量
1. //跨域处理 相当于把index中的api地址拿过来 2. Vue.prototype.HOST = '/api' 3. 复制代码
直接调用就可以了,完全避免了跨域!
3.axios的get请求
在使用时main.js
需要导入axios组件。具体方式请参考下文。
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import axios from "axios" Vue.config.productionTip = false Vue.prototype.$axios = axios /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' }) 复制代码
vue中的get请求.有两种写发,以下附上两种写法的格式。
<template> <div> {{data}} </div> </template> <script> export default { name: 'HelloWorld', data () { return { content:"组件1", data:{} } }, methods:{ }, created() { //第一种 // this.$axios.get("https://api.apiopen.top/searchMusic",{ // params:{ // name:"雅俗共赏" // } // } // ) // .then(res => { // console.log(res) // this.data = res.data // }) // .catch(error => { // console.log(error) // }) // 第二种 this.$axios({ method: 'get', url: 'https://api.apiopen.top/searchMusic', params: { name:"雅俗共赏" } }) .then(res => { console.log(res) this.data = res.data }) .catch(error => { console.log(error) }) ; } } </script> 复制代码
4.axios的post请求
在调用中也有两种写法,需要注意的是,需要使用qs去格式化参数,因为需要把对象转换成json格式。
<template> <div> {{data}} </div> </template> <script> import qs from "qs" export default { name: 'HelloWorld', data () { return { content:"组件1", data:{} } }, methods:{ }, created() { //axios的post请求接收的参数是 form-data格式 ---- name = xiaobao 需要使用qs // this.$axios.post("https://api.it120.cc/common/mobile-segment/next",qs.stringify( // { // segment: 0 // } // ) // ) // .then(res => { // console.log(res) // this.data = res.data // }) // .catch(error => { // console.log(error) // }) //这种写法需要transformRequest来转换格式 否则会报错 因为接受的是string类型参数 //但是不加stringify会直接变成对象传过去 // 发送 POST 请求 this.$axios({ method: 'post', url: 'https://api.it120.cc/common/mobile-segment/next', data: { segment: 0 }, transformRequest: [function (data) { // 对 data 进行任意转换处理 return qs.stringify(data); }] }) .then(res => { console.log(res) this.data = res.data }) .catch(error => { console.log(error) }); } } </script> 复制代码
5.url的全局配置
因为如果调用的api前缀相同,那么可以使用全局配置,将url配成全局,避免多次书写。
这里需要时对main.js
配置,以下附上代码。
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import axios from "axios" Vue.config.productionTip = false Vue.prototype.$axios = axios axios.defaults.baseURL = 'https://api.example.com'; axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' }) 复制代码
调用时,url就可以省略baseURL中配置的
6.拦截器
在axios发送前和接受前,先执行拦截器(类似java拦截器),这里需要在main.js
中加入配置。
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import axios from "axios" import qs from 'qs' Vue.config.productionTip = false Vue.prototype.$axios = axios axios.defaults.baseURL = 'https://api.it120.cc'; //axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; //axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; // 添加请求拦截器 axios.interceptors.request.use(function(config) { // 在发送请求之前做些什么 console.log(config) if (config.method === "post") { config.data = qs.stringify(config.data); } return config; }, function(error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function(response) { console.log(response) if (response.status !== 200) { return; } // 对响应数据做点什么 return response; }, function(error) { // 对响应错误做点什么 return Promise.reject(error); }); /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' }) 复制代码
这样的话,在接下来的使用中我们拦截了qs方法,在之后的使用中就不必每一个请求都调用qs方法了。
<template> <div> {{data}} </div> </template> <script> import qs from "qs" export default { name: 'HelloWorld', data () { return { content:"组件1", data:{} } }, methods:{ }, created() { // 发送 POST 请求 this.$axios({ method: 'post', url: '/common/mobile-segment/next', data: { segment: 0 } }) .then(res => { console.log(res) this.data = res.data }) .catch(error => { console.log(error) }); } } </script> 复制代码
7.前端测试方法
在测试前端时有几种获取数据方法
- 1.mock 请求自己的json格式 缺点:无法post请求
- 2.自己搭建服务器 获取数据
- 3.使用线上已经存在的数据 缺点:线上必须存在数据
注意!操作dom节点时,避免操作原生dom 如:
<template> <div> {{data}} <p ref = "myp">aaa</p> </div> </template> <script> import $ from "jquery" export default { name: 'HelloWorld', data () { return { content:"组件1", data:{} } }, methods:{ }, mounted() { //使用原生操作dom console.log(this.$refs.myp.innerHTML = "BBB") //console.log(this.$refs.myp.style.color = "red") var myo2 = this.$refs.myp myo2.addEventListener("click",function(){ console.log("666") }) //使用jquery操作dom $(myo2).css("color","YELLOW"); } } </script>