【Vue】4000+长文带你学会Vuex(含使用案例)

目录

一、基本介绍

1.为什么要使用Vuex ?

2.原理图及解释

二、环境搭建

1.简述步骤

2.具体图示:

放一个纯代码版,以后可以直接复制:

三、简单案例

1.要实现的效果:

2.具体代码:

3.补充知识点:mapState等

四、进阶知识点

1.分多个小仓库

1.1划分结构:

1.2主要区别:

2.获取后端数据

一、基本介绍

1.为什么要使用Vuex ?

Vuex是Vue的一个插件库,用于实现组件间通信,其功能类似一个消息中转站,大家都向这个中转站发消息(存储数据),然后中转站再转发给需要用到数据的各个组件,如果你写过多人聊天室,就很容易理解其原理。或者也可用菜鸟驿站来理解。

但其功能原不止如此,相对于其他组件间通信的方法,如父组件与子组件间通信的props方法等而言,Vuex的一大优点就是方便接收后端服务器返回的数据,并进行更多的处理。

2.原理图及解释

原理图如下:

从图中可以看出Vuex主要由三部分组成,分别是Actions,Mutations以及State。下面会按顺序来依次简单解释各部分的用处

①Actions部分

这一部分主要是用来对应与各个组件使用各个方法(or称为响应组件中的动作),处理各种数据,或者调用后端接口API,获取服务器发过来的数据,然后进一步提交(Commit)给Mutations部分,从而进行存储;

②Mutations部分

这一部分才是真正要往仓库中存储数据的部分,Mutations部分既可以接收Actions部分发来的提交,也可以直接接收组件的提交,即可以跳过Actions部分,直接调用Mutations中的方法进行数据存储(一下再详细解释);

③State部分

这一部分有作为数据存储的仓库的功能,且一个Vuex只有一个State实例,也即所有提交上来的数据都存储在State中

介绍完以上三部分,再来解释Mutations部分中待解释的部分。

即:为何Mutations可以直接接受组件的提交?如果那Actions部分不就没有必要了吗?

答:其实Actions部分的作用主要就是为了接收从后端请求的数据,然后进行一些判断(如判断是否请求成功,或者对数据要进行一些筛选什么的...),然后再提交给Mutations,如果数据是固定的,或者前端就可以写好的,不用从后端请求的,那么自然可以跳过Acions部分

补充:

④getters 部分

该部分可以对state中的数据进行进一步处理,这在一些场合中是需要的,但不是Vuex必须的;除了处理数据之外,还可以简化数据的书写,在组件应用时就可以不写mapStates,而是写mapGetters(好处是分模块,会区分小仓库),其作用类似于组件中的计算属性(computed),每个getter被调用时都会执行一遍,并同步响应到仓库(store)中。

详细可见:Getter | Vuex

注意:

通常我们将actions部分中的函数名使用驼峰命名法,而mutations中的函数通常都大写,如

以上就是Vuex的存储原理以及简单的解释(笔者能力浅薄,如有疏漏,还望见谅!)

二、环境搭建

1.简述步骤

  • 安装Vuex(这里一定要注意与Vue的版本对应)
  • 创建store文件夹以及index.js文件,并配置
  • 在store的index.js中引入并使用Vuex(Vue.use(Vuex)
  • 在main.js中引入store并在vm实例上创建一个Store实例

2.具体图示:

①安装Vuex

版本 => 对应安装命令

Vue2 => npm i vuex@3

Vue3 => npm i vuex@4

②创建store文件夹以及index.js文件

 

③store文件夹中的index.js中具体配置:

 

放一个纯代码版,以后可以直接复制:

注意:这个纯代码版不适合分多个小仓库的情况(最后会有补充)

//引入Vue
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex
Vue.use(Vuex)
//actions用于响应组件中的动作
const actions = {

};
//mutations用于操作数据
const mutations = {

};
//state用于存储数据
const state = {

};
//getters用于对state中的数据进一步加工
const getters = {

}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

④在main.js中进行相应配置

1f09fbdacd6aef5441388f3ae0ce565c.png

嘿,哥们儿,都看到这里了,点个赞鼓励一下作者吧  ^_^  一起共同进步!

三、简单案例

1.要实现的效果:

 

选择一个数,然后点击按钮,进行求和

2.具体代码:

<template lang="">
    <div>
        <div>
            <h1>当前求和为:{{sum}}</h1>
            <h1>当前求和放大10倍为:{{bigSum}}</h1>
        </div>
        
        <select v-model.number="n">  
            <!-- 这里动态绑定了n,表示当点击该选项时,n就被赋值为value,且要注意这里要进行number强制类型转换,否则选择的默认是字符串类型-->
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
        <button @click="incrementOdd">当前求和为奇数再加</button>
        <button @click="incrementWait">等一秒再加</button>
    </div>
</template>
<script>
    import { mapState,mapGetters } from 'vuex';
    export default {
        name:"Count",
        data() {
            return {
                n:1, //用户选择的数字
            }
        },
        methods:{
            increment(){
                //这里因为不需要对参数进行处理,因此直接可以越过actions部分,而提交给Mutations部分
                this.$store.commit('JIA',this.n);
            },
            decrement(){
                //同上理
                this.$store.commit('JIAN',this.n);
            },
            incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n);
            },
            incrementWait(){
                this.$store.dispatch('jiaWait',this.n);
            }
        },
        computed: {
            ...mapState({
                sum:'sum'
            }),
            ...mapGetters({
                bigSum:'bigSum'
            })
        },
    }
