Vuex、axios、跨域请求处理和import/export的注意问题
一、Vuex
1、介绍
vuex是一个专门为Vue.js设计的集中式状态管理架构。
对于状态,我们把它理解为在data中需要共享给其他组件使用的部分数据。
Vuex和单纯的全局对象有以下不同: 1. Vuex 的状态存储是响应式的。当vue组件从store中读取状态的时候,
若store中的状态发生变化,那么相应的组件也会相应的得到高效更新。 2. 你不能直接改变store中的状态。改变store中的状态的唯一途径就是显示的
提交(commit)mutation。这样使得我们可以方便的跟踪每一个状态的变化,
从而让我们能够实现一些工具来帮助我们更好的了解我们的应用。
2、vuex的安装和实例化
1. 安装命令
-- npm install vuex
2. 实例化的两种方式
方式一:直接在main.js里面注册vuex的仓库实例
// main.js
import Vue from 'vue'
import App from './App'
import Vuex from 'vuex' // 让vue实例使用Vuex
Vue.use(Vuex) Vue.config.productionTip = false // 实例化Vuex的仓库,store代表仓库
const store = new Vuex.Store({
// state存放所有的公用数据
state: {
name : "bdyjy",
}
}); new Vue({
el: '#app',
// 注册store: store
store,
components: { App },
template: '<App/>'
});
方式一
方式二:为了方便维护,通常在src下面新建一个store文件夹,然后在里面新建一个index.js
// store/index.js
import Vuex from "vuex"
import Vue from "vue" Vue.use(Vuex); // 抛出实例化的Vuex仓库,store代表仓库
export default new Vuex.Store({
// state存放所有的公用数据
state: {
name : "bdyjy",
}
}) // main.js
import Vue from 'vue'
import App from './App'
import store from "./store/index" Vue.config.productionTip = false new Vue({
el: '#app',
// 注册store: store
store,
components: { App },
template: '<App/>'
});
方式二
3、获取数据
1. state
state是保存我们data中需要共享的数据。
由于Vuex的存储是响应式的,从store实例中读取状态可以使用:this.$store.state.变量名
且应该在计算属性中返回某个状态,因为计算属性实时在监听数据,数据变化了,它立刻就能知道,
如果在data属性中返回某个状态,那么这个数据如果在后续变化了,它也不知道了,因为data在加载完成后就不会再监听这个数据 示例:在某个组件中使用
// course.vue
<template>
<div>
<h2>这是课程组件</h2>
<p>我是{{name}}</p>
</div>
</template> <script>
export default {
name: "Course",
// 使用计算属性获取仓库里面的name变量的值
computed: {
name: function () {
return this.$store.state.name
}
}
}
</script>
2. getters
有时候我们需要从store中的state中派生出一些状态,例如对数据进行简单的计算。
并且很多组件都需要用到此方法,我们要么复制这个函数,要么抽取到一个公共函数,多处导入。
我们vuex提供了更加方便的方法,getters 它就像计算属性一样,getters的返回值会根据它的依赖被
缓存起来,只有它的依赖发生改变时,才会重新计算。 简单地来说,getters可以对状态进行二次处理
1. // store/index.js
import Vuex from "vuex"
import Vue from "vue" Vue.use(Vuex); // 抛出实例化的Vuex仓库,store代表仓库
export default new Vuex.Store({
// state存放所有的公用数据
state: {
name : "bdyjy",
},
// getters对state的值进行二次处理
getters: {
friend: function (state) {// 接收state作为参数
return state.name + '的朋友是:jty'
}
}
}) 2. // 在某个组件中使用
// course.vue
<template>
<div>
<h2>这是课程组件</h2>
<p>我是{{name}}</p>
<p>{{friend}}</p>
</div>
</template> <script>
export default {
name: "Course",
computed: {
name: function () {// 通过state取值
return this.$store.state.name
},
friend: function () {// 通过getters取值
return this.$store.getters.friend
}
}
}
</script>
示例1
1. // store/index.js
import Vuex from "vuex"
import Vue from "vue" Vue.use(Vuex); // 抛出实例化的Vuex仓库,store代表仓库
export default new Vuex.Store({
// state存放所有的公用数据
state: {
name : "bdyjy",
},
// getters对state的值进行二次处理
getters: {
friend: function (state) {// 接收state作为参数
return state.name + '的朋友是:jty'
},
play: function (state, getters) {// 接收state和getters作为参数
// 因为要取到friend,就要state
return getters.friend + '一起玩'
}
}
}) 2. // 在某个组件中使用
// course.vue
<template>
<div>
<h2>这是课程组件</h2>
<p>我是{{name}}</p>
<p>{{friend}}</p>
<p>{{play}}</p>
</div>
</template> <script>
export default {
name: "Course",
computed: {
name: function () {// 通过state取值
return this.$store.state.name
},
friend: function () {// 通过getters取值
return this.$store.getters.friend
},
play: function () {
return this.$store.getters.play
}
}
}
</script>
示例2
4、更改store中的状态
1. 回想一下非父子之间的组件之间是如何进行通信的
-- 新建一个新的vue实例当做两个组件之间通信的桥梁
-- 一个组件使用 $emit 向这个vue实例提交事件
-- 另一个组件在加载完成后这个vue实例通过钩子函数mounted 使用 $on 监听$emit提交的事件然后处理
2. vuex更改store中的状态类似于上面的步骤
-- 通过this.$store.commit('事件名称', '数据')提交事件到这个vuex仓库
-- 在Vuex.Store这个实例里面通过mutations接收提交过来的事件
-- mutations里面的事件它会接收state为第一个参数,后面接收其他参数
3.示例
<template>
<div>
<h2>这是学位课程信息</h2>
<button @click="my_click">点击展示学位信息</button>
<h3>{{degree_info}}</h3>
</div>
</template> <script>
export default {
name: "DegreeCourse",
computed: {
degree_info: function () {
return this.$store.state.degree_info
}
},
methods: {
// 提交事件到store
my_click: function () {
this.$store.commit('degree_info', '博士')
}
}
}
</script>
某个组件
import Vuex from "vuex"
import Vue from "vue" Vue.use(Vuex); // 抛出实例化的Vuex仓库,store代表仓库
export default new Vuex.Store({
state: {
degree_info: ''
},
// commit上来的事件在这里进行处理
mutations: {
degree_info: function (state, data) {
state.degree_info = data
}
}
})
store/index.js
二、axios的简单使用
1、安装
使用npm安装axios
-- npm install axios axios是基于promise用于浏览器和node.js的http客户端
2、axios基本参数
url:请求接口地址
method:请求方式
data:请求数据
headers:请求头
then(function(response){}):请求成功后的回调函数
catch(function(error){})请求失败后的回调函数
1.发送ajax请求
$.ajax({}) 参数:
url: 提交到哪个URL地址 type: 提交的方式 data: {你要发送的数据} success: function (res) {
请求发送过去,被正常响应后执行的函数,res是后端返回来的数据
} error: function (err) {
请求发送过去,响应失败时执行的函数
} 2.示例
$.ajax({
url: '/regirest/',
type: 'POST',
data: {
username: 'xxx',
},
success: function (res) {
console.log(res)
}
})
对比ajax
3、几种请求方法
1. get请求
// 携带参数的get请求
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
方式一
// 上面的请求可以这样做
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
方式二
2. post请求
axios.post('/user', {
    username: 'xiaoming',
    password: '123abcd'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
post请求
3. 执行多个并发请求
function getUserAccount() {
  return axios.get('/user/12345');
}
function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
  .then().catch();
并发请求
4. axios.request(推荐使用这种)
axios.request({
  url: '/user/12345',
  method: 'post',  // 请求方式:get、post、delete等等
  data: {
    username: 'xiaoming',
    password: '123abcd'
  }
}).then(function (response) {
        console.log(response);
}).catch(function (error) {
        console.log(error)
});
axios.request
4、示例
1. 把axios设置成Vue对象属性
下载好axios后,在需要使用的地方导入axios即可直接使用,axios类似于ajax,用于向后端进行数据传输
但是axios是不能注册到Vue实例里面,因此不能通过this.$axios进行使用的,因为它不是Vue实例的属性,
但是我们就是希望能够通过this.$axios对它进行使用呢,可以给Vue的原型链prototype增加一个$axios属性,
然后所有的Vue对象都可以通过this.$axios对它进行使用 // main.js
import axios from "axios" Vue.prototype.$axios = axios
2. Vue代码
<script>
export default {
name: "DegreeCourse",
mounted(){
this.$axios.request({
url: "http://127.0.0.1:8000/test/", // 后端地址
method: "get" // 提交方式
}).then(function (response) {// then是成功后的回调函数
console.log(response);
}).catch(function (error) {// catch是失败后的回调函数
console.log(error);
})
}
}
</script>
3. 浏览器的同源策略
当这个组件加载完后,会自动向后端http://127.0.0.1:8000/test/ 发送 get 请求,
但是这样发送的请求是属于跨域请求,由于浏览器的同源策略,服务器给我们返回的信息浏览器会给我们拦截下来,
所以如果后端返回消息的时候不进行一些处理的话,前端这里是收不到消息的并且会报错。(前后端的域名和端口只要其中一个不一样,就是跨域),
跨域的ajax请求就会被浏览器拦截(axios发送的也是ajax请求)。
那怎么处理?继续往下看..
三、CORS跨域请求介绍
1、区分简单请求和复杂请求
HTTP方法是下列方法之一
HEAD, GET,POST HTTP头信息不超出以下几种字段
Accept, Accept-Language, Content-Language, Last-Event-ID Content-Type只能是下列类型中的一个 application/x-www-form-urlencoded multipart/form-data text/plain 任何一个不满足上述要求的请求,即会被认为是复杂请求
复杂请求会先发出一个预请求,我们也叫预检,OPTIONS请求 也就是说,HEAD, GET,POST这三个请求,当它们满足上面的头信息时,它们就是简单请求,否则都是复杂请求,
比如一个get请求,但是它请求头的Content-Type是application/json类型,那么它也是复杂请求。
复杂请求会先发出一个OPTIONS预请求。
2、请求头
Accept
我能解析什么数据类型 ContentType
我给你的是什么数据类型 数据类型
application/x-www-form-urlencoded --> form表单的默认编码方式,不能上传文件
multipart/form-data --> 二进制的形式,能上传文件
text/plain --> 文本
application/json --> json格式
html
xml
四、跨域请求处理--jsonp
1、 原理(现在很少有人使用这种方式处理跨域请求)
我们可以发现,我们使用CDN引进任何链接的时候,引进了就可以使用了,但是,CDN的链接对于我们来说也是跨域,为什么不会报错呢?
原因是对于script、link或img这些标签,他们引入CDN只是发送get请求获取资源,浏览器认为这没有风险,所以可以正常进行请求,
而ajax可以发送任何类型的请求,风险太大,浏览器就自动把它们拦截了(浏览器只阻止表单以及ajax请求)。
比如script标签src想某个CDN发送get请求,拿到的所有资源就会存在script标签内,你就可以在script标签内使用这些内容。
2、示例
// 某前端页面代码
<script>
// 定义一个函数
function handlerResponse(data) {
console.log(data)
}
</script> // 向后端发送请求,拿到handlerResponse函数并执行
<script src="http://127.0.0.1:8000/test/"></script>
某前端页面代码
// 某Django后端代码
class TestView(views.View):
def get(self, request):
# 返回一个handlerResponse("ok")字符串
return HttpResponse('handlerResponse("ok")')
某Django后端代码
五、CORS跨域请求之简单请求处理
1、 get跨域简单请求
1. 报错原因
Access-Control-Allow-Origin --> 前端这个域不被允许接收后端的数据
2. 后端视图函数
class TestView(views.View):
def get(self, request):
return HttpResponse('嘿嘿')
3. 后端中间件
from django.utils.deprecation import MiddlewareMixin class MyCores(MiddlewareMixin):
def process_response(self, request, response):
# 给这个响应添加响应头
# 告诉浏览器我这个后端允许响应头指定的域拿到我的响应数据(*代表所有域)
response['Access-Control-Allow-Origin'] = '*' # http://localhost:8080代表只能让这个域拿到我的数据
# response['Access-Control-Allow-Origin'] = 'http://localhost:8080'
return response
4. 前端Vue
<script>
export default {
name: "DegreeCourse",
mounted(){
this.$axios.request({
url: "http://127.0.0.1:8000/test/", // 后端地址
method: "get" // get简单请求
// method: "post" // post简单请求
}).then(function (response) {// then是成功后的回调函数
console.log(response); // 接收到后端response的数据是一个对象
}).catch(function (error) {// catch是失败后的回调函数
console.log(error);
})
}
}
</script>
2、 post跨域简单请求
注意:前后端分离的项目没办法提交csrf,有些框架是可以默认过滤跳过这个验证,现在的话,我们先在后端把csrf中间件注释掉
代码跟上面一样,只是在前端把method的提交方式改成post即可
六、CORS跨域请求之复杂请求处理
1、delete跨域复杂请求
1. 报错原因
Access-Control-Allow-Methods --> 这个请求方法不被允许
2. 后端视图函数
class TestView(views.View):
def delete(self, request):
return HttpResponse("返回DELETE数据")
3. 后端中间件
class MyCores(MiddlewareMixin):
def process_response(self, request, response):
# 给这个响应添加响应头
# 告诉浏览器我这个后端允许响应头指定的域拿到我的响应数据(*代表所有域)
response['Access-Control-Allow-Origin'] = '*'
# http://localhost:8080代表只能让这个域拿到我的数据
# response['Access-Control-Allow-Origin'] = 'http://localhost:8080' # 如果是复杂请求,会先发送OPTIONS预检
if request.method == 'OPTIONS':
# 如果是复杂请求的方法不被允许,那么就给告诉浏览器我允许这个复杂请求
response["Access-Control-Allow-Methods"] = "DELETE"
return response
4. 前端Vue
<script>
export default {
name: "DegreeCourse",
mounted(){
this.$axios.request({
url: "http://127.0.0.1:8000/test/", // 后端地址
method: 'delete' // delete复杂请求
}).then(function (response) {// then是成功后的回调函数
console.log(response); // 接收到后端response的数据是一个对象
}).catch(function (error) {// catch是失败后的回调函数
console.log(error);
});
}
}
</script>
2、post发送复杂请求
1. 报错原因
Access-Control-Allow-Headers --> 这个请求头的数据类型不被允许
2. 后端视图函数
class TestView(views.View):
def post(self, request):
return HttpResponse("返回POST数据")
3. 后端中间件
class MyCores(MiddlewareMixin):
def process_response(self, request, response):
# 给这个响应添加响应头
# 告诉浏览器我这个后端允许响应头指定的域拿到我的响应数据(*代表所有域)
response['Access-Control-Allow-Origin'] = '*'
# http://localhost:8080代表只能让这个域拿到我的数据
# response['Access-Control-Allow-Origin'] = 'http://localhost:8080' # 如果是复杂请求,会先发送OPTIONS预检
if request.method == 'OPTIONS':
# 如果是复杂请求的方法不被允许,那么就给告诉浏览器我允许这个复杂请求
response["Access-Control-Allow-Methods"] = "DELETE"
# 告诉浏览器这个请求头的数据类型我是允许的
response["Access-Control-Allow-Headers"] = "Content-Type"
return response
4. 前端Vue
<script>
export default {
name: "DegreeCourse",
mounted(){
this.$axios.request({
url: "http://127.0.0.1:8000/test/", // 后端地址
method: 'post', // post发送复杂请求
contentType: "application/json",
data: {
"author": "狗屎"
}
}).then(function (response) {// then是成功后的回调函数
console.log(response); // 接收到后端response的数据是一个对象
}).catch(function (error) {// catch是失败后的回调函数
console.log(error);
}) }
}
</script>
3、总结
-- 复杂请求什么不被允许,那么我们就在中间件给它设置成是允许的即可
-- 前端拿到的响应数据是一个对象,具体的值存在这个对象的data属性里面,取值:响应对象.data
-- 响应对象还有其他数据:
config: {...}
data: "后端返回的具体数据"
headers: {content-type: "text/html; charset=utf-8"}
request: XMLHttpRequest {…}
status: 200
statusText: "OK"
七、VUE中import 、export的注意事项
1、导包的问题
1. import引入一个依赖包,不需要相对路径
示例:import axios from 'axios'; 2. import 引入一个自己写的js文件,是需要相对路径的
import AppService from './appService';
2、export import注意事项
"""
import什么情况下,要用{}的方式引入,
什么情况下,只需要一个变量就行。
""" 1. 使用export抛出的变量需要用{}进行import引入
# a.js
let name = "xiaoming";
let age = 18;
export {name, age} # b.js
import {name, age} from "./a.js" 2. 使用export default抛出的变量,只需要自己起一个名字就行
# a.js
var obj = { name: '狗明' };
export default obj; # b.js
import aaa from './a.js';
console.log(aaa.name); // '狗明' 3. 注意
一个js文件中,只能有一个export default,但是可以有多个export
Vuex、axios、跨域请求处理和import/export的注意问题的更多相关文章
- $Django 前后端之 跨域问题(同源策略)  vue项目(axios跨域请求数据)
		
1 跨域问题(多个域之间的数据访问) #同源策略(ip port 协议全部相同) #本站的只能请求本站域名的数据 #CORS实现(跨域资源共享) #实现CORS通信的关键是服务器.只要服务器实现了CO ...
 - vue 使用axios 跨域请求数据的问题
		
axios默认是没有jsonp 跨域请求的方法的.一般来说流行的做法是将跨域放在后台来解决,也就是后台开发人员添加跨域头信息. 例如java中的 header,response.setHeader(& ...
 - vue-cli3.0+node.js+axios跨域请求session不一样的问题
		
一.问题重述 使用的是,前后端分离,前端vue+axios请求,后端使用node搭建服务端接口,遇到的问题是,我通过登录接口吧数据存储型在session,我登录上以后,发现再次验证登录(另一个接口)的 ...
 - axios跨域请求报错:Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
		
在做项目时,用到axios,数据用post提交时,老是报错,错误提示为: Access to XMLHttpRequest at 'http://127.0.0.1:3000/api/add' fro ...
 - axios 跨域请求允许带cookie,则服务器Access-Control-Allow-Origin应设置为具体域名,否则请求无法获得返回数据
		
1.通过允许跨域访问实现了跨域请求,但为了使每个请求带上session信息,我设置了withCredentials ,即: axios.defaults.withCredentials = true ...
 - vue axios跨域请求,apache服务器设置
		
问题所在axios请求会发送两次请求 也就是说,它会先使用options去测试,你这个接口是否能够正常通讯,如果不能就不会发送真正的请求过来,如果测试通讯正常,则开始正常请求. 思路: 跨域--> ...
 - vue-cli 3.0 axios 跨域请求代理配置及生产环境 baseUrl 配置
		
1. 开发环境跨域配置 在 vue.config.js 文件中: module.exports = { runtimeCompiler: true, publicPath: '/', // 设置打包文 ...
 - vue axios跨域请求,代理设置
		
在config下的index.js中的dev下的 proxyTable{}中设置代理 proxyTable: { '/api': { target: 'http://10.0.100.7:8081', ...
 - axios跨域请求报错
		
在nodejs的入口js中的配置路由之前加入这一段就可以了 app.all('*', function(req, res, next) { res.header("Access-Contro ...
 
随机推荐
- Vue中父组件传子组件
			
父组件代码: <template> <section :class="menuMode === 'vertical' ? 'vertical-sub-nav' : 'sub ...
 - 跨域iframe如何实现高度自适应?
			
经常有项目会要求实现iframe高度自适应,如果是同域的还好说,如果是跨域的,父页面没有办法操作子页面,想要正确获取子页面高度的话,可以采用以下办法: 方法一:使用HTML5 postMessage ...
 - 【图解】FlexGrid Explorer 全功能问世
			
前言 在去年的时候,我们推出了FlexGrid Demo,包含了FlexGrid的常用功能,如分组.滚动.冻结.自定义单元格类型.搜索面板.表格过滤器.树形结构.合并单元等,目前我们又在里面添加很多了 ...
 - 仿9GAG制作过程(五)
			
有话要说: 在做完了数据展示功能之后,就想着完善整个APP.发现现在后台非常的混乱,有好多点都不具备,比方说:图片应该有略缩图和原图,段子.评论.点赞应该联动起来,段子应该有创建时间等. 于是就重新设 ...
 - C++ 重点关键字
			
const 四种用法 1.修饰变量起到限定只读作用: void func(const int a, const string str) {...} const int* func(...) {...} ...
 - JSON.Net 自定义Json序列化时间格式
			
JSON.Net 自定义Json序列化时间格式 Intro 和 JAVA 项目组对接,他们的接口返回的数据是一个json字符串,里面的时间有的是Unix时间戳,有的是string类型,有的还是空,默认 ...
 - 【原】Java学习笔记002 - JAVA SE编码规范
			
/* * 编码规范: * 1.所有的命名遵循"见名知意"的原则 * 2.所有的命名不允许使用汉字或拼音 * 3.Java的工程命名建议使用小写,比如:oa.crm.cms... * ...
 - Ambari——大数据平台的搭建利器之进阶篇
			
前言 本文适合已经初步了解 Ambari 的读者.对 Ambari 的基础知识,以及 Ambari 的安装步骤还不清楚的读者,可以先阅读基础篇文章<Ambari——大数据平台的搭建利器>. ...
 - linux-python3.8安装
			
环境: centos7.5 版本:python3.8 1.依赖包安装 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-deve ...
 - Linux实战教学笔记50:Zabbix监控平台3.2.4(二)深入理解zabbix
			
https://www.cnblogs.com/chensiqiqi/p/9162986.html 一,Zabbix Web操作深入 1.1 Zabbix Web下的主机和模版以及监控项的添加方式 ( ...