Vuex使用详解,附加项目遇到的问题(简单明了)

 

Vuex的定义、个人理解和结构解析

 

vuex定义:vuex是一个专门为vue.js设计的集中式状态管理架构。

vuex的个人理解:

是存储公有状态数据state的一个仓库(store);解决了大型应用时组件传参的繁杂和不易维护性;vuex的状态储存是响应的,store中状态发生改变后相应组件会得到更新;不能直接修改store中的状态,唯一途径是显示的提交(commit)mutation, 可以通过getter获取state的派生值;

 

Vuex结构组成:

Store(仓库):

State(状态):负责存储应用的状态数据,可以理解为数据容器;组件中获取vuex中的数据时使用this.$store.state.stateName来获取;

Mutations(变化):利用它来更改状态state数据,本质是处理数据的函数,其接收唯一参数值state。我们可以在methods方法中使用this.$store.commit(‘mutationName’);来触发一个mutation的方法;必须是同步函数,否则devtool中的数据将会出现问题;

Actions:通过触发mutation来修改state状态,重要的是可以异步改变state状态,在methods方法中使用this.$store.dispatch(actionName);直接触发

Getters:有些状态需要进行二次处理就可以使用getters,可以在方法中使用this.$store.getters.valueName对派生出来的状态数据进行访问;当依赖发生改变时会改变

 

mapActions、mapMutations、mapGetters、mapState:是利用辅助函数将actions、mutations、getters、state映射到本地计算属性或methods方法中去;使用前需引入映射如:    import {mapGetters} from ‘vuex’

 

vuex的demo实践:

第一步:创建项目

    基于vue-cli脚手架生成一个vue项目;

    常用命令:

        npm i vue-cli --g                     来安装vue-cli

         vue --vesion  或  vue -V        来检查vue安装是否成功

         vue init webpack 项目名       来创建vue-cli 脚手架项目

 

注意:运行 npm i vue-cli --g 安装vue-cli“ WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen) ” 错误时可以尝试 使用   cnpm i vue-cli --g  安装

 

第二步:检查项目是否创建成功,安装vuex

          npm run dev                        来运行vue项目

          npm i vuex --save               来安装vuex

 

第三步:代码实现父子组件通过vuex传递参数Demo

效果:

 

1、项目文件结构如下: 创建父子组件文件和store.js文件

 

2、Store.js文件引用vuex如下:

import Vue from 'vue';
import Vuex from 'vuex';//vue引用vuex
Vue.use(Vuex);//state状态数据容器
const state={testMsg:"state中的一行测试文本",parentMsg:"父组件原始文本",childMsg:"子组件原始文本",count:99,
}//修改satate的方法,就是state状态数据的处理函数
const mutations= {changeParentMsg:function(state,str){state.parentMsg=str;},changeChildMsg:function(state,str){state.childMsg=str;},
}//异步,通过commit触发mutations中的方法来修改state
const actions={changeParentTxt({commit},data){commit('changeParentMsg',data);},changeChildTxt:function(context,data){context.commit('changeChildMsg',data);},//上述两个方法中的参数使用{commit}和context均有效,context代表store本身
}//对获取到的state数据进行过滤修改
const getters={countNum:function(state){if(state.count>100){return state.count+100;}else {return state.count-50;}}
}//创建store实例,将在main.js文件中将它加入到vue实例对象中
export default new Vuex.Store({   //export default 是封装代码,使外部可用state,  //依此加入到store对象中mutations,actions,getters,
});

3、Main.js文件在vue实例中引用store对象:

将store实例从根组件中‘注入’到子组件中,子组件通过‘this.$store’调用

 

4、组件文件:

     HelloWorld.vue