</script>
<style lang="css">
    button{
        margin-left: 10px;
    }
</style>

//引入Vue
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex
Vue.use(Vuex)
//actions用于响应组件中的动作
const actions = {
    jiaOdd(context, value) {
        //context参数意为上下文,其包含的属性比store少,但也挺多
        //调用context参数下的commit方法,将参数value传递给mutations进行实际存储
        if (context.state.sum % 2) {
            context.commit('JIA', value);
        }
    },
    jiaWait(context, value) {
        setTimeout(() => {
            context.commit('JIA', value)
        }, 1000);
    },
  //注意:有时也可以用花括号提取出context中的commit方法,从而简化书写,如下
  /*
    jiaWait({commit}, value) {
        setTimeout(() => {
            commit('JIA', value)
        }, 1000);
    },
  */
};
//mutations用于操作数据(state)
const mutations = {
    JIA(state, value) {
        state.sum += value;
    },
    JIAN(state, value) {
        state.sum -= value;
    },
};
//state用于存储数据
const state = {
    sum:0
};
//getters用于对state中的数据进一步加工
const getters = {
    bigSum(state){  
        return state.sum*10;
    }
}

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters
})

说明:

这个案例虽然只有一个组件,并没有体现Vuex进行组件间通信的功能,但是其实已经很好地运用上了Vuex中的主要功能,即存储数据到公共仓库,并还可以进行一定的处理。

3.补充知识点:mapState等

可以注意到案例代码中Count组件里的计算属性使用了 ...mapState 以及 ...mapGetters,如下:

 

这里使用的是对象写法,其实也可以写成数组形式,如

(注意引号不要丢!)

他们其实是Vue团队为了方便组件使用Vuex的state中的数据而设计的 工具函数 ,存在于vuex插件库中,因此需要引入:

作为对比,下面展示未应用Vuex时的Count组件(纯Vue代码):

<template lang="">
  <div>
  <h1>当前求和为:{{sum}}</h1>
  <select v-model.number="n">  
  <!-- 这里动态绑定了n,表示当点击该选项时,n就被赋值为value,且要注意这里要进行number强制类型转换,否则选择的默认是字符串类型-->
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  </select>
  <button @click="increment">+</button>
  <button @click="decrement">-</button>
  <button @click="incrementOdd">当前求和为奇数再加</button>
  <button @click="incrementWait">等一秒再加</button>
  </div>
  </template>
  <script>
  export default {
  name:"Count",
  data() {
    return {
      n:1, //用户选择的数字
      sum:0, //当前的和
    }
  },
  methods:{
    increment(){
      this.sum += this.n;
    },
    decrement(){
      this.sum -= this.n;
    },
    incrementOdd(){
      if(this.sum % 2){  //如果sum对2取余不为0,则为奇数,则加
        this.sum+=this.n; 
      }
    },
    incrementWait(){
      setTimeout(()=>this.sum+=this.n,
                 1000)
    }
  }
}
  </script>
  <style lang="css">
  button{
  margin-left: 10px;
}
</style>

四、进阶知识点

