一、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">&times;</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的更多相关文章

  1. Vue状态管理vuex

    前面的话 由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue提供了vuex.本文将详细介绍Vue状态管理vuex 引入 当访问数据对象时,一个 V ...

  2. Vue 入门之 Vuex 实战

    Vue 入门之 Vuex 实战 引言 Vue 组件化做的确实非常彻底,它独有的 vue 单文件组件也是做的非常有特色.组件化的同时带来的是:组件之间的数据共享和通信的难题. 尤其 Vue 组件设计的就 ...

  3. Vue学习笔记:Vuex

    为什么需要Vuex 管理共享状态 解决一份数据在多个组件中试用的困难 系统化的状态管理,区别于小型状态过来 底层设计模式: 全局单例模式 应用场景 适合中大型项目: 小项目反而会因为引入更多概念和框架 ...

  4. Vue学习日记(四)——Vue状态管理vuex

    前言 先说句前话,如果不是接触大型项目,不需要有多个子页面,不使用vuex也是完全可以的. 说实在话,我在阅读vuex文档的时候,也很难以去理解vuex,甚至觉得没有使用它我也可以.但是直到我在项目碰 ...

  5. Vue刷新页面VueX中数据清空了,怎么重新获取?

    Vue刷新页面VueX数据清空了,怎么重新获取? 点击打开视频讲解更详细 在vue中刷新页面后,vuex中的数据就没有了,这时我们要想使用就要重新获取数据了, 怎么在刷新后重新获取数据呢??? 这时我 ...

  6. vue+vux+axios+vuex+vue-router的项目的理解

    本文主要是讲解项目前期的工作,后期考虑再详细说明. 作为一个技术团队如果你们团队选择了上面的技术栈,这说明你们的技术团体对于vue有很熟练的掌握了.在这里我想说明的是前期架构的重要.这里有一遍博客写的 ...

  7. 简单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 ...

  8. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单

    前言 哈喽大家周五好,马上又是一个周末了,下周就是中秋了,下下周就是国庆啦,这里先祝福大家一个比一个假日嗨皮啦~~转眼我们的专题已经写了第 23 篇了,好几次都坚持不下去想要中断,不过每当看到群里的交 ...

  9. vue学习之vuex

    1  首先还是安装 npm install vuex --save. 2 在src这种创建目录为store 创建 index.js  (getters.js ,actions.js ,mutation ...

随机推荐

  1. 回头看看HTML5

    前言:自从学习各种框架各种成熟的控件库,越来越觉得疲惫. 一.用语义元素构造网页 在html5中最常用到的页面结构相关的语义元素如下: 页面结构想相关的语义元素 元素 说明 <article&g ...

  2. display: flex属性介绍

    参考文章: 阮大神的:Flexbox 布局的最简单表单(主要讲解项目item上的属性) 另一位大神的:布局神器display:flex(整体讲解的非常详细) 之前没有仔细看flex布局(弹性布局),设 ...

  3. Html5介绍及新增标签

    什么是 HTML5? HTML5 将成为 HTML.XHTML 以及 HTML DOM 的新标准. HTML 的上一个版本诞生于 1999 年.自从那以后,Web 世界已经经历了巨变. HTML5 仍 ...

  4. 微信小程序生命周期、页面生命周期、组件生命周期

    1. 生命周期 App(全局) 位置:项目根目录app.js文件 App({ onLaunch (options) { // console.log('小程序初始化') }, onShow(optio ...

  5. Install ncurses (ncurses-devel) and try again

    apt install libncurses5-dev libncursesw5-dev

  6. nginx 和keepalived的使用

    今天看了培训视频,看到这俩玩意,挺有意思,先粘贴一下,别等到时候忘了. 官方网站 www.nginx.org nginx的特点 稳定版本是用偶数来做标记,测试版本使用奇数作为标记 通过yum来安装 安 ...

  7. Codeforces 1182D Complete Mirror 树的重心乱搞 / 树的直径 / 拓扑排序

    题意:给你一颗树,问这颗树是否存在一个根,使得对于任意两点,如果它们到根的距离相同,那么它们的度必须相等. 思路1:树的重心乱搞 根据样例发现,树的重心可能是答案,所以我们可以先判断一下树的重心可不可 ...

  8. Eclipse maven 明明有jar包 但是不能用

    原因1:没有引入pom.xml依赖 解决: 添加pom.xml依赖

  9. jsp引擎是什么

    1.JSP引擎 执行JSP代码需要在服务器上安装JSP引擎,比较常见的引擎有webLogic和Tomcat.把这些支持JSP的web服务器配置好后,就可以在客户端通过浏览器来访问JSP页面了. 2.J ...

  10. Anaconda配置

    0x00 下载 为了更快的下载,可以到清华开源软件镜像站下载 地址:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 在此以Anaconda ...