<template><div class="hello"><h3>测试文本如下:</h3><p>在组件模板中直接输出获取值:{{$store.state.testMsg}}</p><hr><Parent></Parent><hr><h4>getters获取state的值修改后如下:</h4><p>{{$store.getters.countNum}}</p></div>
</template><script>
import Parent from './Parent'
export default {name: 'HelloWorld',data () {return {msg: 'Welcome to Your Vue.js App'}},components:{Parent},
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {font-weight: normal;
}
ul {list-style-type: none;padding: 0;
}
li {display: inline-block;margin: 0 10px;
}
a {color: #42b983;
}</style>

     Parent.vue

<template><div><div class="parentContainer"><div><h3>父组件的内容:</h3><p class="txt">{{oldtxt}}</p></div><button class="btn" @click="changeParentTxt()">点击更改父组件内容</button><button class="btn" @click="changeChildTxt()">点击更改子组件内容</button></div><Child></Child></div>
</template>
<style>.parentContainer {height:150px;width:350px;background-color: lightblue;color:#fff;margin:10px auto;}.txt {border:1px solid red;padding:10px;}.btn {background-color: #fff;color: #000;}
</style>
<script>import Child from './Child'export default {name:"Parent",data(){return {}},components:{Child,},computed:{oldtxt:function(){return this.$store.state.parentMsg;}},methods:{changeParentTxt:function(){let newParentTxt="更改后的父组件内容变长的很多!!!";this.$store.dispatch('changeParentTxt',newParentTxt);},changeChildTxt:function(){let newChildTxt="这里是父组件点击修改后的文本内容....";this.$store.dispatch('changeChildTxt',newChildTxt);},},}
</script>

 

     Child.vue

<template><div class="childContainer"><div><h3>子组件的内容:</h3><p class="txt">{{oldtxt}}</p></div><button class="btn" @click="changeChildTxt2()">点击更改子组件内容</button><button class="btn" @click="changeParentTxt2()">点击更改父组件内容</button></div>
</template>
<style>.childContainer {height:150px;width:350px;background-color: lightcoral;color:#fff;margin:10px auto;}.txt {border:1px solid red;padding:10px;}.btn {background-color: #fff;color: #000;}
</style>
<script>export default {name:"Child",data(){return {}},computed:{oldtxt:function(){return this.$store.state.childMsg;}},methods:{changeParentTxt2:function(){let newParentTxt="我这是通过子组件修改父组件state后获取到的文字!!!";this.$store.dispatch('changeParentTxt',newParentTxt);},changeChildTxt2:function(){let newChildTxt="点击子组件按钮后内容变成了这样!!!";this.$store.dispatch('changeChildTxt',newChildTxt);},},}
</script>

 

Vuex在项目中代码使用详解

1、组件模板获取state状态数据:将状态对象赋值给内部对象,也就是将stroe.js中的值赋值给模板中的data中的值,有三种赋值方式:

      ①使用computed计算属性直接赋值;

      ②使用mapState辅助函数来赋值(将state值映射到局部计算属性);

      ③使用mapState的数组来赋值;

    <div>computed计算属性获取的值:{{count01}}</div><div>使用mapState辅助函数来赋值:{{count02}} </div><div>使用mapState的数组来赋值:{{count}} </div>
  computed:{ //多个computed时,后面的会覆盖前面的count01(){  //普通计算属性return this.$store.state.count;},...mapState({  //mapState(obj)对象辅助函数赋值count02:(state)=>{return state.count}  //ES6的箭头函数}),...mapState(['count'])  //mapState(arr)数组来赋值}

 

2、getters获取的是经过加工过滤后的state状态数据。

//store.js中getters定义
//对获取到的state数据进行过滤修改
const getters={changeCount:function(state){if(state.count>100){return state.count*2;}else {return state.count-1;}}
}const mutations= {addCount:function(state,num){return state.count+=num;},
}
// 组件模板中使用mapGetters
<template><div class="childContainer"><h3>原值:{{count}}</h3><h3>getter加工过滤后的值:{{changeCount}}</h3><button @click="$store.commit('addCount',20)">点击数字加20</button></div>
</template>
<script>
import {mapState,mapMutations, mapGetters} from 'vuex'export default {name:"Child",data(){return {}},computed:{...mapState(['count']),...mapGetters(['changeCount']),},methods:{...mapMutations(['reduceCount']),},}
</script>

同理在组件模板可以通过this.$store.getters.changeCount来获取store中过滤更改后的count值;

mapGetters辅助函数和mapState辅助函数类似是将store中的getter 映射到局部计算属性computed中,mapGetters使用前先import引入;

 

3、组件模板更改store中的state值通过mutations中的方法:mutations同步更改状态($store.commit('mutationName'))的方式:

     ①使用this.$store.commit('mutationName');

//store.js
//mutations中更改satate的方法,就是state状态数据的处理函数
const mutations= {addCount:function(state,num){return state.count+=num;},reduceCount:function(state,num){return state.count-=num;},
}
 <button class="btn" @click="$store.commit('addCount',50)">点击使用commit直接触发mutations中的方法</button>

   

②使用mapMutations辅助函数将mutations中的方法映射到methods中; 

a、组件中首先需要使用import 引入mapMutations和mapState(依赖性),如

import {mapState,mapMutations} from 'vuex'

b、将mutations中的方法映射到methods中; 

methods:{...mapMutations(['reduceCount']),
},

c、组件模板中直接使用映射的方法如:

<button class="btn" @click="reduceCount(20)">通过mapMutations触发mutations中的方法</button>

 

4、actions异步更改状态state,actions方法通过mutations中方法来更改state,actions中的方法有两种写法如下:

//异步,通过commit触发mutations中的方法来修改state
const actions={changeParentTxt({commit},data){commit('changeParentMsg',data);},changeChildTxt:function(context,data){context.commit('changeChildMsg',data);},//上述两个方法中的参数使用{commit}和context均有效,context代表store本身
}

mapActions的使用类似mapMutations将方法映射到methods中,组件模板使用前先 import 引用mapActions、mapMutations、mapState;

methods:{changeCountNum:function(){this.$store.dispatch("countNum_action",99);  //$store.dispatch("actionName");直接触发actions中的方法},
},

 

5、module模块组:为解决state状态对象过多而杂的问题,我们将一个store划分为多个module模块,每个模块拥有自己的state、mutations、actions、getters使用如下

①store.js中是声明modules

//声明模块组module
const moduleA={state:{name:'zhangsan',age:27},mutations:{},actions:{},getters:{}
};const moduleB={state:{name:'wangwu',age:26},mutations:{},actions:{},getters:{}
};export default new Vuex.Store({modules:{a:moduleA,b:moduleB}  //使用a做为moduleA的别名,b同理
});

②模板组件中获取指定module中的state数据有以下两种方式

<div>模块A的name值是:{{$store.state.b.name}}</div>
computed:{moduleAname:function(){return this.$store.state.a.name;}
},

 

PS附加:

1、如果store文件太大,也可以将 action、mutation 和 getter 分割到单独的文件。分割的文件需要export  default 导出,并在store.js文件中的import 导入,如下

//mymutations.js 文件
const mutations= {changeParentMsg:function(state,str){state.parentMsg=str;},changeChildMsg:function(state,str){state.childMsg=str;},
}
export default mutations
import state from './mystate'
import mutations from './mymutation'
import actions from './myactions'export default new Vuex.Store({state,  mutations,actions,getters,
});

2、在vue 的构造器里边只能有一个computed属性,如果你写多个,只有最后一个computed属性可用;

 

3、vuex数据在页面刷新时数据会丢失问题,解决思路是vuex更改state数据时同时存储到sessionStorage,当getters获取state数据时判断state为空时对应sessionStorage是否存在,为true则获取sessionStorage赋值给丢失了数据的stateName,如下:

//store.js中定义getters获取时为空会判断从sessionStorage获取值或初始值
const getters={countNum:function(state){if(!state.count){state.count=10; //首次num数值为空初始值赋值为10let sessionVal=sessionStorage.getItem("count_num");if(sessionVal){state.count=parseInt(sessionVal);}}return state.count}
}//store.js中定义mutations更改state后存储到sessionStorage
const mutations= {change_numCount:function(state,data){state.count=data;sessionStorage.setItem('count_num',data);},
}
//组件模板中触发更改state状态数据的action方法
methods:{changeCountNum:function(){  this.$store.dispatch("countNum_action",99);},
},

 

参考网址:https://blog.csdn.net/H5_QueenStyle12/article/details/75386359

https://blog.csdn.net/mjzhang1993/article/details/78321903

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/554065.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Chorme控制台console的用法;

前提&#xff1a;是谷歌浏览器&#xff01; IE8- 不支持console.log();会报错&#xff0c;解决如下&#xff1a; (function (){//创建空console对象&#xff0c;避免JS报错 if(!window.console) window.console {}; var console window.console; //添加console对象的方…

搜狗浏览器如何下载安装 安装搜狗浏览器的详细步骤

搜狗浏览器如何下载安装?搜狗浏览器是一款很不错的网页浏览软件&#xff0c;但是大家知道如何下载安装搜狗浏览器吗?不会的小伙伴就请跟着小编一起来看看安装搜狗浏览器的操作步骤吧。 方法/步骤 1、我们寻找搜狗浏览器官方版本&#xff0c;点击搜寻。 2、可以选择软件库下…

null、undefined、NaN区分解析和条件判定,以及在IF条件中的判定

NaN的理解和用法&#xff1a; NaN 属性是代表非数字值的特殊值。该属性用于指示某个值不是数字。可以把 Number 对象设置为该值&#xff0c;来指示其不是数字值。 Number.NaN 是一个特殊值&#xff0c;说明某些算术运算&#xff08;如求负数的平方根&#xff09;的结果不是数…

360浏览器鼠标手势怎么关 取消360浏览器鼠标手势的方法

360浏览器鼠标手势怎么关?鼠标手势&#xff0c;也就是右键滑动动作&#xff0c;对于不习惯使用该功能的用户而言&#xff0c;是一项体验很差的功能&#xff0c;如果你也想要关闭该功能&#xff0c;可以参考下文中的方法进行处理&#xff0c;想要再次开启也可以这样操作。 1、…

vue数组修改不触发视图更新、vue向响应式对象添加或删除属性

背景&#xff1a;在vue开发中会遇到data数据更改后view试图不会进行响应式更新的情况 以下4种情况不触发vue响应式更新&#xff01;&#xff01; 不能检测到的数组变动是&#xff1a; 1、当利用索引直接设置一个项时&#xff0c;例如&#xff1a;vm.items[indexOfItem] newVal…

360浏览器怎样清除缓存

360浏览器怎样清除缓存?很多用户反应360浏览器跳转页面的速度越来越慢&#xff0c;其实这时候有可能是因为缓存太多&#xff0c;下面&#xff0c;小编就为大家介绍下360浏览器清除缓存方法。 1、点击浏览器右上角的“工具”菜单。 2、点击“清除上网痕迹”。 3、在清除上网…

vue.nextTick()方法的使用详解(简单明了)

什么是Vue.nextTick()&#xff1f;&#xff1f; 定义&#xff1a;在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法&#xff0c;获取更新后的 DOM。 所以就衍生出了这个获取更新后的DOM的Vue方法。所以放在Vue.nextTick()回调函数中的执行的应该是会…

猎豹浏览器网页声音怎么关闭 2步关闭网页声音

作为一款主打安全与极速特性的浏览器产品&#xff0c;猎豹浏览器在国内也有不少忠实的粉丝。不过&#xff0c;想要熟练的使用猎豹浏览器中的各种功能&#xff0c;其实并不容易!下面小编就来介绍一下猎豹浏览器关闭网页声音的方法&#xff0c;小伙伴们可不要错过了。 方法步骤 …

vue项目中全局引用jquery 、引用外部js的多种方式(外部纯函数js、外部自执行js、外部js插件),附niceScroll滚动条插件使用

vue项目中全局引用jquery &#xff1a; 1、“ npm install jquery --save ” 命令安装jquery 2、在项目根目录下的 build 目录下找到webpack.base.conf.js 文件&#xff0c;在开头使用以下代码引入webpack&#xff0c;如下 var webpack require(webpack) 3、在webpac…

隐藏浏览器滚动条但内容可以滚动的3种解决方式(简单清晰)

第一种&#xff1a;使用纯css样式属性隐藏滚动条 &#xff1a;火狐浏览器的css写法不兼容 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, i…

QQ浏览器登陆微信的方法

微信是腾讯旗下第二款即时通讯软件&#xff0c;简单明了的功能界面&#xff0c;简洁的聊天窗口收获了大量的用户&#xff0c;而且强大的在线支付功能与支付宝一同为现代中国的网络发展提供了巨大的推力。微信不同于QQ可以直接使用电脑客户端登陆&#xff0c;在早期更是只有手机…

vue生命周期详解、钩子函数的调用(简单易懂)

定义&#xff1a;vue的生命周期是指vue实例从初始化创建到实例销毁的过程。期间会有8个钩子函数的调用。 vue的钩子函数图解&#xff1a; vue的钩子函数使用总结&#xff1a; 1、beforeCreate&#xff08;创建前&#xff09;:beforeCreate钩子函数&#xff0c;这个时候&#x…

QQ浏览器如何查看网站保存的密码

小编日常使用的浏览器大多是QQ浏览器&#xff0c;基于腾讯QQ下的账号同步功能给我带来了许多方便&#xff0c;其中QQ浏览器的账号密码自动保存&#xff0c;同时通过云同步可以在各个终端同步账号密码&#xff0c;所以使用QQ浏览器对常用网络浏览时可以一键免密登录&#xff0c;…

vue-router详尽:编程式导航、路由重定向、动态路由匹配、路由别名、嵌套路由、命名视图

vue-router编程式导航 在vue项目中经常用到this.$router.push() 和 this.$router.replace() 方法进行路由跳转就是编程式导航。。。 通俗理解编程式导航&#xff1a;通过操作$router实例的JavaScript代码实现路由跳转。点击 <router-link :to"..."> 等同于调用…

win10 edge默认浏览器设置更改教程

win10 edge默认浏览器设置更改教程 win10 edge默认浏览器怎么设置?在Win10中&#xff0c;默认浏览器修改已经不再像以前Win7/Win8.1那样容易&#xff0c;已经不能直接通过第三方浏览器设置直接修改&#xff0c;要用到新的“招数”&#xff0c;用户需在“设置”中手动修改。如…

ie浏览器ip代理怎么设置

核心提示&#xff1a;经常上网的朋友经常会遇到想使用代理IP上网的情况&#xff0c;但是又苦恼不知道怎么设置&#xff0c;小编这就告诉大家怎么在IE浏览器上设置代理IP上网。 ie浏览器ip代理怎么设置&#xff1f;经常上网的朋友经常会遇到想使用代理IP上网的情况&#xff0c;…

理解JavaScript中this的指向详解

this的定义和理解&#xff1a; this是JavaScript语言的一个关键字&#xff0c;它是函数运行时&#xff0c;在函数体内部自动生成的一个对象&#xff0c;只能在函数体内使用。 1、this和执行环境对象有关&#xff0c;和函数的声明无关。 var name"Tom";var Bob{name:…

如何设置PP视频允许PPAP驻留

今天继续给大家分享PP视频方面的内容。   如何设置PP视频允许PPAP驻留&#xff0c;将让下次启动时更加快速&#xff0c;下面让我们一起看看&#xff0c;是如何设置的吧 1、点击“PP视频” 2、在“PP视频”播放窗口中&#xff0c;点击“菜单”按钮 3、在弹出下拉栏中&#…

深入理解call、apply、bind(改变函数中的this指向)

在JavaScript中call、apply、bind是Function 对象自带的三个方法&#xff0c;这三个方法的主要作用是改变函数中的 this 指向&#xff0c;从而可以达到接花移木的效果。本文将对这三个方法进行详细的讲解&#xff0c;并列出几个经典应用场景。 区分&#xff1a; 1、call(objec…

360浏览器设置多标签操作步骤

360浏览器设置多标签操作步骤 360浏览器怎么设置多标签?昨天小编写了一篇如何使用ie7浏览器设置多个主页的文章&#xff0c;就有小伙伴留言给小编360浏览器能否实现这项功能?当然有!下面小编就介绍操作方法&#xff1a; 1、打开360浏览器&#xff0c;在左上角找到“工具”点…