vuex vuex模块化案例

Posted 暑假过期le

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vuex vuex模块化案例相关的知识,希望对你有一定的参考价值。

Vuex

一.简介

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

Vuex采用类似全局对象的形式来管理所有组件的公用数据,如果想修改这个全局对象的数据,得按照Vuex提供的方式来修改(不能自己随意用自己的方式来修改)。

二.安装使用步骤

1.安装Vuex

npm i vuex

2.引入Vuex

import Vuex from 'vuex'
Vue.use(Vuex)

3.新建store文件

在scr目录下创建store目录,其中新建index.js文件

使用Vuex,我们要创建一个实例store,我们称之为仓库,利用这个仓库store来对我们的状态进行管理

创建一个store
const store =new Vuex.Store()

主要有一下这几个模块

state:定义了应用状态的数据结构,可以在这里设置默认的初始状态,vuex 中的 state 相当于组件中的 data

getter:允许组件从store中获取数据,mapGetters辅助函数仅仅是将store中的getter映射到局部计算属性

mutation:是唯一更改store中状态的方法,且必须是同步函数

action:用于提交mutation,而不是直接改变状态,可以包含任意异步操作

module:可以将store分割成模块。每个模块拥有自己的state,mutation,action,getter,甚至是嵌套子模块——从上至下进行同样方式的分隔

1.state

全局状态count的值为5.那么,我吗就可将其定义位state对象中的key和value作为全局状态使用如下:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store(
  // state存储应用层的状态
  state: 
    song: 5
  
)
export default store

2.Getters

可以认为,getters 是store的计算属性,类似于computed,对state里的数据进行一些过滤,改造...

要在state.song的基础上派出一个新的状态newSong出来,就用getters 接受state作为其中一个参数

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store(
  // state存储应用层的状态
  state: 
    song: '身骑白马'
  ,
  getters: 
    newSong: state => state.song + '徐佳莹'
  
)
export default store

在数组中获取newSong方式:

<template>
  <div>
     $store.state.song 
    <h1> newSong </h1>
  </div>
</template>
<script>
export default 
  computed: 
    newSong () 
      return this.$store.getters.newSong
    
  

</script>

3.mutations

vuex给我们提供修改仓库store中的状态的唯一办法就是通过提交mutation,并且必须是同步函数(也可以是异步,但是不提倡)

在mutations中定义了一个叫addSong的函数,函数体就是我们要进行更改的地方会接受state作为第一个参数,第二个是自定义传参

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store(
  // state存储应用层的状态
  state: 
    song: 8
  ,
  getters: 
    newSong: state => state.song + '徐佳莹'
  ,
  mutations: 
    addSong (state) 
      state.song++
    
  
)
export default store

在组件中获取newSong方式:

<template>
  <div>
     $store.state.song 
    <h1> newSong </h1>
    <button @click="add">增加</button>
  </div>
</template>
<script>
import  mapState, mapMutations  from 'vuex'
export default 
  data () 
    return 
  ,
  methods: 
    ...mapMutations(['addSong']),
    add () 
      this.addSong()
    
  ,
  computed: 
    ...mapState(['newSong'])
  

</script>

模块化

在大型项目中,为了方便项目的维护,代码的更新,需要将项目

没有进行模块化写法

进行模块化

1.vuex状态管理
定义一个module文件,将vuex状态管理分开

2.在index.js中引入并使用模块

3.newlist.js模块(category.js格式一样)

vuex模块化案例


安装vue脚手架

vue create toutiao

在app.vue中

<template>
  <div id="app">
    <!-- 导航 -->
    <Category></Category>
    <!-- 点击导航后展示的对应的内容 -->
    <NewsList></NewsList>
  </div>
</template>
<script>
import Category from './components/Category'
import NewsList from './components/NewsList'
export default 
  name: 'App',
  components: 
    Category,
    NewsList
  

</script>

在src中新建一个style文件夹创建index.css

body 
  margin: 0;
  padding: 0;


*,
*:before,
*:after 
  box-sizing: inherit;


li 
  list-style: none;


dl,
dd,
dt,
ul,
li 
  margin: 0;
  padding: 0;


.no-padding 
  padding: 0px !important;


.padding-content 
  padding: 4px 0;


a:focus,
a:active 
  outline: none;


a,
a:focus,
a:hover 
  cursor: pointer;
  color: inherit;
  text-decoration: none;


b 
  font-weight: normal;


div:focus 
  outline: none;


.fr 
  float: right;


.fl 
  float: left;


.pr-5 
  padding-right: 5px;


.pl-5 
  padding-left: 5px;


.block 
  display: block;


.pointer 
  cursor: pointer;


.inlineBlock 
  display: block;


