🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的专栏《ELement》。🎯🎯
👉点击这里,就可以查看我的主页啦!👇👇
🎁如果感觉还不错的话请给我点赞吧!🎁🎁
💖期待你的加入,一起学习,一起进步!💖💖
目录
1、在store文件夹,新建个index.js文件(命名看个人习惯,如果没有该文件夹,可以新建一个,当然也可以不建文件夹,直接新建个js文件也是可以的)
3、保存数据:(场景举例:当我点击按钮后,我需要把当前的数据保存到vuex中,然后跳转到别的路由,然后使用这些数据)
4、获取变量:(当数据初始获取不到时,可以使用计算属性用来获取)
2、mutations.js :保存所有方法,用来改变state的数据
3、actions.js :暴露给用户使用,借此触发mutations中的方法,保存数据(可执行异步操作)
4、index.js:引入相应模块,暴露出store,供vue注册后全局使用
vuex是使用vue中必不可少的一部分,基于父子、兄弟组件,我们传值可能会很方便,但是如果是没有关联的组件之间要使用同一组数据,就显得很无能为力,那么vuex就很好的解决了我们这种问题,它相当于一个公共仓库,保存着所有组件都能共用的数据。
那么,我们一起来看看vue项目怎么使用它吧。(如果你对vuex有一定了解,不是刚接触的小白,请忽略第一步,直接查看第二步)
在新建的js文件中写入如下代码:
- import Vue from "vue"
- import Vuex from "vuex"
-
- Vue.use(Vuex);
-
- export default new Vuex.Store({
- state:{
- pathName: "",
- currDbSource: {},
- currJobData: {},
- DbSource: []
- },
- mutations:{
- // 保存当前菜单栏的路径
- savePath(state,pathName){
- state.pathName = pathName;
- },
- // 保存当前点击的数据源
- saveCurrDbSource(state,currDbSource){
- state.currDbSource = currDbSource;
- },
- // 保存当前点击的元数据
- saveCurrJobData(state,currJobData){
- state.currJobData = currJobData;
- },
- // 保存所有数据源
- saveDbSource(state,DbSource){
- state.DbSource = DbSource;
- }
- }
- })
这里解释一下各个代码段的作用:state是自定义的一些变量,需要用来保存数据,mutations是用来触发事件,相当于方法,用户需要通过触发这个方法,借此来保存数据,参数的话,第二个参数就是用户传入的值,然后在方法中赋值给state中的变量
- // 引入vuex-store
- import store from './store/index';
-
- new Vue({
- el: '#app',
- router,
- store,
- render: h => h(App)
- });
- methods:{
- click(){
- // 点击按钮进行一些操作,然后保存数据
- this.$store.commit('saveCurrDbSource',this.db)
- }
- }
这里的第一个参数是要触发的方法,也就是上面mutations中的方法,第二个参数是你要传递的数据
- this.$store.state.变量名
-
- // 例如
- this.$store.state.currDbSource
这样其他组件就可以共用这个保存起来的数据了,也能进行相应的修改
当然,上述方法中我们把所有东西都写在一个文件中了,这样数据多的时候,耦合度太高,也不便于维护,而且mutations也不能解决异步问题,这里就介绍另一种方式以及actions
actions:看过官网介绍的人都知道,这是间接触发mutations方法的一种 " 中间商 ",而且它可以执行异步操作,避免用户去直接操作state
- export default {
- pathName: '', // 路由
- currDbSource: {}, // 当前数据源
- currJobData: {}, // 当前元数据
- DbSource: [], // 所有数据源,供元数据界面下拉列表使用
- selectJobMeta: {}, // 当前选择的元数据(搜索后点击的单条数据)
- specialSubject: [], // 专题数据(多条)
- duplicateJobMeta: {}, // 复制的数据
- };
- // 保存当前菜单栏的路径
- export const savePath = (state, pathName) => {
- state.pathName = pathName;
- };
-
- // 保存当前点击的数据源
- export const saveCurrDbSource = (state, currDbSource) => {
- state.currDbSource = currDbSource;
- };
-
- // 保存当前点击的元数据
- export const saveCurrJobData = (state, currJobData) => {
- state.currJobData = null;
- state.currJobData = currJobData;
- };
-
- // 保存所有数据源
- export const saveDbSource = (state, DbSource) => {
- state.DbSource = DbSource;
- };
-
- // 保存搜索后选择的那一条元数据
- export const saveSelectJobMeta = (state, selectJobMeta) => {
- state.selectJobMeta = selectJobMeta;
- };
-
- // 保存搜索的那一类专题
- export const saveSpecialSubject = (state, specialSubject) => {
- state.specialSubject = specialSubject;
- state.selectJobMeta = {};
- };
-
- // 保存复制的元数据(名称为空)
- export const saveDuplicateJobMeta = (state, duplicateJobMeta) => {
- state.duplicateJobMeta = duplicateJobMeta;
- };
- // 触发保存菜单栏的路径方法
- export const savePath = ({ commit }, payload) => {
- commit('savePath', payload);
- };
-
- // 触发获取当前点击的数据源方法
- export const saveCurrDbSource = ({ commit }, payload) => {
- commit('saveCurrDbSource', payload);
- };
-
- // 触发获取当前点击的元数据方法
- export const saveCurrJobData = ({ commit }, payload) => {
- commit('saveCurrJobData', payload);
- };
-
- // 触发获取所有数据源方法
- export const saveDbSource = ({ commit }, payload) => {
- commit('saveDbSource', payload);
- };
-
- // 触发保存搜索后选择单条元数据方法
- export const saveSelectJobMeta = ({ commit }, payload) => {
- commit('saveSelectJobMeta', payload);
- };
-
- // 触发保存搜索专题数据方法
- export const saveSpecialSubject = ({ commit }, payload) => {
- commit('saveSpecialSubject', payload);
- };
-
- // 触发保存复制元数据方法
- export const saveDuplicateJobMeta = ({ commit }, payload) => {
- commit('saveDuplicateJobMeta', payload);
- };
这里有2种方式:
- // 方法一:
- export const saveDbSource = (context, payload) => {
- context.commit('saveDbSource', payload);
- };
-
- // 方法二:
- export const saveDbSource = ({ commit }, payload) => {
- commit('saveDbSource', payload);
- };
第一种是通过 context上下文用来触发事件,一种是直接通过commit,为了保存数据,都需要加第二个参数payload,不然保存到vuex的数据就是空值
- import Vue from 'vue';
- import Vuex from 'vuex';
- import state from './state';
- import * as actions from './actions';
- import * as mutations from './mutations';
-
- Vue.use(Vuex);
-
- export default new Vuex.Store({
- state,
- actions,
- mutations
- });
- // 引入vuex-store
- import store from './store/index';
-
- new Vue({
- el: '#app',
- router,
- store,
- render: h => h(App)
- });
- import { mapActions } from 'vuex';
-
- // 2种方式
-
- // 方法一(dispatch)
- this.$store.dispatch('saveDbSource', this.DbSource);
-
- // 方法二(映射)
- // 1、通过methods方法添加映射关系
- methods: {
- ...mapActions(['saveDbSource'])
- }
- // 2、使用
- this.saveDbSource
这里也有2种保存数据的方法,第一种就是直接操作方法,通过disptach派发给actions,让actions去触发
第二种就是通过在methods中添加映射关系,数组方式,意味着我们可以在数组中写多个方法(这里数组中的每一个方法名是actions.js文件中所定义的方法名),然后在需要使用的地方直接this.方法名即可。当然,也可以直接绑定给html中的某个事件。
值的注意的是,避免和methods中自己定义的其他方法的名字冲突
- import { mapState } from 'vuex';
-
- computed: {
- ...mapState(['DbSource']),
- // 推荐写法如下:
- //...mapState({
- // DbSource: state => state.DbSource,
- // phoneMap: state => state.richCommunicationSuite.phoneMap, // 模块化写法
- //}),
- },
- watch: {
- DbSource(currVal) {
- // 监听mapState中的变量,当数据变化(有值、值改变等),
- // 保证能拿到完整的数据,不至于存在初始化没有数据的问题,然后可以赋给本组件data中的变量
- this.currVal = currVal;
- }
- }
通过计算属性,当数据发生改变,我们可以保证拿到的是响应过后的数据,也是数组形式,意味着我们可以拿到多组数据,这里数组中的数据也是state.js中定义的变量(当然,更推荐使用我注释的那段代码,那种写法可以应对当state中存在多模块的情况,比如state.a.xxx,state.b.xxx,其中a和b都是两个模块,各自有对应的数据要存储,也可以自定义我们前面的名字来避免和data中数据重名的情况)
使用的时候,可以直接通过this.变量名拿到,例如本例中的 this.DbSource,我们可以把它赋给我们自定义的变量,也可以直接使用
值的注意的是,避免和data中自己定义的其他变量的名字冲突
至此,我们就完成了vuex的保存以及获取数据,希望对你有所帮助。
当然,我们需要把一vuex中的一组数据过滤,其他组件都共用过滤后的数据,这种情况大家可能会用到getters,这里我就不多赘述了,有兴趣的小伙伴可以自己了解一下。
附上vuex的运行过程,官网的图片:组件派发任务到actions,actions触发mutations中的方法,然后mutations来改变state中的数据,数据变更后响应推送给组件,组件重新渲染
npm install vuex -S
npm i -S vuex@3.6.2
store
index.js
state.js
actions.js
mutations.js
getters.js
- import Vue from 'vue'
- import Vuex from 'vuex'
- import state from './state'
- import getters from './getters'
- import actions from './actions'
- import mutations from './mutations'
- Vue.use(Vuex)
- const store = new Vuex.Store({
- state,
- getters,
- actions,
- mutations
- })
-
- export default store
并在main.js中导入并使用store实例
state.js:保存对象
- export default {
- Name: '哈佛大学'
- };
mutations.js:改变state
- export default {
- setName:(state,payload) => {
- state.Name = payload.Name;
- }
- };
getters.js:获取state
- export default {
- getName:(state) => {
- return state.Name
- }
- };
vue组件效果展示
- <div>
- <h1>我是页面一h1>
- 学校:<input v-model="msg"/>
-
- <button @click="fun1">获取vuex的值button>
- <button @click="fun2">改变vuex的值button>
- div>
-
- <script>
- export default {
- data() {
- return {
- msg: '北京大学'
- }
- },
- methods: {
- fun1(){
- let name= this.$store.state.Name
- alert(name)
- },
- fun2(){
- this.$store.commit('setName',{
- Name:this.msg
- })
- }
- }
- }
- script>
-
- <style>
- style>
扩展:在别的页面上同样可以获取到state的值
- <div>
- <h1>我是页面二h1>
- {{name}}
- div>
-
- <script>
- export default {
- computed:{
- name(){
- return this.$store.state.Name
- }
- }
- }
- script>
-
- <style>
- style>
actions.js:异步改变state的值
- export default {
- setNameSync:(context,payload) => {
- //context指的是vuex的上下文
- setTimeout(function(){
- context.commit('setName',payload)
- },5000)
- }
- };
在刚刚的Vue组件中新增一个按钮和点击事件
-
-
- fun3() {
- this.$store.dispatch('setNameSync', {
- Name: this.msg
- })
- }
效果演示:
这个我们有两个注意的点:
1.发送ajax的vue实例在vuex中不生效;
2.异步相应时间超时内容不会显示;
其实很好解决我们只需将vue实例在调用方法的时候就通过参数传递过来,在vuex接收即可使用,然后超时的问题我们设置好我们的响应时间即可。
后端代码
- package com.zking.ssm.controller;
-
- import com.zking.ssm.util.JsonResponseBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import javax.servlet.http.HttpServletRequest;
- import java.text.SimpleDateFormat;
- import java.util.Date;
-
- @RestController
- @RequestMapping("/vuex")
- public class VuexController {
-
- @RequestMapping("/queryVuex")
- public JsonResponseBody> queryVuex(HttpServletRequest request) {
- String resturantName = request.getParameter("resturantName");
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- String date = sdf.format(new Date());
- try {
- System.out.println("模拟异步情况,睡眠6秒,不能超过10秒,axios超时时间设置的是10秒!");
- Thread.sleep(6000);
- System.out.println("睡醒了,继续...");
- } catch (Exception e) {
- e.printStackTrace();
- }
- return new JsonResponseBody<>(resturantName + "-" + date,true,0,null);
- }
- }
在api文件夹下的action.js设置后台请求的地址的封装(URL)
'VUEX': '/vuex/queryVuex', //Vue后端异步获取
actions.js:异步发送ajax到后端
- setNameAjax: (context, payload) => {
- let _this=payload._this
- let url = _this.axios.urls.VUEX
- let params = {
- resturantName: payload.Name
- }
- _this.axios.post(url, params).then(r => {
- console.log(r)
-
- }).catch(r => {
-
- });
- }
继续在刚刚的Vue组件中新增一个按钮和点击事件
-
-
- fun4() {
- this.$store.dispatch('setNameAjax', {
- Name: this.msg,
- _this:this
- })
- }
效果演示:
到这里我的分享就结束了,欢迎到评论区探讨交流!!
💖如果觉得有用的话还请点个赞吧 💖