一、Vuex简介
vuex是一个专门为Vue.js设计的集中式状态管理架构。我们把它理解为在data中需要共享给其他组件使用的部分。
Vuex和单纯的全局对象有以下不同:
- 1、Vuex 的状态存储是响应式的。当vue组件从store中读取状态的时候,
若store中的状态发生变化,那么相应的组件也会相应的得到高效更新。 - 2、你不能直接改变store中的状态。改变store中的状态的唯一途径就是显示的
提交(commit)mutation。这样使得我们可以方便的跟踪每一个状态的变化,
从而让我们能够实现一些工具来帮助我们更好的了解我们的应用。
二、安装使用vuex
安装: -- npm install vuex
方式一:
// main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import vuex from 'vuex'
Vue.use(vuex)
Vue.config.productionTip = false
const store = new vuex.Store({
state: {
show: false,
}
});
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
});
方式二:
- 为了方便维护,我们通常把在src下面新建一个store文件夹,然后在里面新建一个index.js
import Vue from 'vue'
import Vue_x from "vuex"
Vue.use(Vue_x);
export default new Vue_x.Store({
state: {
show: false,
},
});
- 那么main.js要改成
import Vue from 'vue'
import App from './App'
import router from './router'
import store from "./store"
Vue.config.productionTip = false;
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
});
三、vuex的三种方法
- State
简而言之~~state是保存我们data中需要共享的数据。
由于Vuex的存储是响应式的,从store实例中读取状态的最简单的方式就是在计算属性中返回某个状态。
this.$store.state.count
// 创建一个组件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count(){
return this.$store.state.count
}
}
};
- Getter
有时候我们需要从store中的state中派生出一些状态,例如对数据进行简单的计算。
并且很多组件都需要用到此方法,我们要么复制这个函数,要么抽取到一个公共函数,多处导入。我们vuex提供了更加方便的方法,getter ,它就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,只有它的依赖发生改变时,才会重新计算。
Getter会接收state作为其第一个参数:
Getter的使用:
import Vue from 'vue'
import Vue_x from "vuex"
Vue.use(Vue_x);
export default new Vue_x.Store({
state: {
count: 20,
},
// 通过 this.$store.getters.my_func
getters: {
my_func: function (state) {
return state.count * 2
}
},
});
Getters也能接收getters作为第二个参数:
import Vue from 'vue'
import Vue_x from "vuex"
Vue.use(Vue_x);
export default new Vue_x.Store({
state: {
count: 20,
},
// 通过 this.$store.getters.my_func
getters: {
my_func: function (state) {
return state.count * 2
},
// 通过 this.$store.getters.my_func_count
my_func_count: function (state, getters) {
return getters.my_func.length
}
},
});
- Mutation
更改Vuex中的store中的状态的唯一方法是提交mutation。
每个mutation都有一个字符串的事件类型(type),和一个回调函数handler。
也就是说我们要触发mutation中定义的方法(type),然后才会执行这个方法(handler)。
这个方法就是我们更改状态的地方,它会接收state为第一个参数,后面接收其他参数:
mutation 的基本使用:
mutation中的事件需要通过 this.$store.commit('increment', 10)这个方式来提交触发事件
import Vue from 'vue'
import Vue_x from "vuex"
Vue.use(Vue_x);
export default new Vue_x.Store({
state: {
count: 20,
},
// 需要通过 this.$store.commit('increment', 10)
mutations: {
increment (state, n) {
// 变更状态
state.count += n
}
}
});
Mutation需要遵守Vue的响应规则:
既然vuex中的store中的状态是响应式的,那么当我们状态变更时,监视状态的vue组件也会更新。这就意味着vuex中的mutation也需要与使用vue一样遵守一些注意事项:
-- 1,最好提前在你的store中初始化好所有的所需要的属性
-- 2,当对象需要添加属性时,你应该使用
-- Vue.set(obj, 'newProp', 123)
-- 以新对象代替老对象 state.obj = { ...state.obj, newProp: 123}
四、axios的简单使用
基于Promise的HTTP请求客户端,可以同时在浏览器和node.js使用
- 安装axios:
-- npm install axios -D
- 基本配置:
// main.js
import axios from "axios"
Vue.prototype.$axios = axios
// 组件中
methods: {
init () {
this.$axios({
method: "请求方式",
url: "后端的url"
})
},
};
- 基本使用:
- get请求
test(){
this.$axios.get(this.$store.state.apiList.course,{
params: {
id: 123,
}
}).then(function (response) {
// 请求成功回调函数
}).catch(function (response) {
// 请求失败的回调函数
})
}
- post请求:
test(){
this.$axios.post(this.$store.state.apiList.course,{
course_title: "Python",
course_price: "19.88"
}).then(function (response) {
// 请求成功回调函数
}).catch(function (response) {
// 请求失败的回调函数
})
}
- 发送多个并发请求:
function getCourse(){
return this.$axios.get('/course/12')
}
function getCourse_all() {
return this.$axios.get('/course')
}
this.$axios.all([getCourse_all(),getCourse()])
.then().catch()
- axios.request方式:
methods: {
init(){
var that = this
this.$axios.request({
url: that.$store.state.apiList.course,
method: 'get'
}).then(function (data) {
if (data.status === 200){
that.courseList = data.data
}
}).catch(function (reason) {
console.log(reason)
})
}
},
五、简单实例:
- vue组件代码:
<template>
<div>
<h1>这是轻课</h1>
<el-table :data="tableData2" :border="true" :row-class-name="tableRowClassName">
<el-table-column prop="date" label="日期" width="100"></el-table-column>
<el-table-column prop="name" label="姓名" width="100"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "qingke",
//element的事件方法
methods: {
tableRowClassName({row, rowIndex}) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
}
},
//定义的数据
data() {
return {
tableData2: "",
}
},
//生命周期函数,加载完页面就执行里面的方法
mounted() {
let that = this;
this.$axios.request({
url: "http://127.0.0.1:8000/index/",
method: "get"
}).then(function (data) {
console.log(data)
that.tableData2 = data.data
}).catch(function (data) {
console.log(222)
})
}
}
</script>
//样式省略
</style>
- 基于Django实现的后端:
- urls:
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
]
- views.py
from django.shortcuts import render
from django.http import JsonResponse
def index(request):
tableData2 = [{
'date': '2016-05-02',
'name': '王计飞',
'address': '上海市普陀区金沙江路 1518 弄',
}, {
'date': '2016-05-04',
'name': '刘德凯',
'address': '上海市普陀区金沙江路 1518 弄'
}, {
'date': '2016-05-01',
'name': '杜彪',
'address': '上海市普陀区金沙江路 1518 弄',
}, {
'date': '2016-05-03',
'name': '左帮政',
'address': '上海市普陀区金沙江路 1518 弄'
},
{
'date': '2016-05-03',
'name': '李永辉',
'address': '上海市普陀区金沙江路 1513 弄'
}
]
return JsonResponse(tableData2, safe=False)
- 解决跨域问题的middlemares
middlewares.py:需要django注册
from django.utils.deprecation import MiddlewareMixin
class my_middleware(MiddlewareMixin):
def process_response(self, request, response):
response["Access-Control-Allow-Origin"] = "*"
if request.method == "OPTIONS":
response["Access-Control-Allow-Headers"] = "Content-Type"
response["Access-Control-Allow-Methods"] = "POST, DELETE, PUT"
return response
-
前端数据渲染得到视图
后端按照前端数据的格式要求返回数据,前端拿到数据后驱动生成视图,所以Vue的开发前后端只需要沟通好接口就行,从而大大提高了开发的效率。