vue生态系统之vuex
一、webpack生成项目
1、webpack
在需要建立项目的目录中进行初始化项目
E:\vueProject>vue init webpack vuexpj
? Project name vuexpj
? Project description A Vue.js project
? Author bright <bright@live.com>
? Vue build (Use arrow keys)
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
安装参数选择
2、项目组件关系图
在父组件App.vue中导入Vheader.vue组件:
<template>
<div id="app">
<Vheader></Vheader>
<router-view/>
</div>
</template> <script>
import 'bootstrap/dist/css/bootstrap.min.css' import Vheader from '@/components/Vheader' export default {
name: 'App', components:{
Vheader,
}
}
</script> <style scoped> </style>
App.vue
在Vheader.vue组件中渲染路由:
<template>
<el-menu
:default-active="activeIndex2"
class="el-menu-demo"
mode="horizontal"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="0"> <router-link to="/user">用户管理</router-link></el-menu-item>
<el-menu-item index="1" ><router-link to="/depart">部门管理</router-link></el-menu-item>
</el-menu> </template> <script>
export default {
name: "Vheader",
data:function () {
return {
activeIndex2: '0',
}
},
methods:{
//在当前组件内调用
},
computed:{
//在在当前组件内调用
}
}
</script> <style scoped>
/*设置scoped,只对当前组件样式起作用*/ </style>
Vheader.vue
在父组件App.vue中设置路由出口,路由对应组件的内容在这里输出:
<template>
<div id="app">
<Vheader></Vheader>
<router-view/>
</div>
</template>
这里对应的VuserList组件就是所有的用户信息,而VuserItem就是每一条的用户信息,假设现在父组件App.vue已经从数据库接收到了用户的数据,那么如何才能在VuserItem上进行渲染呢?这牵扯到父子组件的传值问题,可以利用props进行传值,但是这样一层一层的传递是相当麻烦的,此时可以使用vuex处理复杂传值的问题了。
二、vuex
1、安装vuex
E:\vueProject\vuexpj>npm install vuex --save
2、使用vuex
(1)导入模块
在main.js中导入模块
import Vuex from 'vuex'
(2)注册到全局
在main.js文件中进行注册
Vue.use(Vuex);
(3)创建store
const store = new Vuex.Store({
state: {
//这里面的状态跟每一个数据属性有关
UserList:[]
},
mutations: { }
});
(4)挂载到根实例上
new Vue({
el: '#app',
router,
store, //挂载到根实例中
components: { App },
template: '<App/>'
});
3、获取用户数据
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态。
- State
Vuex使用单一状态树,用一个对象就包含了全部的应用层级状态。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段。由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态。
当父组件App.vue页面所有的DOM元素加载完成,页面结构加载完成,就可以向后台API请求数据了,此时需要在App.vue组件中利用mounted方法(页面结构加载完成后执行)发送ajax请求数据:
mounted(){
var _this=this; #_this获取的是Vue实例
//当页面DOM元素即页面结构加载完成后执行此方法
$.ajax({
url:'http://127.0.0.1:8000/api/userdata/',
dataType:'JSON',
methods:'GET',
success:function (data) {
_this.$store.state.UserList=data; //Json数据自动解析为对象,并且将数据更新为state中的UserList
} }) }
#urls
urlpatterns = [
path('api/userdata/', views.getAllUser), ] #views
def getAllUser(request):
queryset=models.UserInfo.objects.values('username','password')
UserList=list(queryset)
print(UserList)
return HttpResponse(json.dumps(UserList,ensure_ascii=False))
后台获取数据API
此时store实例的状态中UserList就有数据了,store实例是每一个组件都可以使用其中的状态,现在将数据渲染在VuserList组件中:首先在VuserList组件的计算属性中从store实例中获取state状态的UserList
computed:{
getAllUserList(){
return this.$store.state.UserList
} }
然后,在VuserList组建的模板中进行渲染
<table class="table table-hover">
<tr class="active">
<td>用户名</td>
<td>密码</td>
</tr>
<VuserItem v-for="item in getAllUserList" :userinfo="item"></VuserItem>
</table>
这里可以看出来,循环每一条用户数据,然后自定义属性userinfo,并且将每一个用户数据传给其子组件VuserItem,在VuserItem中接收每一个用户数据,并且渲染:
<script>
export default {
name: "VuserItem",
data:function () {
return { }
},
//在VuserItem中验证数据类型,接收数据
props:{
userinfo:Object,
} }
</script> //渲染单条数据
<template>
<tr>
<td>{{userinfo.username}}</td>
<td>{{userinfo.password}}</td>
</tr>
</template>
4、添加用户数据
- Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
在VuserList组件中,增加添加按钮:
<button type="button" class="btn btn-info" @click="addOneUser">添加</button>
在VuserList组件中,增加addOneUser方法:
addOneUser() {
$('#addModal').modal('show')
},
点击之后弹出模态对话框,用于添加数据:
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">创建用户</h4>
</div>
<div class="modal-body">
<form id="fm" class="form-horizontal">
<div class="form-group">
<label for="username" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="username" placeholder="姓名" v-model="getUsername">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="password" placeholder="密码" v-model="getPassword">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<span id="errorMsg" style="color: red;"></span>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" @click="isSave">保存</button>
<el-button :plain="true" @click="open2"></el-button> <!--保存成功提示-->
<el-button :plain="true" @click="open4"></el-button> <!--保存失败提示-->
</div>
</div>
</div>
</div>
可以看到使用v-model获取值,相当于v-model给计算属性getUsername,getPassword赋值:
computed: { getAllUserList() {
return this.$store.state.UserList
}, getUsername: {
set(newValue) {
this.$store.state.UserObject.username = newValue//将获取的username 值保存在store实例的state状态中
},
get() {
return this.$store.state.UserObject.username //返回store实例的state状态中password
}
}, getPassword:{
set(newValue) {
this.$store.state.UserObject.password = newValue //将获取的password值保存在store实例的state状态中
},
get() {
return this.$store.state.UserObject.password //返回store实例的state状态中password
}
}
}
}
在main.js文件中新建的store实例中保存UserObject状态:
const store = new Vuex.Store({
state: {
//这里面的状态跟每一个数据属性有关
UserList: [], UserObject: {
username: '',
password: ''
},
},
保存UserObject状态
此时,在VuserList组件的方法中写入点击保存按钮向后台API提交数据了:
//发送数据
isSave(){
var _this = this; //获取Vue实例对象,Ajax中的this不是实例本身 var data={
//通过计算属性获取数据,实际也是从store实例的状态中拿到数据
username:this.getUsername,
password:this.getPassword,
// csrfmiddlewaretoken: '{{ csrf_token }}'
}; $.ajax({
url:'http://127.0.0.1:8000/api/addUser/',
method:'post',
dataType:'JSON',
contentType: 'application/json', //发送的数据类型为json,所以自己发送的数据必须保证为json
data:JSON.stringify(data), //发送json数据
success:function (data) {
console.log(data);
if(data.state){
_this.open2(); //执行保存成功提示函数
_this.getUsername=''; //添加成功后将input框置空
_this.getPassword=''
}else {
_this.open4(); //执行保存失败提示函数
}
_this.$store.state.UserList.push(data.user); //将添加成功的数据添加到状态,用于页面更新
} }); $('#addModal').modal('hide') //发送成功后模态对话框消失 }
open2(){
this.$message({
message: '恭喜你,创建用户成功!',
type: 'success'
});
},
保存成功提示函数
open4() {
this.$message.error('对不起,创建用户失败!');
},
保存失败提示函数
这样在后台接收数据进行处理接可以了:
#urls
urlpatterns = [
path('api/addUser/', views.addUser), ] #views
def addUser(request):
retDict={
'code':1000,
'state':False,
'msg':'存储失败'
}
userjson=request.body #json数据存储在request.body中
userdict=json.loads(str(userjson,encoding='utf8'))
obj=models.UserInfo.objects.create(username=userdict['username'],password=userdict['password'])
print(obj)
if obj:
retDict['code']=2000
retDict['state']=True
retDict['msg']='存储成功'
retDict['user']={'username':obj.username,'password':obj.password}
return HttpResponse(json.dumps(retDict,ensure_ascii=False))
后台API
截止到这里,我们还是没有使用mutition,但是也完成了对应的功能,但是,可以发现,我们在改变store实例的state状态时,是通过赋值或者其它手段:
_this.$store.state.UserList.push(data.user); //将添加成功的数据添加到状态,用于页面更新
官方文档上说更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,这里就需要做一些改变了,我们将所有与Ajax的操作交给Mutation来做,然后在需要的地方通过store.commit方法唤醒:
(1)获取数据使用mutation
//在App.vue中
//mounted方法页面加载完成后触发该方法
mounted(){ //在这个地方触发对应mutation方法,也就是getAllUser,通过ajax获取所有的数据
this.$store.commit('getAllUser'); } //在main.js文件中
mutations: { //在App.vue组件中来提交该方法触发,向后端获取数据
getAllUser(state){
//当页面DOM元素即页面结构加载完成后执行此方法
$.ajax({
url:'http://127.0.0.1:8000/api/userdata/',
dataType:'JSON',
methods:'GET',
success:function (data) {
state.UserList=data;
}
})
}
}
(2)添加数据使用mutation
//在VuserList.vue组件中
//发送数据
isSave(){ var data={
//通过计算属性获取数据,实际也是从store实例的状态中拿到数据
username:this.getUsername,
password:this.getPassword,
// csrfmiddlewaretoken: '{{ csrf_token }}'
}; //在这个地方触发对应mutation方法,也就是gaddUser,通过ajax提交所有的数据
this.$store.commit(
{
type: 'addUser',
data:data,
getUsername:this.getUsername,
getPassword:this.getPassword,
successfunc: this.open2,
failturefunc:this.open4,
}
); $('#addModal').modal('hide') //发送成功后模态对话框消失 } //在main.js文件中
mutations: { //在VuserList组件中提交该方法触发,向后端提交数据
addUser(state,payload){ $.ajax({
url:'http://127.0.0.1:8000/api/addUser/',
method:'post',
dataType:'JSON',
contentType: 'application/json', //发送的数据类型为json,所以自己发送的数据必须保证为json
data:JSON.stringify(payload.data), //发送json数据
success:function (data) {
console.log(data);
if(data.state){
payload.successfunc(); //执行保存成功提示函数
payload.getUsername=''; //添加成功后将input框置空
payload.getPassword=''
}else {
payload.failturefunc(); //执行保存失败提示函数
}
state.UserList.push(data.user); //将添加成功的数据添加到状态,用于页面更新
} }); }
}
虽然使用mutition了,但是mutation 必须是同步函数,那么如何使用异步操作呢?
- Action
Action 类似于 mutation,不同在于:
(1)Action 提交的是 mutation,而不是直接变更状态。
(2)Action 可以包含任意异步操作。
页面中需要做如下更改:
(1)获取数据
//1、在App.vue组件中分发action,这样触发action函数执行 mounted(){ //在这个地方触发对应mutation方法,也就是getAllUser,通过ajax获取所有的数据
// this.$store.commit('getAllUser'); //更改为: this.$store.dispatch('getAllUser') } //2、在main.js的action中 //用于执行异步函数操作,并且提交的是mutation
actions:{ //context与 store 实例具有相同方法和属性
getAllUser(context){
$.ajax({
url:'http://127.0.0.1:8000/api/userdata/',
dataType:'JSON',
methods:'GET',
success:function (data) { //保存返回的数据状态,mutation修改state状态,所以传给mutation处理
context.commit('GETALLUSER',data) //传递的是后台的数据
}
})
}, }); //3、在main.js的mutations中,因为action不能与state直接交互,它提交mutation
mutations: { //在action中提交的mutation方法
GETALLUSER(state,data){
state.UserList=data;
}, },
(2)添加数据
//1、在VuserList.vue组件中分发action,这样触发action函数执行 this.$store.dispatch(
{
type: 'addUser',
data:data,
getUsername:this.getUsername,
getPassword:this.getPassword,
successfunc: this.open2,
failturefunc:this.open4,
}
); //2、在main.js的action中 //用于执行异步函数操作,并且提交的是mutation
actions:{ addUser(context,payload){
$.ajax({
url:'http://127.0.0.1:8000/api/addUser/',
method:'post',
dataType:'JSON',
contentType: 'application/json', //发送的数据类型为json,所以自己发送的数据必须保证为json
data:JSON.stringify(payload.data), //发送json数据
success:function (data) {
if(data.state){
payload.successfunc(); //执行保存成功提示函数
payload.getUsername=''; //添加成功后将input框置空
payload.getPassword=''
}else {
payload.failturefunc(); //执行保存失败提示函数
}
//保存返回的数据状态,mutation修改state状态,所以传给mutation处理
context.commit('ADDUSER',data); //data是后台数据
} });
} }
//3、在main.js的mutations中,因为action不能与state直接交互,它提交mutation
mutations: { //在action中提交的mutation方法
ADDUSER(state,data){
state.UserList.push(data.user); //将添加成功的数据添加到状态,用于页面更新 } },
Vue对用户的增删改查完整操作,详见:https://www.cnblogs.com/shenjianping/p/11254442.html
vue生态系统之vuex的更多相关文章
- Vue状态管理vuex
前面的话 由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue提供了vuex.本文将详细介绍Vue状态管理vuex 引入 当访问数据对象时,一个 V ...
- Vue 入门之 Vuex 实战
Vue 入门之 Vuex 实战 引言 Vue 组件化做的确实非常彻底,它独有的 vue 单文件组件也是做的非常有特色.组件化的同时带来的是:组件之间的数据共享和通信的难题. 尤其 Vue 组件设计的就 ...
- Vue学习笔记:Vuex
为什么需要Vuex 管理共享状态 解决一份数据在多个组件中试用的困难 系统化的状态管理,区别于小型状态过来 底层设计模式: 全局单例模式 应用场景 适合中大型项目: 小项目反而会因为引入更多概念和框架 ...
- Vue学习日记(四)——Vue状态管理vuex
前言 先说句前话,如果不是接触大型项目,不需要有多个子页面,不使用vuex也是完全可以的. 说实在话,我在阅读vuex文档的时候,也很难以去理解vuex,甚至觉得没有使用它我也可以.但是直到我在项目碰 ...
- Vue刷新页面VueX中数据清空了,怎么重新获取?
Vue刷新页面VueX数据清空了,怎么重新获取? 点击打开视频讲解更详细 在vue中刷新页面后,vuex中的数据就没有了,这时我们要想使用就要重新获取数据了, 怎么在刷新后重新获取数据呢??? 这时我 ...
- vue+vux+axios+vuex+vue-router的项目的理解
本文主要是讲解项目前期的工作,后期考虑再详细说明. 作为一个技术团队如果你们团队选择了上面的技术栈,这说明你们的技术团体对于vue有很熟练的掌握了.在这里我想说明的是前期架构的重要.这里有一遍博客写的 ...
- 简单vue项目脚手架(vue+webpack2.0+vuex+vue-router)
github地址 使用技术栈 webpack(^2.6.1) webpack-dev-server(^2.4.5) vue(^2.3.3) vuex(^2.3.1) vue-router(^2.5.3 ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单
前言 哈喽大家周五好,马上又是一个周末了,下周就是中秋了,下下周就是国庆啦,这里先祝福大家一个比一个假日嗨皮啦~~转眼我们的专题已经写了第 23 篇了,好几次都坚持不下去想要中断,不过每当看到群里的交 ...
- vue学习之vuex
1 首先还是安装 npm install vuex --save. 2 在src这种创建目录为store 创建 index.js (getters.js ,actions.js ,mutation ...
随机推荐
- Javascript高级程序设计--读书笔记之面向对象(一)
哈哈哈万物皆对象,终于到了js的面向对象篇. 一.属性类型 (1)数据属性 数据属性包含一个数据值的位置,在这个位置可以写入和读取数值,数据属性有四个描述器行为的特性 [[Configurable]] ...
- 【记录】Nginx错误could not build the server_names_hash you should increase server_names_hash_bucket_size: 32
今天遇到这个错误,现记录下解决方案: 在nginx的配置文件的http段中增加如下配置: server_names_hash_bucket_size 64; 下面是nginx官方文档解释: 如果定义了 ...
- 你不知道的USB
USB的接口类型.定义和原理 目前USB接口类型已经更新到了USB3.1和USB Type-C类型,下面就对USB的类型进行介绍整理 一.UCB的通信协议类型 1.1 USB定义及类型 USB(Uni ...
- 使mysql数据库支持简体中文
永久支持简体中文[root@localhost ~]# vim /etc/my.cnf添加如下四行:[client]default-character-set=utf8 [mysql]default- ...
- 深入理解java虚拟机JVM(上)
深入理解java虚拟机JVM(上) 链接:https://pan.baidu.com/s/1c6pZjLeMQqc9t-OXvUM66w 提取码:uwak 复制这段内容后打开百度网盘手机App,操作更 ...
- php操作redis--字符串篇
前提:已经安装好了redis和相关拓展 常用函数:set/get/decr/incr等 应用场景:普遍的key/value存储类型 连接: $redis = new Redis(); $redis-& ...
- 问题 |无法找到Python路径,需手动配置环境变量
问题: 在命令行cmd输入Python,如果出现以下无法识别命令行的报错,说明在系统环境变量中无法找到对应之前安装的Python的路径,则需手动配置一下 怎么配置? 1.打开我的电脑——右键——属性— ...
- Delphi获取指定文件的版本号
获取指定文件的版本号 方式一: function GetFileVersion(FileName: string): string; type PVerInfo = ^TVS_FIXEDFILEINF ...
- SQL LIKE 运算符
SQL LIKE 运算符 在WHERE子句中使用LIKE运算符来搜索列中的指定模式. SQL LIKE 操作符 LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式. 有两个通配符与LIKE运 ...
- 每天一个Linux命令:pwd(3)
pwd pwd是Print Working Directory的缩写,其功能是显示当前所在工作目录的全路径.主要用在当不确定当前所在位置时,通过pwd来查看当前目录的绝对路径 格式 pwd [选项] ...