1.分多个小仓库

为什么要分多个小仓库?

答:为了更清晰地划分各个组件模块所需要的不同数据。

1.1划分结构:

这里在store文件夹下的 index.js ,相当于主仓库,而另外三个.js文件则是分别管理不同组件数据的小仓库

1.2主要区别:

①在小仓库中,不需要单独命名了

②要在主仓库中进行整合

示例如下:

                                                                        小仓库

34bd9d04708b607d6b70e3699c189e2e.png                                                                         主仓库

2.获取后端数据

下面是detail.js小仓库中的部分配置,其主要目的就在于在actions中对后端发起请求,从而拿到数据传递给mutations进行存储。

其中 async、await是异步操作的关键词。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个比较广泛的问题,我会尽可能详细地回答。 首先,我们需要创建一个基本的 Vue.js 应用程序,并安装所需的依赖项。我们可以使用 Vue CLI 来创建应用程序,它会自动配置我们需要的大部分内容,如路由和状态管理。 ``` vue create my-app ``` 接下来,我们需要安装 vue-router 和 vuex,这两个库分别用于路由和状态管理。 ``` npm install vue-router vuex ``` 接着,我们可以创建一个名为“contacts”的组件,用于显示我们的通讯录。这个组件将包一个表格,用于显示我们的联系人列表。我们还需要一个名为“contact”的组件,用于编辑单个联系人的详细信息。 接下来,我们可以在我们的应用程序中配置路由。我们需要定义两个路由,一个用于显示联系人列表,另一个用于编辑单个联系人的详细信息。 ```javascript import Vue from 'vue' import VueRouter from 'vue-router' import Contacts from './components/Contacts.vue' import Contact from './components/Contact.vue' Vue.use(VueRouter) const routes = [ { path: '/', component: Contacts }, { path: '/contact/:id', component: Contact } ] const router = new VueRouter({ routes }) export default router ``` 在这里,我们使用 VueRouter 创建了两个路由。一个路由用于显示联系人列表,另一个路由用于编辑单个联系人的详细信息。我们使用“:id”来指定要编辑的联系人的 ID。这个参数将在我们的组件中使用。 接下来,我们可以创建一个名为“contacts”的 Vuex 模块,用于管理我们的通讯录。这个模块将包我们的联系人列表,并提供用于添加、编辑和删除联系人的方法。 ```javascript const state = { contacts: [] } const mutations = { addContact (state, contact) { state.contacts.push(contact) }, updateContact (state, contact) { const index = state.contacts.findIndex(c => c.id === contact.id) state.contacts.splice(index, 1, contact) }, deleteContact (state, contact) { const index = state.contacts.findIndex(c => c.id === contact.id) state.contacts.splice(index, 1) } } const actions = { addContact ({ commit }, contact) { commit('addContact', contact) }, updateContact ({ commit }, contact) { commit('updateContact', contact) }, deleteContact ({ commit }, contact) { commit('deleteContact', contact) } } export default { state, mutations, actions } ``` 在这里,我们定义了三个 mutation,用于添加、更新和删除联系人。我们还定义了三个 action,用于触发这些 mutation。 最后,我们可以使用 Axios 库从后端 API 获取我们的联系人数据。我们可以在组件的 created 钩子中发出 GET 请求,并将结果存储在我们的 Vuex store 中。 ```javascript import axios from 'axios' export default { created () { axios.get('/api/contacts') .then(response => { this.$store.dispatch('addContact', response.data) }) .catch(error => { console.log(error) }) } } ``` 在这里,我们使用 Axios 发出 GET 请求,并在响应中获取联系人数据。然后,我们调用我们的 Vuex action,将联系人添加到我们的 store 中。 最终,我们将所有这些部分组合在一起,使用我们的通讯录应用程序。我们可以像这样在我们的 App.vue 文件中导入我们的组件和路由: ```javascript <template> <div id="app"> <router-view></router-view> </div> </template> <script> import router from './router' export default { name: 'app', router } </script> ``` 在这里,我们将我们的路由器导入到我们的应用程序中,并在模板中使用<router-view>来显示当前路由。 这就是用 Vue 组件、Vue 路由、Vuex 和 Axios 实现通讯录的基本步骤。当然,这只是一个基本的示例,您可能需要根据您的具体需求进行更改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值