Vue 入门到实战 十一 Vuex

目录

11.1状态管理与应用场景

1)state

2)Getters

3)Mutations

4)Actions

5)Module

11.2Vuex的安装与基本应用

11.3Vuex的核心概念


一句话解释vuex:就是单独成立一个组件,这个组件存储共享的数据,其他组件都可以从这个共享组件里面抽取数据。这就是vuex的作用。

11.1状态管理与应用场景

本章主要讲解了Vuex的基本用法。通过本章的学习,掌握Vuexstategettersmutationsactions等核心概念,掌握如何使用Vuex进行状态管理。

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

大白话:Vuex 是一个插件,可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。例如:购物车数据 个人信息数

状态(state:驱动应用的数据源,即组件中的data

视图(view:以声明方式将状态映射到视图,如{{counter}}

操作action:响应在视图上的用户输入导致的状态变化,即组件的函数methods

1)state

state是存储的单一状态,是存储的基本数据。

2)Getters

getters是store的计算属性,对state的加工,是派生出来的数据。就像computed计算属性一样,getter返回的值会根据它的依赖被缓存起来,且只有当它的依赖值发生改变才会被重新计算。

3)Mutations

mutations提交更改数据,使用store.commit方法更改state存储的状态。(mutations同步函数)

4)Actions

actions像一个装饰器,提交mutation,而不是直接变更状态。(actions可以包含任何异步操作)

5)Module

Module是store分割的模块,每个模块拥有自己的state、getters、mutations、actions。

在较大型的项目中,将有许多组件用到同一变量,比如,一个登录的状态,很多页面组件都需要这个信息。在这样的情景下,使用Vuex进行登录状态的统一管理就很方便。当然,虽然麻烦但也可以时刻在对应页面操作cookie。所以,状态管理不是必需的,所有状态管理能做的,都能用其它方式实现,但是状态管理提供了统一管理的地方,操作方便,也更加明确。但一些状态只是父组件和子组件共享,不推荐使用状态管理实现,而用$emitprops即可简单实现。

11.2Vuex的安装与基本应用

1.安装Vuex

VueRouter一样,将Vuex添加到项目中也有4种主要方法:本地独立版本方法、CDN方法、NPM方法以及命令行工具(VueCLI)方法。

2.项目文件中导入并显式地使用Vuex

使用VueCLI安装Vuex后,首先,在项目的/src/store/index.js文件中,导入Vuex模块,并创建一个store(仓库)。

