当前位置: 首页>后端>正文

VueX详细教学(modules和namespaced)

一、今天主要解决:

1.1、 什么是vuex?

1.2、 为什么要用到vuex?

1.3、 基础用法?

二、初步认识Vuex

2.1、父子通信,兄弟间通信局限性

父子通信,兄弟间通信我们都知道,但是有复杂的项目,可能会嵌套很多层,这样一层一层的传值,很麻烦!不光是对代码质量造成了影响,也对代码运行的性能造成了影响,甚至会造成难以排查的bug。

2.2、讲个例子

小朋友想要零花钱,会先和妈妈要,妈妈没有,就去和爸爸要爸爸把零花钱给了妈妈妈妈再给了小朋友。这个就很麻烦了,解决办法,不如直接爸爸把零花钱放在一个指定的位置谁要,谁就去那个位置拿

2.3、vuex

vuex就是那个指定的地方,官方给起了个很专业的名字,叫:状态管理模式,说白了,就是一个统一存放状态的地方,谁用里边的值都可以取到,无论页面的层次多深,不用担心拿不到的问题,这样解决复杂通信或传值的问题就很方便了。

三、引入vuex

3.1、安装

//vue2
npm install --save vuex@3
//vue3
npm install --save vuex

3.2、编写store的js文件

在src目录下创建一个文件夹统一取名为 store
在store中创建index.js
新建的index.js中有如下代码:

import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex)

export default new vuex.Store({
    state: {},
    mutations: {},
    getters: {},
    actions: {},
    modules: {}
})

3.2、引入

import store from './store'
new Vue({
  store,
  render: h => h(App),
}).$mount('#app')

四、各个模块介绍

4.1、 state

export default new vuex.Store({
// 手动定义一些数据
   state:{
    a: 10
   }
})

接下来我们在组件中获取并使用一下这个公共的数据

<template>
  <div>
    {{$store.state.a}} // 页面中打印出10
  </div>
</template>

4.2、mutations

主要用于修改state中的数据

  • 参数一: state对应 state对象

  • 参数二: 形参- 需要传入的参数,可有可无

  • 语法: mutations:{‘mutations名’:funtion(state,形参) }

例子: 在state中a = 10 , 我们定义一个mutations方法 对state中的a的值进行修改

export default new vuex.Store({
    state: {
        a: 10
    },
    mutations: {
    state.a += 1 //  a+1
    },
})

接下来在App.vue中我们写一个button按钮用来点击并调用这个方法 点一次触发一次 让a的值每次加一

<template>
  <div>
    {{$store.state.a}}
     // 点击一次 就调用一次 进行+1
    <button @click="$store.commit('add')">a+1</button>
  </div>
</template> 
  • 在模板中: $store.commit(‘mutations名’)

  • 在组件中: 要加this调用, this.$store.commit(‘mutations名’)

4.3、getters

  • 语法: getters:{ ‘getters名’,function(state,形参)},用法和mutations差不多,
  • getters的作用是用于计算数据得到计算后的新的数据 类似于computed计算数据
  • 示例: 例如在state中有一个值为b:[1,2,3,4,5],

用getters对这个数据进行计算 然后打印到页面中,具体代码如下:

 getters: {
        sum: function (state) {
            return state.b.reduce((temp, item) => temp + item, 0)
        }
    }

在页面中渲染出来{{$store.getters.sum}} // 15

4.4、actions

  • 语法: actions:{ ‘action名’,function(context,形参)}

  • context其实就是对应的state .

  • actions用于发起异步的请求,可以在actions中用axios发起数据请求,获取数据
    继续看示例代码:
// 
  state:{
      book:[ ]
   },
   mutations:{
      updateBook:function(state,newbook){
      state.book = newbook
       }
   }

  actions: {
        getBooks: function (context) {
            axios({
                url: 'https://www.fastmock.site/mock/37d3b9f13a48d528a9339fbed1b81bd5/book/api/books',
                method: 'get'
            }).then(res => {
                console.log(res);
                context.commit('updateBook', res.data.data)
            })
        }
    }

注意: 在state中我定义了一个数组 book:[ ]用来接收获取到的数据 , 接收到数据res后, 想赋值给book数组, 但是要记住不能直接进行赋值,必须要在mutations中一个一个赋值的函数, 在actions获取到数据.调用mutations中的函数,进行赋值.

接着组件中写一个button按钮用来测试 触发actions发起axios请求获取数据,并赋值给book数组

调用actions的方式:

  • 模块中: $store.dispatch(‘actions名’)

  • 组件中: this.store.dispatch(‘actions名’)

<template>
  <div>
  // 点击 触发actions 并发起axios请求数据
    <button @click="$store.dispatch('getBooks')">获取数据</button>
    {{$store.state.book}} // 打印获取到的数据
  </div>
</template>

4.5、modules

