Nuxt使用Vuex的方法示例


Posted in Javascript onSeptember 06, 2019

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

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

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

Nuxt使用Vuex的方法示例

这里主要简单讲一讲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 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:

  1. 应用层级的状态应该集中到单个 store 对象中。
  2. 提交mutation是更改状态的唯一方法,并且这个过程是同步的。
  3. 异步逻辑都应该封装到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方法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js之WEB开发调试利器:Firebug 下载
Jan 13 Javascript
JavaScript 和 Java 的区别浅析
Jul 31 Javascript
jCallout 轻松实现气泡提示功能
Sep 22 Javascript
JavaScript+html5 canvas绘制缤纷多彩的三角形效果完整实例
Jan 26 Javascript
JS获取input file绝对路径的方法(推荐)
Aug 02 Javascript
jquery实现下拉菜单的手风琴效果
Jul 23 jQuery
仿淘宝JSsearch搜索下拉深度用法
Jan 15 Javascript
一文读懂ES7中的javascript修饰器
May 06 Javascript
JS防抖和节流实例解析
Sep 24 Javascript
浅谈如何优雅处理JavaScript异步错误
Nov 12 Javascript
VUE.CLI4.0配置多页面入口的实现
Nov 25 Javascript
在vue中使用el-tab-pane v-show/v-if无效的解决
Aug 03 Javascript
vue中input的v-model清空操作
Sep 06 #Javascript
nuxt框架中对vuex进行模块化设置的实现方法
Sep 06 #Javascript
layui 表格操作列按钮动态显示的实现方法
Sep 06 #Javascript
基于Vue和Element-Ui搭建项目的方法
Sep 06 #Javascript
微信小程序 搜索框组件代码实例
Sep 06 #Javascript
layui加载表格,绑定新增,编辑删除,查看按钮事件的例子
Sep 06 #Javascript
详解webpack打包vue项目之后生成的dist文件该怎么启动运行
Sep 06 #Javascript
You might like
又一个php 分页类实现代码
2009/12/03 PHP
单点登录 Ucenter示例分析
2013/10/29 PHP
PHP使用SOAP调用.net的WebService数据
2013/11/12 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
js的event详解。
2006/09/06 Javascript
HTML Color Picker(js拾色器效果)
2013/08/27 Javascript
jquery.cookie用法详细解析
2013/12/18 Javascript
window.open打开页面居中显示的示例代码
2013/12/27 Javascript
用Jquery实现滚动新闻
2014/02/12 Javascript
使用jQuery实现验证上传图片的格式与大小
2014/12/03 Javascript
Jquery中巧用Ajax的beforeSend方法
2016/01/20 Javascript
基于JQuery实现图片上传预览与删除操作
2016/05/24 Javascript
jQuery模拟Marquee实现无缝滚动效果完整实例
2016/09/29 Javascript
Vue常用指令V-model用法
2017/03/08 Javascript
使用InstantClick.js让页面提前加载200ms
2017/09/12 Javascript
完美解决手机浏览器顶部下拉出现网页源或刷新的问题
2017/11/30 Javascript
Vue computed 计算属性代码实例
2020/04/22 Javascript
[54:18]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS BO3 第一场 1月22日
2021/03/11 DOTA
举例讲解Python面相对象编程中对象的属性与类的方法
2016/01/19 Python
Python程序运行原理图文解析
2018/02/10 Python
详解python使用pip安装第三方库(工具包)速度慢、超时、失败的解决方案
2018/12/02 Python
Python configparser模块配置文件过程解析
2020/03/03 Python
jupyter notebook 添加kernel permission denied的操作
2020/04/21 Python
python爬虫用scrapy获取影片的实例分析
2020/11/23 Python
python 制作本地应用搜索工具
2021/02/27 Python
CSS3地图动态实例代码(圆圈向外扩散)
2018/06/15 HTML / CSS
HTML5 CSS3给网站设计带来出色效果
2009/07/16 HTML / CSS
欧洲有机婴儿食品最大的市场:Organic Baby Food(供美国和加拿大)
2018/03/28 全球购物
Fossil美国官网:化石手表、手袋、首饰及配饰
2019/02/17 全球购物
用你熟悉的语言写一个连接ORACLE数据库的程序,能够完成修改和查询工作
2012/06/11 面试题
委托书怎么写
2014/07/31 职场文书
先进事迹材料范文
2014/12/29 职场文书
团代会开幕词
2015/01/28 职场文书
幼儿园父亲节活动总结
2015/02/12 职场文书
公司总经理岗位职责
2015/04/01 职场文书
2015年个人工作总结报告
2015/04/25 职场文书