然后,在项目主文件main.js中导入Vuex,并显式地使用Vue实例调用Vuex

    import { createApp } from 'vue'import App from './App.vue'import store from './store' //导入store目录中的index.js,Vuex的创建与配置在该文件中createApp(App).use(store).mount('#app')

    11.3Vuex的核心概念

    Vuex应用的核心是store,即仓库。store实际上就是一个容器,它包含应用中大部分的状态(state),与单纯的全局对象不同,主要有两点区别。

    1Vuex的状态存储是响应式的。也就是说,当Vue实例或组件从仓库store中读取状态时,若store中状态发生变化,那么相应的Vue实例或组件也会高效更新。

    2)用户不能直接更新store中的状态。更新的唯一途径是显式地提交mutation(类似于事件),以便跟踪每一个状态的变化。

    一个完整的store包含stategettersmutationsactionsmodules五大组成部分。

    11.3.1 Vuex中的state

    Vuex使用单一状态树,即使用一个对象包含了所有的应用层级状态,作为一个唯一的数据源而存在。也就是说,每个应用将仅包含一个仓库store实例。因此,需要状态跟踪(管理)的数据保存在Vuex选项的state选项内。

    1.在Vue 组件中通过computed计算属性获得 Vuex状态

    $storestore的区别

    l  $store是挂载在Vue 实例上的(即Vue.prototype),而组件也是一个Vue实例。在组件中可使用this访问原型上的属性,template拥有组件实例的上下文,可直接通过{{$store.state }}访问,等价于script 中的this.$store.state

    l  store是挂载到Vue上,为Vue的根实例;store引入后被注入到Vue上,成为Vue的原型属性,所以store是挂载到Vue上,为Vue的根实例;store引入后被注入到Vue上,成为Vue的原型属性,所以在script中通过store.state$store.state都可以访问。

    l  至于{{store.state}}script中的data需声明过store才可以访问。

    2.在Vue 组件中通过mapState()辅助函数获得Vuex 状态

    当一个组件需要获取多个状态时,将这些状态都声明为计算属性会有些重复和冗余。为解决这个问题,Vuex通过使用 mapState() 辅助函数帮助生成计算属性,减少按键次数。

    mapState() 辅助函数返回的是一个对象,用来获取多个状态。mapState()可以接收{}[]作为参数。

    {}参数为键值对形式参数,即key:valuekey为计算属性,value为函数,参数为store.state,返回需要的state

      computed: mapState({    // 箭头函数可使代码更简练    count: state => state.count,    // 传字符串参数 'count' 等同于 `state => state.count`    countAlias: 'count',    // 为了能够使用 `this` 获取局部状态,必须使用常规函数    countPlusLocalState(state) {      return state.count + this.localCount    }  })

      当映射的计算属性名称与state的子节点名称相同时,可以为mapState()传一个字符串数组参数。

      computed: mapState([

        // 映射 this.count 为 store.state.count

        'count'   //可以有多个state对象中属性,用逗号分隔

      ])

      3.对象展开运算符

        mapState()函数返回的是一个对象。如何将它与局部计算属性混合使用呢?通常,首先需要使用一个工具函数将多个对象合并为一个,然后将最终对象传给computed 属性。但自从有了对象展开运算符(…),可以极大地简化写法。computed: {  localComputed () { /* ... */ },  // 使用对象展开运算符将此对象混入到外部对象中  ...mapState({    // ...  })}

        app.vue

        app是从共享组件中读取数据,这里有两种方式,

        方法一

        this.$store.state.bookPress
        方法二
        ...mapState(['BISBN''bookPrice''bookAuthor']),注意这里的三个点的含义是打散的意思,我们看看下面的这个例子,.mapState数据赋值给变量S,然后在控制台打印,发现是个键值对,key是组件state里面的对象key。
        let mapState(['BISBN''bookPrice''bookAuthor'])

        ...mapState(['BISBN''bookPrice''bookAuthor']),最后就会变成

        BISBN:ƒ mappedState()

        bookPrice:ƒ mappedState()

        bookAuthorƒ mappedState()

          <template><div><h3>{{bookName}}</h3><h3>作者:{{$store.state.bookAuthor}}</h3><h3>出版社:{{$store.state.bookPress}}</h3><h3>ISBN:{{$store.state.BISBN}}</h3><h3>价格:{{$store.state.bookPrice}}</h3></div><hr/><div><h3>{{bookName}}</h3><h3>作者:{{bookAuthor}}</h3><h3>出版社:{{bookPress}}</h3><h3>ISBN:{{BISBN}}</h3><h3>价格:{{bookPrice}}</h3></div>
          </template>
          <script>
          import { mapState } from 'vuex'
          export default {name: 'App',data() {//组件中的私有数据return {bookName : 'Vue.js '}},//使用计算属性获取store中的状态数据computed: {bookPress() {return this.$store.state.bookPress},//使用对象展开运算符获取store中的状态数据...mapState(['BISBN', 'bookPrice', 'bookAuthor']),}
          }
          </script>
          <style>
          #app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
          }
          </style>

          index.js

            import { createStore } from 'vuex'
            export default createStore
            ({  state: { BISBN : '9787302598503',   bookPrice : 99.8,    bookAuthor : '刘巍',    bookPress : '江西出版社'  }, mutations: {  }, actions: {  },  modules: {  }})

            main.js

              import { createApp } from 'vue'
              import App from './App.vue'
              import store from './store'
              createApp(App).use(store).mount('#app')

              11.3.2 Vuex中的getters

              在工程项目中,有时需要从 store.state 中派生出一些状态,如对列表进行过滤并计数,可以通过计算属性来实现,具体代码如下。

                computed: {doneTodosCount () {return this.$store.state.todos.filter(todo=> todo.done).length}
                }

                Vuex允许在store中定义“getters(可以认为是 store 的计算属性)。getters可以接受state 作为其第一个参数,示例代码如下。

                  const store = createStore({state: {todos: [{ id: 1, text: '...', done: true },{ id: 2, text: '...', done: false }]},getters: {doneTodos (state) {return state.todos.filter(todo => todo.done)}} })

                  index.js

                    import { createStore } from 'vuex'
                    export default createStore({state: {BISBN : '9787302598503',bookPrice : 99.8,bookAuthor : '刘巍',bookPress : '江西出版'},getters: {//接受 state 作为其第一个参数getBookPrice(state) {return state.bookPrice},//接受其他 getters 作为第二个参数getThreeTimesBookPrice(state, getters) {return state.bookPrice + getters.getBookPrice * 2}},mutations: {},actions: {},modules: {}
                    })

                    getters程序流程图:

                    ①在21行中用插值语法读取计算属性的值.

                    ②计算梳理有个方法mapGetters里面有数组,数组里面就是方法名,系统就会调用store下面的index.JS文件,getters是默认的语法关键字.

                    ③getters方法就是从数据源state中获取数据,然后二次加工.

                    app.vue

                      <template><div><h3>{{bookName}}</h3><h3>作者:{{$store.state.bookAuthor}}</h3><h3>出版社:{{$store.state.bookPress}}</h3><h3>ISBN:{{$store.state.BISBN}}</h3><h3>价格:{{$store.state.bookPrice}}</h3></div><hr/><div><h3>{{bookName}}</h3><h3>作者:{{bookAuthor}}</h3><h3>出版社:{{bookPress}}</h3><h3>ISBN:{{BISBN}}</h3><h3>价格:{{bookPrice}}</h3></div><hr/><h3>getters访问</h3><h3>一本书花的钱:{{$store.getters.getBookPrice}}</h3><h3>三本书花的钱:{{$store.getters.getThreeTimesBookPrice}}</h3><h3>一本书花的钱:{{getBookPrice}}</h3><h3>三本书花的钱:{{getThreeTimesBookPrice}}</h3>
                      </template>
                      <script>
                      import { mapState } from 'vuex'
                      import { mapGetters } from 'vuex'
                      export default {name: 'App',data() {//组件中的私有数据return {bookName : 'Vue.js 3'}},//使用计算属性获取store中的状态数据computed: {bookPress() {return this.$store.state.bookPress},//使用对象展开运算符获取store中的状态数据...mapState(['BISBN', 'bookPrice', 'bookAuthor']),...mapGetters(['getBookPrice', 'getThreeTimesBookPrice'])//混入计算属性}
                      }
                      </script>
                      <style>
                      #app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
                      }
                      </style>

                      main.js

                        import { createApp } from 'vue'
                        import App from './App.vue'
                        import store from './store'
                        createApp(App).use(store).mount('#app')

                        11.3.3 Vuex中的mutations

                        更改 Vuex 的 store 中的状态的唯一方法是提交 mutations。每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是实际进行状态更改的地方,并且它会接受 state 作为第一个参数。(其实简单的理解就是state的数据不能直接修改,需要通过mutations里面的方法去修改数据源state的数据)

                        const store = createStore({state: {count: 1},mutations: {increment (state) {  // increment为事件类型type,state为参数// 变更状态state.count++}}})

                        不能直接调用一个 mutation 处理函数。这个选项更像是事件注册:“当触发一个类型为 increment 的 mutation 时,调用此函数。”要唤醒一个 mutation 处理函数,需要以相应的 type 调用 store.commit()方法。store.commit('increment')

                        11.3.4 Vuex中的actions

                        actions 类似于 mutations,不同在于以下两点。

                        l  actions提交的是 mutations,而不是直接变更状态。

                        l  actions可以包含任意异步操作。

                        actions中的方法需要使用store.dispatch()方法调用。action函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此可以调用 context.commit() 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters

                        一句话解释:action就是异步请求,比如我调用一个接口,我不会等接口结果,就处理后面的代码,等接口返回数据的时候,我重新渲染页面。

                        app.vue

                        <template><div><h3>书名:{{bookName}}</h3><h3>出版社:{{$store.state.bookPress}}</h3><h3>作者:{{$store.state.bookAuthor}}</h3><h3>原价:{{bookPrice}}</h3></div><hr/><my-add></my-add><hr/><my-reduce></my-reduce>
                        </template>
                        <script>
                        import { mapState } from 'vuex'
                        import AddBookPrice from './components/AddBookPrice.vue'
                        import ReduceBookPrice from './components/ReduceBookPrice.vue'
                        export default {name: 'App',computed: {...mapState(//混入计算属性['bookName','bookPrice'])},components: {//定义子组件'my-add': AddBookPrice,'my-reduce': ReduceBookPrice}
                        }
                        </script>
                        <style>
                        #app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
                        }
                        </style>

                        index.js

                        import { createStore } from 'vuex'
                        export default createStore({state: {BISBN : '9787302598503',bookPrice : 99.8,bookAuthor : '刘巍',bookPress : '江西出版社',bookName : 'Vue.js 3'},getts: {},mutations: {addBookBy10(state) {state.bookPrice = state.bookPrice + 10},addBookByNum(state, num) {state.bookPrice = state.bookPrice + num},reduceBookBy10(state) {state.bookPrice = state.bookPrice - 10},reduceBookByNum(state, num) {state.bookPrice = state.bookPrice - num},},actions: {//同步增加addBookBy10Action(context) {//执行mutations中的addBookBy10context.commit('addBookBy10')},//同步减少,step为参数reduceBookByNumAction(context, step) {//执行mutations中的reduceBookByNumcontext.commit('reduceBookByNum', step)},//异步增加addBookBy10ActionAsync(context) {setInterval(() => {context.commit('addBookBy10')}, 1000);},//异步减少,step为参数reduceBookByNumActionAsync(context, step) {setInterval(() => {context.commit('reduceBookByNum', step)}, 1000);}},modules: {}
                        })

                        main.js

                        import { createApp } from 'vue'
                        import App from './App.vue'
                        import store from './store'
                        createApp(App).use(store).mount('#app')

                        本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/75158.shtml

                        如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

                        相关文章

                        【YOLOv11】目标检测任务-实操过程

                        目录 一、torch环境安装1.1 创建虚拟环境1.2 启动虚拟环境1.3 安装pytorch1.4 验证cuda是否可用 二、yolo模型推理2.1 下载yolo模型2.2 创建模型推理文件2.3 推理结果保存路径 三、labelimg数据标注3.1 安装labelimg3.2 解决浮点数报错3.3 labelimg UI界面介绍3.4 数据标注案例…

                        探索 Vue 中的多语言切换:<lang-radio /> 组件详解!!!

                        探索 Vue 中的多语言切换&#xff1a;<lang-radio /> 组件详解 &#x1f30d; 嗨&#xff0c;大家好&#xff01;&#x1f44b; 今天我们来聊聊如何在 Vue 项目中实现一个优雅的多语言切换功能——<lang-radio /> 组件。这是一个小而美的组件&#xff0c;出现在登…

                        grafana 配置页面告警

                        添加告警规则 1.登录grafana 点击 Alerting > Alert rules 点击 New alert rule 2.填写告警规则名字 3.配置告警规则 选择数据源为 Loki 单机 Builder 单机Label brower 单机 node_name 标签&#xff0c;选择一个主机&#xff0c;选好后单机 Show logs 这时候查询语…

                        关于JVM和OS中的栈帧的区别和内存浅析

                        关于JVM和OS中的栈帧的区别和内存浅析 刚看了黑马JVM中的栈帧的讲解&#xff0c;感觉和自己理解的栈帧有一定出入&#xff0c;查询资料研究了一下发现的确有天壤之别&#xff0c;可惜黑马并没有讲。 故写下这篇文章巩固一下, OS的栈帧&#xff1a; ​ OS的栈帧会在调用一个函…

                        Python FastApi(7):请求体

                        1 多个参数 1.1 混合使用 Path、Query 和请求体参数 首先&#xff0c;毫无疑问地&#xff0c;你可以随意地混合使用 Path、Query 和请求体参数声明&#xff0c;FastAPI 会知道该如何处理。你还可以通过将默认值设置为 None 来将请求体参数声明为可选参数&#xff1a; from ty…

                        告别枯燥工作,走向自动化

                        嘿&#xff0c;小伙伴们&#xff01;今天给你们介绍两款超实用的RPA办公自动化软件&#xff0c;用它们&#xff0c;再也不用像机器一样做重复劳动啦&#xff0c;超省时间&#xff01; 工具名称&#xff1a;影刀RPA&#xff08;类似产品&#xff0c;八爪鱼 RPA&#xff0c;操作上…

                        一种C# Winform的UI处理

                        效果 圆角 阴影 突出按钮 说明 这是一种另类的处理&#xff0c;不是多层窗口 也不是WPF 。这种方式的特点是比较简单&#xff0c;例如圆角、阴影、按钮等特别容易修改过。其实就是html css DirectXForm。 在VS中如下 圆角和阴影 然后编辑这个窗体的Html模板&#xff0c…

                        HarmonyOS-ArkUI Navigation (导航组件)-第一部分

                        导航组件主要实现页面间以及组件内部的界面跳转&#xff0c;支持在不同的组件间进行参数的传递&#xff0c;提供灵活的跳转栈操作&#xff0c;从而便捷的实现对不同页面的访问和复用。 我们之前学习过Tabs组件&#xff0c;这个组件里面也有支持跳转的方式&#xff0c;Navigati…

                        华为开源自研AI框架昇思MindSpore应用案例:基于MindSpore框架实现PWCNet光流估计

                        如果你对MindSpore感兴趣&#xff0c;可以关注昇思MindSpore社区 1 环境准备 1.进入ModelArts官网 云平台帮助用户快速创建和部署模型&#xff0c;管理全周期AI工作流&#xff0c;选择下面的云平台以开始使用昇思MindSpore&#xff0c;可以在昇思教程中进入ModelArts官网 创建…

                        虚幻基础:UI

                        文章目录 控件蓝图可以装载其他控件蓝图可以安装其他蓝图接口 填充&#xff1a;相对于父组件填充水平框尺寸—填充—0.5&#xff1a;改变填充的尺寸填充—0.5&#xff1a;改变与父组件的距离 锚点&#xff1a;相对于父组件的控件坐标系原点&#xff0c;屏幕比例改变时&#xff…

                        监控平台——SkyWalking部署

                        一、环境准备 先下载SkyWalking安装包&#xff0c;需要注意的是SkyWalking 版本在10.X以上使用的nacos-client是2.X&#xff0c;如果安装的Nacos版本是1.X就会存在兼容性的问题。由于本人使用的SpringBoot项目是2.7.X版本&#xff0c;安装的Nacos版本只能是1.X版本的&#xff…

                        热门索尼S-Log3电影感氛围旅拍LUTS调色预设 Christian Mate Grab - Sony S-Log3 Cinematic LUTs

                        热门索尼S-Log3电影感氛围旅拍LUTS调色预设 Christian Mate Grab – Sony S-Log3 Cinematic LUTs 我们最好的 Film Look S-Log3 LUT 的集合&#xff0c;适用于索尼无反光镜相机。无论您是在户外、室内、风景还是旅行电影中拍摄&#xff0c;这些 LUT 都经过优化&#xff0c;可为…

                        自动化工作流工具的综合对比与推荐

                        最近收到很多朋友私信我说&#xff1a;“刷短视频的时候&#xff0c;总是刷到自动化工作流的工具&#xff0c;有好多直播间都在宣传&#xff0c;不知道哪款工具好”。我花了点时间&#xff0c;做了一下测试&#xff0c;大家可以参考一下&#xff0c;以下内容&#xff1a; 以下…

                        fircrawl本地部署

                        企业内部的网站作为知识库给dify使用&#xff0c;使用fircrawl来爬虫并且转换为markdown。 ​ git clone https://github.com/mendableai/firecrawl.gitcd ./firecrawl/apps/api/ cp .env.example .env cd ~/firecrawl docker compose up -d 官方&#xff1a; https://githu…

                        day17 学习笔记

                        文章目录 前言一、数组的增删改查1.resize函数2.append函数3.insert函数4.delete函数5.argwhere函数6.unique函数 二、统计函数1.amax&#xff0c;amin函数2.ptp函数3.median函数4.mean函数5.average函数6.var&#xff0c;std函数 前言 通过今天的学习&#xff0c;我掌握了num…

                        CentOS 8 Stream 配置在线yum源参考 —— 筑梦之路

                        CentOS 8 Stream ISO 文件下载地址&#xff1a;http://mirrors.aliyun.com/centos-vault/8-stream/isos/x86_64/CentOS-Stream-8-20240603.0-x86_64-dvd1.isoCentOS 8 Stream 网络引导ISO 文件下载地址&#xff1a;http://mirrors.aliyun.com/centos-vault/8-stream/isos/x86_6…

                        网络原理-TCP/IP

                        网络原理学习笔记&#xff1a;TCP/IP 核心概念 本文是我在学习网络原理时整理的笔记&#xff0c;主要涵盖传输层、网络层和数据链路层的核心协议和概念&#xff0c;特别是 TCP, UDP, IP, 和以太网。 一、传输层 (Transport Layer) 传输层负责提供端到端&#xff08;进程到进…

                        EF Core 执行原生SQL语句

                        文章目录 前言一、执行查询&#xff08;返回数据&#xff09;1&#xff09; 使用 FromSqlRaw或 FromSqlInterpolated 方法&#xff0c;适用于 DbSet<T>&#xff0c;返回实体集合。2&#xff09;结合 LINQ 查询3&#xff09;执行任意原生SQL查询语句&#xff08;使用ADO.N…

                        Unity LOD Group动态精度切换算法(基于视锥+运动速度)技术详解

                        一、动态LOD技术背景与核心挑战 1. 传统LOD系统的局限 静态阈值切换&#xff1a;仅基于距离的切换在动态场景中表现不佳 视觉突变&#xff1a;快速移动时LOD层级跳变明显 性能浪费&#xff1a;静态算法无法适应复杂场景变化 对惹&#xff0c;这里有一个游戏开发交流小组&…

                        MyBatis复杂查询——一对一、一对多

                        目录 &#xff08;一&#xff09;复杂查询&#xff1a;1对1关系 【任务】数据库里有学生表(student)和学生证信息表(student_card)&#xff0c;表结构如下所示&#xff0c;要求使用MyBatis框架查询所有的学生信息以及每位学生的学生证信息 解决方案1&#xff1a;关联查询实现…