modules中命名空间默认是namespaced: 为false ,
设置true后,在组件中使用拆分到modules的数据和方法要加"模块名"

  • 语法: modules:{ ‘模块名’:{state{},mutations:{},getters:{},actions:{} }}

  • 作用
    modules用来拆分index.js中的代码, 减少index.js中代码的繁多和体积,让index.js中更简洁,把相同的需要的数据和方法都提取到同一个js中

  • 前提
    在store文件中新建modules文件,把state中book数组和mutations中修改book的方法,以及actions中获取数据的相关代码剪切到modules文件中的新建的allBook.js文件中

import axios from 'axios'
export default {
    state: {
        b: [1, 2, 3, 4, 5],
        book: []
    },
    mutations: {
        updateBook: function (state, newbook) {
            state.book = newbook
        }
    },
    getters: {
        sum: function (state) {
            return state.b.reduce((temp, item) => temp + item, 0)
        }
    },
    actions: {
        getBooks: function (context) {
            axios({
                url: 'https://www.fastmock.site/mock/37d3b9f13a48d528a9339fbed1b81bd5/book/api/books',
                method: 'get'
            }).then(res => {
                console.log(res);
                context.commit('updateBook', res.data.data)
            })
        }
        
    }
}

抽离到allBook.js中后,在index.js中引入,并添加到modules对象中

import Vue from 'vue'
import vuex from 'vuex'
import allBook from './modules/allBook.js'

Vue.use(vuex)

export default new vuex.Store({
    modules: {
        allBook
    }
})

  • 注意:
    抽离后.组件中调用的方式就变了, 还记得我们加了namespaced: true这句话, 加了之后,引用数据和方法时都必须要加上模块名了

  • 示例: 如何调用

  • 以及其他三个调用方式:

// 例子: 
1. // 原先写法:  {{$store.getters.sum}}  //  15
2. // 抽离后的写法:  {{$store.gerters['allBook/sum']}} // 15
 
 // 这里我都列举一下其他三种的方式
 // state: 
  $store.state.模块名.属性名
 // mutations:
 $store.commit('模块名/mutation名')
 // getters:
  $store.gerters['模块名/getter名']
 // actions:
  $store.dispatch('模块名/action名')
  • 补充: 如果要修改state/mutations/getters/actions名字,例如:可以这样写 $store.commit(‘模块名,{新名字:久名字}’) ,其他的格式都类似如此

五、辅助函数用法(不分modules)

mapState/mapMutations/mapGetters/mapActions
  • 作用
    用来优化访问的方式, 普通的写法太麻烦了,利用vuex内置的方法,可以简洁的引用vuex中的数据和方法

5.1、mapState函数()

将state中的变量映射到当前组件中使用

使用步骤,代码如下:

// 当前组件中 按需引入mapState
// 例如引用vuex中state中的变量 c:30
<template>
{{c}} // 30
</template>
<script>
import { mapState } from 'vuex'
export default {
  computed: {
    ...mapState(['c'])
    // 如果需要改名字的话
    ...mapState({'新名字':'旧名字'})
  }
}
</script>
computed:{ …mapState() } 这里的…是对象的展开运算符,整体来看是对象的合并。

5.2、mapMutations

// 在state中定义一个变量为a:10
// App.vue组件中
<template>
  <div>
    {{a}}
    <button @click="abb">点击+1</button>
  </div>
</template>

<script>
import { mapMutations, mapState } from 'vuex'
export default {
  computed: {
    ...mapState(['a'])
  },
  methods: {
    ...mapMutations(['add'])
  },
}
</script>

以上列举了mapState和mapMutations的语法,其他两个(mapGetters和mapActions)用法和前两个都是一样的

六、辅助函数用法(分modules)(namespaced:false)

和访问非model用法一样,不赘述

七、辅助函数用法(分modules)(namespaced:true)

7.1、mapStates

computed: { 
  ...mapState('模块名', ['xxx']), 
  ...mapState('模块名', {'新名字': 'xxx'})
}
//或者
computed: { 
  ...mapState(['模块名/xxx']), 
  ...mapState({'新名字': '模块名/xxx'})
}

7.2、mapGetters

computed: { 
  ...mapGetters('模块名', ['xxx']), 
  ...mapGetters('模块名',{'新名字': 'xxx'})
}
//或者
computed: { 
  ...mapGetters(['模块名/xxx']), 
  ...mapGetters({'新名字': '模块名/xxx'})
}

7.3、mapMutations

methods: { 
  ...mapMutations('模块名', ['xxx']), 
  ...mapMutations('模块名',{'新名字': 'xxx'})
}
//或者
methods: { 
  ...mapMutations(['模块名/xxx']), 
  ...mapMutations({'新名字': '模块名/xxx'})
}

7.4、mapActions

methods: { 
  ...mapActions('模块名', ['xxx']), 
  ...mapActions('模块名',{'新名字': 'xxx'})
}
//或者
methods: { 
  ...mapActions(['模块名/xxx']), 
  ...mapActions({'新名字': '模块名/xxx'})
}

https://www.xamrdz.com/backend/33j1933987.html

相关文章: