Nuxt使用Vuex解读

 更新时间:2023年10月11日 10:06:11   作者:靳哲  
这篇文章主要介绍了Nuxt使用Vuex的方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Nuxt使用vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

基础知识这里不再重述,学习的话请自行到官网学习https://vuex.vuejs.org/zh/

文档最后有具体使用的实例,不想看基础的就直接下调页面~

这里主要简单讲一讲Nuxt里怎么使用vuex,

Nuxt.js 内置引用了vuex模块,所以不需要额外安装。

Nuxt.js 会尝试找到应用根目录下的store目录,如果该目录存在,它将做以下的事情:

  • 引用 vuex 模块
  • 将 vuex 模块 加到 vendors 构建配置中去
  • 设置 Vue 根实例的 store 配置项

Nuxt.js 支持两种使用store的方式,你可以择一使用:

  • 普通方式: store/index.js 返回一个 Vuex.Store 实例
  • 模块方式: store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块 (当然,index 是根模块)

普通方式

使用普通方式的状态树,需要添加store/index.js文件,并对外暴露一个 Vuex.Store 实例:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = () => new Vuex.Store({
  state: {
    counter: 0
  },
  mutations: {
    increment (state) {
      state.counter++
    }
  }
})
export default store

现在我们可以在组件里面通过this.$store来使用状态树

<template>
    <button @click="$store.commit('increment')">{{ $store.state.counter }}</button>
</template>

模块方式

状态树还可以拆分成为模块,store目录下的每个.js文件会被转换成为状态树指定命名的子模块

使用状态树模块化的方式,store/index.js不需要返回 Vuex.Store 实例,而应该直接将statemutationsactions暴露出来:

export const state = () => ({
  counter: 0
})
export const mutations = {
  increment (state) {
    state.counter++
  }
}

其他的模块文件也需要采用类似的方式,如store/todos.js文件:

export const state = () => ({
  list: []
})
export const mutations = {
  add (state, text) {
    state.list.push({
      text: text,
      done: false
    })
  },
  remove (state, { todo }) {
    state.list.splice(state.list.indexOf(todo), 1)
  },
  toggle (state, todo) {
    todo.done = !todo.done
  }
}

在页面组件pages/todos.vue, 可以像下面这样使用todos模块:

<template>
  <ul>
    <li v-for="todo in todos">
      <input type="checkbox" :checked="todo.done" @change="toggle(todo)">
      <span :class="{ done: todo.done }">{{ todo.text }}</span>
    </li>
    <li><input placeholder="What needs to be done?" @keyup.enter="addTodo"></li>
  </ul>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
  computed: {
    todos () { return this.$store.state.todos.list }
  },
  methods: {
    addTodo (e) {
      this.$store.commit('todos/add', e.target.value)
      e.target.value = ''
    },
    ...mapMutations({
      toggle: 'todos/toggle'
    })
  }
}
</script>
<style>
.done {
  text-decoration: line-through;
}
</style>

模块方法也适用于顶级定义,而无需在store目录中实现子目录

state 示例,您需要创建一个文件store/state.js并添加以下内容:

export default () => ({
  counter: 0
})

并且相应的 mutations 在文件store/mutations.js中:

export default {
  increment (state) {
    state.counter++
  }
}

模块文件

您可以将模块文件分解为单独的文件:state.js,actions.js,mutations.jsgetters.js

如果您使用index.js来维护state,getters,actionsmutations,同时具有单个单独的操作文件,那么仍然可以正确识别该文件。

项目结构

vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:

  • 应用层级的状态应该集中到单个 store 对象中。
  • 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
  • 异步逻辑都应该封装到 action 里面。

只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。

对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。

下面是项目结构示例

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块

下面用是实例说一下怎么使用

一、在Nuxt项目的store目录下新建一个index.js文件

这样项目就启用了vuex

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = () => new Vuex.Store({
  state: {
    counter: 0
  },
  mutations: {
    increment (state) {
      state.counter++
    }
  }
})
export default store

一般这个文件我们只作为vuex的入口文件,不在这里面写业务代码,其他的功能写在其他的vuex文件中,在index中导入一下即可

二、在store文件夹里再新建一个filter.js文件

在index.js中引入一下,这个文件来写我们的业务代码

filter.js文件

const state = ({
  value: 'Hello World',
  list: [1, 2, 3, 4, 5]
});
const getters = {
  include: (state) => (val) => {
    return state.list.indexOf(val) > -1;
  }
  }
;
const mutations = {
  SET_VALUE(state, value) {
    state.value = value;
  }
};
const actions = {
  async getInfo({state, commit}, val) {
    commit('SET_VALUE', val);
  }
};
export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
};

这个文件中输出时候的namespaced属性,如果为true时,使用这个文件的方法时,需要标注namespace,不写或为false时,则可以直接使用,这里建议使用namespaced,因为大型项目可能有很多复杂的业务,可能命名冲突,使用namespaced可以把方法区分开,避免很多问题

index.js文件

import Vue from 'vue';
import Vuex from 'vuex';
import filter from './filter';
Vue.use(Vuex);
const store = () => new Vuex.Store({
  state: {
  },
  mutations: {
  },
  modules: {
    filter
  }
});
export default store

在index.js文件中import一下我们的filter.js文件,然后在modules中引入即可使用

三、在vue文件中使用vuex

index.vue

