一、vue-axios学习网址
网址1: https://github.com/imcvampire/vue-axios网址2: https://www.npmjs.com/packge/axios
二、vue中get与post请求
vue高版本中,推荐使用axios进行网络请求,而不再使用vue-resource。在vue04项目中,在终端运行 npm install --save axios vue-axios ,下载vue-axios插件
注意:“vue04项目”是指我的上篇博客中通过vue-cli脚手架创建的项目(后面我会附上源码,博客标题:《利用vue-cli创建项目步骤简述》,博客链接:https://blog.csdn.net/qq_41115965/article/details/80766520)
提示:使用插件的时候,一般都要在入口文件main.js中引入,因为main.js项目运行首先运行的文件。具体代码如下:
main.js文件
import Vue from 'vue' import axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios, axios)疑问:为什么使用Vue.use(VueAxios, axios)
解惑:通过全局方法 Vue.use() 使用插件,就相当于调用install方法,vue官网举例如下:
// 调用 `MyPlugin.install(Vue)` Vue.use(MyPlugin)
注意:在comunication组件中发起请求,要使用Vue,所以需要引入,即import vue from 'vue'(comunication组件是本例中发起网络请求的组件)
axios的get请求的参数解释:
第一个参数是链接,参数还可以拼接,也可以使用params形式。学习网址: https://www.npmjs.com/package/axios
axios的get使用方法(源自相关学习网址截图)
// Make a request for a user with a given ID axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); // Optionally the request above could also be done as axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
注意:原本url应该http://127.0.0.1:5888/api/get,但是开发时,代码都是放在公司服务器上的,绝对不会存在跨域问题。测试环节中,没有必要让后台进行jsonp处理或者cors。
此时点击comunication组件中的按钮,发起get请求,会出现报错。报错信息为:GET http://localhost:8080/api/get?name=%E5%AC%B4%E6%94%BF&age=45 404 (Not Found)
报错解释:
其中http://localhost:8081是默认的服务器端口,在package.json中 "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",利用webpack-dev-server插件,搭建一个服务器,执行webpack.dev.conf.js,内置的服务器没有/get/api接口,所以会报错。
解决方法:设置转发的域
具体做法:查看package.json文件,"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",双击打开build/webpack.dev.conf.js文件,找到proxy设置代理,按住Ctrl并鼠标点击proxy: config.dev.proxyTable,此时会进入index.js文件,配置转发的域,具体做法见下图,而后在终端按下Ctrl+c,而后 npm start 重启项目。
点击get请求button,请求成功的标志,见下图:
comunication.vue组件中的get请求代码
// 发起get请求 Vue.axios.get('/api/get', { // get传递的query参数(传递的参数应与后台人员协商,本次模拟不做限制,不做判断) params: { name: '嬴政', age: 45 } }).then((response) => { // then 指成功之后的回调 (注意:使用箭头函数,可以不考虑this指向) console.log(response); console.log(response.data); this.resData = response.data; }).catch((error) => { // catch 指请求出错的处理 console.log(error); });
axios的post请求方法介绍
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
点击post请求button,请求成功的标志,见下图:
comunication.vue组件中的post请求代码
// 提示:该方式传递的参数是json格式,如上传不成功,需检查后台接收的方式是不是application/x-www-form-urlencoded默认格式,jquery中ajax请求的就是application/x-www-form-urlencoded,后台需要body-parser解码 Vue.axios.post('/api/post', { // 此参数就是写到请求体中的参数 stuName: '盖聂', height: 180 }).then((response) => { console.log(response); console.log(response.data); this.postData = response.data; }).catch((error) => { console.log(error); });
服务器端server.js文件
附加练习:引入body-parser访问body做法:因为node-modules中依赖已经包含了body-parser,直接使用即可。根据post请求传入参数的形式,阅读body-parser的readme文件,选择合适的使用方式。
代码修改:在server.js文件中添加以下代码
var bodyParser = require('body-parser'); app.use(bodyParser.json());
三、示例代码
comunication.vue
<template> <div id="comunication"> <h3>comunication组件--通信组件</h3> <button @click="doGet">GET请求</button> <br> <span class="getData">get请求到的数据:{{resData}}</span> <button @click="doPost">POST请求</button> <br> <span class="postData">post请求到的数据:{{postData}}</span> <h4>vue-axios网络请求演示参考网站</h4> <a href="https://github.com/imcvampire/vue-axios">https://github.com/imcvampire/vue-axios</a> <a href="https://www.npmjs.com/package/axios">https://www.npmjs.com/package/axios</a> <form action="" enctype="application/x-www-form-urlencoded"></form> </div> </template> <script> // 需要使用Vue,所以需要引入 import Vue from 'vue' export default { data (){ return { resData:[], postData:[] } }, // vue高版本中,推荐使用axios进行网络请求,而不再使用vue-resource methods: { doGet(){ // 发起get请求 Vue.axios.get('/api/get', { // get传递的query参数(传递的参数应与后台人员协商,本次模拟不做限制,不做判断) params: { name: '嬴政', age: 45 } }).then((response) => { // then 指成功之后的回调 (注意:使用箭头函数,可以不考虑this指向) console.log(response); console.log(response.data); this.resData = response.data; }).catch((error) => { // catch 指请求出错的处理 console.log(error); }); }, doPost(){ // 提示:该方式传递的参数是json格式,如上传不成功,需检查后台接收的方式是不是application/x-www-form-urlencoded默认格式,jquery中ajax请求的就是application/x-www-form-urlencoded,后台需要body-parser解码 Vue.axios.post('/api/post', { // 此参数就是写到请求体中的参数 stuName: '盖聂', height: 180 }).then((response) => { console.log(response); console.log(response.data); this.postData = response.data; }).catch((error) => { console.log(error); }); } } } </script> <style scoped> #comunication { border: 1px solid gold; padding: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; margin-bottom: 10px; } h3 { width: 100%; height: 60px; line-height: 60px; text-align: center; background: gainsboro; font-size: 30px; } button { background-color: #008CBA; padding: 10px 20px; border: none; font-size: 18px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; display: block; } button:hover { background-color: #008CDA; color: #ffffff; } h4 { font-size: 24px; } a { background: rgba(255, 255, 0, 0.5); padding: 5px 20px; width: 350px; border-radius: 8px; text-decoration: none; } .getData,.postData{ font-size: 20px; background: greenyellow;padding: 5px 10px 5px 20px; border-radius:18px; display: block; margin-bottom: 20px; margin-top: 10px; width: 900px; } </style>
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 axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios, axios); Vue.config.productionTip = false; /* eslint-disable no-new */ new Vue({ el: '#app', components: { App }, template: '<App/>', data(){ return { totalVm: new Vue() } } })
index.js
'use strict' // Template version: 1.3.1 // see http://vuejs-templates.github.io/webpack for documentation. const path = require('path') module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { // 配置转发的域 /api下面的请求均发起转发 '/api':{ target:'http://127.0.0.1:5888', changeOrigin:true } }, // Various Dev Server settings host: 'localhost', // can be overwritten by process.env.HOST port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined autoOpenBrowser: false, errorOverlay: true, notifyOnErrors: true, poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- /** * Source Maps */ // https://webpack.js.org/configuration/devtool/#development devtool: 'cheap-module-eval-source-map', // If you have problems debugging vue-files in devtools, // set this to false - it *may* help // https://vue-loader.vuejs.org/en/options.html#cachebusting cacheBusting: true, cssSourceMap: true }, build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/', /** * Source Maps */ productionSourceMap: true, // https://webpack.js.org/configuration/devtool/#production devtool: '#source-map', // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to `true`, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: false, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: // `npm run build --report` // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report } }
以下为示例涉及的其他代码(与博客介绍的内容关系不大,主要复习组件间的通信,为防止运行错误,现附上代码)
test.vue
<template> <div id="test"> <h3>test组件--演示组件传值与方法调用</h3> <button @click="doClick()">点击按钮,向根组件传值</button> <p class="childToParent">app组件传过来的值:{{cn}}<span class="tip">提示:父向子传值</span></p> <table border="1" cellspacing="0" width="250"> <tr> <th>ID</th> <th>姓名</th> <th>身高</th> </tr> <tr v-for="girl in arr" :key="girl.ID"> <td>{{girl.ID}}</td> <td>{{girl.name}}</td> <td>{{girl.height}}</td> </tr> </table> </div> </template> <script> export default { name: 'test', props: { cn: { type: String } }, data(){ return { msg: 'hello world', arr: [] } }, created(){ this.$root.totalVm.$on('custom', (v) => { this.arr = v; }) }, methods: { doClick(){ console.log('您点击了按钮。。。'); this.$emit('event1', this.msg); } } } </script> <style scoped> #test { border: 3px solid green; border-radius: 8px; padding: 10px; margin-bottom: 10px; } h3 { width: 100%; height: 60px; line-height: 60px; text-align: center; background: gainsboro; font-size: 30px; } button { background-color: #008CBA; padding: 10px 20px; border: none; font-size: 18px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } button:hover { background-color: #008CDA; color: #ffffff; } tr { text-align: center; font-size: 16px; } .childToParent { font-size: 24px; } .tip { background: red; font-size: 16px; padding: 5px 10px; border: 1px solid transparent; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; margin-left: 20px; } </style>
test02.vue
<template> <div id="test02"> <h3>test02组件--演示组件传值与方法调用</h3> <button @click="doClick">向test组件发送消息,生成动态表格填充数据</button> <span class="tip">提示:兄弟组件通信</span> </div> </template> <script> export default { data(){ return { aGirls: [{ name: '韩非', height: 180, ID: 1002 }, { name: '李斯', height: 182, ID: 1003 }, { name: '卫庄', height: 183, ID: 1004 }, { name: '嬴政', height: 183, ID: 1005 } ] } }, methods: { doClick(){ this.$root.totalVm.$emit('custom', this.aGirls) } } } </script> <style scoped> #test02 { border: 2px solid blue; padding: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; margin-bottom: 10px; } h3 { width: 100%; height: 60px; line-height: 60px; text-align: center; background: gainsboro; font-size: 30px; } button { background-color: #008CBA; padding: 10px 20px; border: none; font-size: 18px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } button:hover { background-color: #008CDA; color: #ffffff; } .tip { background: red; font-size: 16px; padding: 5px 10px; border: 1px solid transparent; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; margin-left: 20px; } </style>
app.vue
<template> <div id="app"> <h3>app组件--根组件</h3> <p class="testToApp">test组件传过来的值为:{{szStr}}<span class="tip">提示:子向父传值</span></p> <!--必须引入才可以显示子组件的内容--> <my-test @event1="getInfo($event)" :cn="carName"></my-test> <my-test02></my-test02> <my-comunication></my-comunication> </div> </template> <script> // 引入 import myTest from './components/test.vue'; import myTest02 from './components/test02.vue' import myComunication from './components/comunication/Comunication.vue' export default { name: 'App', components: { myTest, myTest02, myComunication }, data(){ return { szStr: '', carName: 'BWM' } }, methods: { getInfo(e){ this.szStr = e; } } } </script> <style scoped> #app { border: 3px dashed #d17bff; padding: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; } h3{ width: 100%; height: 60px; line-height: 60px; text-align: center; background: gainsboro; font-size: 30px; } .testToApp{ font-size: 24px; } .tip { background: red; font-size: 16px; padding: 5px 10px; border: 1px solid transparent; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; margin-left: 20px; } </style>
四、效果图