.catagtory 
  display: flex;
  overflow: hidden;
  overflow-x: scroll;
  background-color: #f4f5f6;
  width: 100%;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;


.catagtory li 
  padding: 0 15px;
  text-align: center;
  line-height: 40px;
  color: #505050;
  cursor: pointer;
  z-index: 99;
  white-space: nowrap;


.catagtory li.select 
  color: #f85959


.list 
  margin-top: 60px;


.article_item 
  padding: 0 10px;


.article_item .img_box 
  display: flex;
  justify-content: space-between;



.article_item .img_box .w33 
  width: 33%;
  height: 90px;
  display: inline-block;


.article_item .img_box .w100 
  width: 100%;
  height: 180px;
  display: inline-block;



.article_item h3 
  font-weight: normal;
  line-height: 2;
  font-size: 20px;


.article_item .info_box 
  color: #999;
  line-height: 2;
  position: relative;
  font-size: 12px;



.article_item .info_box span 
  padding-right: 10px;



.article_item .info_box span.close 
  border: 1px solid #ddd;
  border-radius: 2px;
  line-height: 15px;
  height: 12px;
  width: 16px;
  text-align: center;
  padding-right: 0;
  font-size: 8px;
  position: absolute;
  right: 0;
  top: 7px;

在main.js中引入index.css

在commponets中创建 Category.vue和NewList.vue文件

Category.vue

<template>
  <ul class="catagtory">
    <li
      v-for="item in category"
      :key="item.id"
      @click="onSelect(item.id)"
      :class=" select: item.id === currentCategory "
    >
       item.name 
    </li>
  </ul>
</template>
<script>
import  mapGetters  from 'vuex'
export default 
  computed: 
    ...mapGetters(['category', 'currentCategory'])
  ,
  created () 
    this.$store.dispatch('getCategory')
    this.$store.dispatch('getnewsList', 2)
  ,
  methods: 
    onSelect (cateId) 
      this.$store.commit('updateCurrentCategory', cateId)
    
  

</script>

NewList.vue

<template>
  <div class="list">
    <div class="article_item" v-for="item in newsList" :key="item.id">
      <h3 class="van-ellipsis"> item.title </h3>
      <div class="img_box">
        <img :src="item.imgUrl" class="w100" />
      </div>
      <div class="info_box">
        <span> item.author </span>
        <span> item.comment_count 评论</span>
        <span> item.create_time </span>
      </div>
    </div>
  </div>
</template>
<script>
import  mapGetters  from 'vuex'
export default 
  computed: 
    ...mapGetters(['newsList', 'currentCategory'])
  ,
  watch: 
    currentCategory: function (newVlue) 
      this.$store.dispatch('getnewsList', newVlue)
    
  

</script>

在store中建立modules,modules文件中建立category.js,newlist.js

category.js

import axios from 'axios'
export default 
  state: 
    category: [],
    currentCategory: -1
  ,
  mutations: 
    updateCategory (state, result) 
      state.category = result
    ,
    updateCurrentCategory (state, cateId) 
      state.currentCategory = cateId
    
  ,
  actions: 
    async getCategory (context) 
      const url = 'https://www.fastmock.site/mock/ce0b69cd4c83bf085a0840aa9fdd545a/vuex/api/category'
      const res = await axios.get(url)
      context.commit('updateCategory', res.data.data.channels)
      context.commit('updateCurrentCategory', res.data.data.channels[0].id)
    
  


newlist.js

import axios from 'axios'
export default 
  state: 
    newsList: []
  ,
  mutations: 
    updateNewsList (state, result) 
      state.newsList = result
    
  ,
  actions: 
    async getnewsList (context, categoryId) 
      const url = 'https://www.fastmock.site/mock/ce0b69cd4c83bf085a0840aa9fdd545a/vuex/api/newlist?categoryId=' + categoryId
      const res = await axios.get(url)
      context.commit('updateNewsList', res.data.data)
    
  


在store中index.js

import Vue from 'vue'
import Vuex from 'vuex'
import category from './modules/category'
import newsList from './modules/newlist'
Vue.use(Vuex)
export default new Vuex.Store(
  modules: 
    category,
    newsList
  ,
  getters: 
    category: state => state.category.category,
    currentCategory: state => state.category.currentCategory,
    newsList: state => state.newsList.newsList
  ,
  state: ,
  mutations: ,
  actions: 
)

以上是关于vuex vuex模块化案例的主要内容,如果未能解决你的问题,请参考以下文章

Vuex 核心概念基本使用 及 求和案例

Vuex(二) —— 用Vuex完成购物车案例

Vue.js 状态管理:Pinia 与 Vuex

Vue.js 状态管理:Pinia 与 Vuex

Vue.js 状态管理:Pinia 与 Vuex

Vuex