<template>
  <section class="p-10">
    <h1> {{ value }} </h1>
    <h1> {{ result }} </h1>
    <el-button type="danger" @click="change">点击</el-button>
  </section>
</template>
<script>
  import { mapState, mapMutations, mapActions, mapGetters } from 'vuex';
export default {
  data() {
    return {
      result: false
    };
  },
  computed: {
    ...mapGetters('filter', [
      'include'
    ]),
    ...mapState({
      value: state => state.filter.value
    })
  },
  methods: {
    ...mapMutations('filter', [
      'SET_VALUE'
    ]),
    ...mapActions('filter', [
      'getInfo'
    ]),
    change() {
      // this.result = this.include(1);
      // this.getInfo('你好');
      // this.SET_VALUE('HELLO');
    }
  },
  mounted() {
  },
  beforeDestroy() {
  }
};
</script>

1.在vue文件中,首先通过import { mapState, mapMutations, mapActions, mapGetters } from 'vuex' 来引入我们需要的模块,按需引用,只需要引入本页面用到的模块即可

2.mapGetters和mapState需要在页面的计算属性computed中引入,mapMutations和mapActions需要在methods中引入,此时要注意模块的命名空间,如果vuex文件导出时标注了namespaced,我们使用时也需要写出才可以找到,反之则不需要

3.首先是mapState,使用mapState时,我有两种方法来取,两种方式都可以,这个方法是从store中取出这个变量,然后显示在此页面上,store变动的话,此页面也会跟着动态改变

...mapState({
      value: state => state.filter.value
    })
...mapState('filter', {
      value: state => state.value
    })

4.mapGetters类似于store的计算属性,我们可以通过mapGetters的方法在store里进行计算,然后返回我们需要的结果即可

上面例子就是点击按钮的时候传了一个数字到store里,然后判断store里的list是否包含这个数字,然后返回结果到页面,页面根据返回值重新刷新数据

5.MapMutation是更改store中状态的唯一方法,Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和 一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

上面的例子是点击按钮时,直接通过mutation 的方法修改了store里的数据,然后把数据同步到页面

6.mapAction类似于mutation, 但是Action提交的是mutation,而不是直接变更状态,Action可以包含任意异步操作,我们一般把异步获取数据的方法都放在这里,然后在回调函数里使用mutation里的方法把异步获取的数据保存在store里,然后把store里的数据传到页面

上面的例子是点击按钮时调用了action里的异步方法,然后在方法的回调函数里修改了store的数据,一般这里是把请求的结果进行保存,这里是省略了请求API方法

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 记一次vue跨域的解决

    记一次vue跨域的解决

    这篇文章主要介绍了vue跨域的解决方法,帮助大家解决前端跨域问题,感兴趣的朋友可以参考下
    2020-10-10
  • vue添加锚点,实现滚动页面时锚点添加相应的class操作

    vue添加锚点,实现滚动页面时锚点添加相应的class操作

    这篇文章主要介绍了vue添加锚点,实现滚动页面时锚点添加相应的class操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • 在Vue3中实现一个自定义的v-html组件方式

    在Vue3中实现一个自定义的v-html组件方式

    文章介绍了Vue.js中的v-html指令及其潜在的安全风险,然后通过DOMParser实现了一个自定义的v-html组件,以提高安全性并避免XSS攻击
    2025-11-11
  • 深入探索Vue3.x中的七大高级用法

    深入探索Vue3.x中的七大高级用法

    Vue3.x 自发布以来,凭借其性能的显著提升和更加灵活的组合式 API,已经成为了现代前端开发的重要工具之一,除了基本用法外,Vue3.x 还提供了许多高级功能,本文将和大家一起深入探索Vue3.x中的七大高级用法,需要的朋友可以参考下
    2024-03-03
  • Vue项目之安装引入使用vconsole方式(生产环境不显示)

    Vue项目之安装引入使用vconsole方式(生产环境不显示)

    在Vue2开发中,引入vConsole可以为移动端提供类似浏览器F12的调试工具,支持查看日志、网络请求等功能,vConsole是一个轻量、可拓展的前端调试面板,与框架无关,适用于多种前端框架,安装方法包括npm和CDN两种,可根据项目环境配置是否显示调试面板
    2024-10-10
  • vue 中 beforeRouteEnter 死循环的问题

    vue 中 beforeRouteEnter 死循环的问题

    这篇文章主要介绍了vue beforeRouteEnter 死循环的问题,在文章末尾给大家补充介绍了vue中beforeRouteEnter使用的误区,需要的朋友可以参考下
    2019-04-04
  • vue将时间戳转换成自定义时间格式的方法

    vue将时间戳转换成自定义时间格式的方法

    下面小编就为大家分享一篇vue将时间戳转换成自定义时间格式的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue引入组件的几种方法代码示例

    vue引入组件的几种方法代码示例

    vue的一个强大功能就是组件化开发,下面这篇文章主要给大家介绍了关于vue引入组件的几种方法,文中给出了详细的代码及图文介绍,需要的朋友可以参考下
    2024-04-04
  • vue路由守卫,限制前端页面访问权限的例子

    vue路由守卫,限制前端页面访问权限的例子

    今天小编就为大家分享一篇vue路由守卫,限制前端页面访问权限的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Vue组件内部实现一个双向数据绑定的实例代码

    Vue组件内部实现一个双向数据绑定的实例代码

    这篇文章主要介绍了Vue组件内部实现一个双向数据绑定的实例代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04

最新评论