vuex原理

article/2025/4/22 10:16:56

目录

一、 为啥会出现vuex

二 、什么是vuex

三、 怎么使用vuex

四、vue和vuex比较

五、vuex的五个属性

5.1 state

5.2 mutations

5.3 getters

5.4 Actions

5.5 Modules

六、为啥state里的数据可以实现响应式

七、为啥每个组件都可以拿到state里的数据


一、 为啥会出现vuex

  若是vue内需要传递数据的组件不是父子组件关系或者两组件之间隔了很多其他组件,这时再通过上面的几种方式传递数据就会十分困难。于是有了vuex,我们可以把要共享的数据都存放到vuex中的state属性里,通过this.$store.state就能拿到里面的数据了!

二 、什么是vuex

  可以把vuex理解为一个大仓库,整个vue组件内都可以拿到里面的资源

三、 怎么使用vuex

1、npm install vuex --save

补充:--save和--save -dev的区别

   --save:将保存配置信息到package.json文件中的dependencies节点中,运行时依赖

   --save-dev:将保存配置信息到package.json文件中的devdependencies节点中,开发时依赖

2、导入vuex

import Vuex from 'vuex'

3、安装插件

Vue.use(Vuex)

4、创建实例

const store = new Vuex.Store({state,mutations,actions,getters
})

5、挂载到vue实例上

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

四、vue和vuex比较

 state相当于data,里面定义一些基本数据类型;

 mutations相当于methods,里面定义一些方法来操作state里面的数据;

 actions用来存放一些异步操作;

 getters里存放一些基本数据类型的派生类型,相当于computed

 modules内部仍然可以继续存放一些子store,内部再有五种属性,模块化vuex

五、vuex的五个属性

  分别为state,mutations,actions,getters,modules,一个一个介绍

5.1 state

  vuex采用单一状态树,即用一个对象表示所有的状态数据,state里面存放的数据就是基本状态数据

1、怎样获取state里面的数据呢?

  通过组件内部的computed属性获取

const store = new Vuex.Store({state: {count:0}
})
const app = new Vue({//..store,computed: {count: function(){return this.$store.state.count}},//..
})

   如果在组件中想要使用state内部的很多数据,按照上面这种写法只能一个一个定义,有啥方法可以快速批量的获取到state里的数据呢?可以使用这个方法:mapState辅助函数

2、怎么使用mapState辅助函数

上代码!

先在组件内导入

import {mapState} from 'vuex'

开始在compute内使用:

   注意这里有三种方式导入:a. count: 'count'

                                              b. count: (state) => {state.count}

                                              c. count: function(state){ return this.data + state.count}

 为啥要把箭头函数和普通函数分开,因为要是在computed里先拿到state里的数据,然后和本组件data内的数据进行一些操作,就得保证函数里的this指向

<template><div id="example"><button @click="decrement">-</button>{{count}}{{dataCount}}<button @click="increment">+</button><div>{{sex}}</div><div>{{from}}</div><div>{{myCmpted}}</div></div>
</template>
<script>
import { mapState } from 'vuex'
export default {data () {return {str: '国籍',dataCount: this.$store.state.count}},computed: mapState({count: 'count', // 第一种写法sex: (state) => state.sex, // 第二种写法from: function (state) { // 用普通函数this指向vue实例,要注意return this.str + ':' + state.from},// 注意下面的写法看起来和上面相同,事实上箭头函数的this指针并没有指向vue实例,因此不要滥用箭头函数// from: (state) => this.str + ':' + state.frommyCmpted: function () {// 这里不需要state,测试一下computed的原有用法return '测试' + this.str}}),methods: {increment () {this.$store.commit('increment')},decrement () {this.$store.commit('decrement')}},created () {// 写个定时器,发现computed依旧保持了只要内部有相关属性发生改变不管是当前实例data中的改变,还是vuex中的值改变都会触发dom和值更新setTimeout(() => {this.str = '国家'}, 1000)}
}
</script>

  这时又有一个新问题可能产生,如果原先在computed里面有其他的函数,还能直接这样computed: mapState({ })吗?可以使用对象展开符,合并computed里的函数和mapState里定义的数据

3、对象展开符

  先来说说...对象展开符

let arr = [1,2,3]
console.log(...arr) //1,2,3

 mapState是一个函数,它会返回一个对象,用...展开符就会把返回的对象一一放到computed中,与原来computed里定义的函数放在一起,也可以叫做对象混合。

//之前的computed
computed:{fn1(){ return ...},fn2(){ return ...},fn3(){ return ...}........
}
//引入mapState辅助函数之后computed:{//原来的继续保留fn1(){ return ...},fn2(){ return ...},fn3(){ return ...}......//再维护vuex...mapState({  //这里的...不是省略号了,是对象扩展符count:'count'})
}

当映射的对象名称和state里面的变量名称相同时,也可以传一个数组

computed: mapState([// 映射 this.count 为 store.state.count'count'
])

4、向state中添加删除新属性

添加必须使用

 方式一:使用Vue.set(obj,"新属性名称","对应的属性值")方式二:用新对象对就对象重新赋值   state.obj = {...state.obj, newProp: 123 }

删除必须使用

	使用“delete+某个属性”,满足不了响应式。解决办法:Vue.delete(obj,“属性名”)

5.2 mutations

  vuex中只能通过mutations唯一改变state里面的数据(若没有异步操作),mutations的第一个参数是state,第二个参数是传输过来的数据(payload),可省略。

const store = new Vuex.Store({state: {count: 1},mutations: {//无提交荷载increment(state) {state.count++}//提交荷载incrementN(state, obj) {state.count += obj.n}}
})

  组件内部

​
//无提交荷载
store.commit('increment')
//提交荷载
store.commit('incrementN', {n: 100})​

  通过this.$store.commit('事件类型’),这里的事件类型是mutations里的函数,也可以通过...mapMutations

import { mapMutations } from 'vuex'export default {//..methods: {...mapMutations(['increment' // 映射 this.increment() 为 this.$store.commit('increment')]),...mapMutations({add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')})}
}

5.3 getters

getters接收第一个参数为state,第二个参数为其他getters(可省略)

const store = new Vuex.Store({state: {count:0},getters: {// 单个参数countDouble: function(state){return state.count * 2},// 两个参数countDoubleAndDouble: function(state, getters) {return getters.countDouble * 2}}
})

 和state一样也可以在computed属性中获取到getters

const app = new Vue({//..store,computed: {count: function(){return this.$store.state.count},countDouble: function(){return this.$store.getters.countDouble},countDoubleAndDouble: function(){return this.$store.getters.countDoubleAndDouble}},//..
})

当然也可以使用...mapGetters

import { mapGetters } from 'vuex'export default {// ...computed: {// 使用对象展开运算符将 getters 混入 computed 对象中...mapGetters(['countDouble','CountDoubleAndDouble',//..])}
}

5.4 Actions

  Actions里面用于存放一些异步代码,在组件中只能先通过dispatch到actions,再在actions里commit到mutations,最后在mutations里更改state

  注意:action接受的第一个参数是context

const store = new Vuex.Store({state: {count: 0},mutations: {increment (state) {state.count++}},actions: {increment (context) {setInterval(function(){context.commit('increment')}, 1000)}}
})
store.dispatch('increment')

5.5 Modules

modules实现vuex模块化,每个模块都有自己的五种属性,甚至嵌套子模块

const moduleA = {state: { ... },mutations: { ... },actions: { ... },getters: { ... }
}const moduleB = {state: { ... },mutations: { ... },actions: { ... }
}const store = new Vuex.Store({modules: {a: moduleA,b: moduleB}
})store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态,对于模块内部的 getter,根节点状态会作为第三个参数:

const moduleA = {state: { count: 0 },mutations: {increment (state) {// state 模块的局部状态state.count++}},getters: {doubleCount (state) {return state.count * 2},sumWithRootCount (state, getters, rootState) {return state.count + rootState.count}}
}

六、为啥state里的数据可以实现响应式

class Store {constructor (options) {// this.vm  = options.state   只是单纯获取state数据,但是数据修改不会更新界面/** 借用Vue的双向绑定机制让Vuex中data变化实时更新界面 */this.vm = new _Vue({data: {state: options.state}})}
/* 类的属性访问器访问state对象时候,就直接返回响应式的数据Object.defineProperty get 同理*/get state () {return this.vm.state}
}

在data里注入state,使得可以响应式

七、为啥每个组件都可以拿到state里的数据

let Vue
const install = (_Vue) => { Vue = _Vue// 使用vue的混入方法,在创建之前,给每个组件都增加$store属性Vue.mixin({// 创建之前会被执行beforeCreate () {// 根实例有store属性if (this.$options && this.$options.store) {this.$store = this.$options.store  } else {// 根实例上没有的store属性,往父亲节点找// new Vue({store}) 这里已经在根组件挂载有store属性this.$store = this.$parent && this.$parent.$store }}})
}
export default {install // 给用户提供一个install方法,默认会被调用
}

用vue.mixin混入,在每个组件的beforeCreate生命周期函数,使得每个组件初始化时都会给自身注入一个store属性


http://chatgpt.dhexx.cn/article/utg0rc1q.shtml

相关文章

vuex的原理

1.vuex的作用 vuex是专门为Vuejs应用程序设计的状态管理工具。其实是集中的数据管理仓库。相当于数据库mongoDB等&#xff0c;任何组件都可以存取仓库中的数据。 vuex的组成部分&#xff1a; state:是存储的基本数据。mutations:提交更改数据。getter:对state加工&#xff0c…

vuex 的基本用法

一、vuex是什么&#xff1f; Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c; 这个状态管理应用包含以下几个部分&#xff1a; state&#xff0c;驱动应用的数据源&#xff1b;view&#xff0c;以声明方式将 stat…

DNS风险分析及安全防护研究(三):DNS缓存投毒及防御策略

在前面章节中&#xff0c;我们简单介绍了DNS系统在协议、软件以及结构中脆弱性&#xff0c;并对DNSSEC协议、去中心化结构等安全增强进行了讨论&#xff0c;接下来针对DNS安全所面临的外部攻击威胁和相应的防御策略做下讨论。 1.DNS缓存投毒攻击 在目前各种DNS攻击手段中&…

细说SQL注入:攻击手法与防御策略

一、 SQL注入的基本概念 &#xff08;一&#xff09;什么是SQL注入 SQL注入是一种常见的网络攻击技术&#xff0c;它允许攻击者在Web应用程序中插入并执行恶意的SQL代码。这种攻击通常针对的是数据驱动的应用程序&#xff0c;尤其是那些未对用户输入进行充分过滤和处理的应用程…

服务器被cc攻击的简单防御策略(附代码)

CC攻击&#xff08;也称为网络层攻击或流量攻击&#xff09;是指企图通过向网站或服务器发送大量伪造的请求&#xff0c;以干扰正常的用户访问的攻击。这些请求可能是来自单个设备的&#xff0c;也可能是来自一群被控制的设备的。为了防御CC攻击&#xff0c;你可以考虑使用以下…

DOS防御策略

该方法能解决一些小型服务的DOS防御问题&#xff0c;成本不高&#xff0c;能在一定程度上起到DOS防御的作用。 原本服务架构 我们的服务器向多个客户机提供服务&#xff0c;这里以腾讯云服务器为例&#xff0c;假设服务商租了一台腾讯云的服务器&#xff0c;一旦服务器收到攻击…

网络安全中的常见攻击类型和防御策略

友情链接&#xff1a;简单实用的IPAD协议框架GeWe框架 网络安全是当前互联网世界中的重要问题。本文将详细介绍常见的网络攻击类型&#xff0c;包括分布式拒绝服务攻击&#xff08;DDoS&#xff09;、SQL注入、钓鱼等&#xff0c;并提供相应的防御策略。读者将了解如何识别和应…

会话重放之防御策略、手段

目录 什么是会话重放&#xff1f; 有什么预防手段&#xff1f; 请求添加时间戳或UUID方式实现预防 什么是会话重放&#xff1f; 会话重放是一种攻击方式&#xff0c;攻击者利用先前记录的会话数据来重放或重新发送网络通信流量&#xff0c;以模拟合法用户的身份&#xff0c;…

SQL注入攻击原理及防御策略

一.什么是SQL注入 SQL注入&#xff0c;一般指web应用程序对用户输入数据的合法性没有校验或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服务器执…

安全防御策略trust-untrust-dmz(1)

策略实验 一&#xff0c;规划分析和拓扑图的搭建二&#xff0c;配置思路1&#xff0c;先配置FW000口的IP2&#xff0c;使用IP进入防火墙图形化界面&#xff0c;并且可以创建安全区域3&#xff0c;配置FW100口&#xff0c;其它同理4&#xff0c;配置AR15&#xff0c;配置SERVER2…

浅谈撞库防御策略

2014,12306遭遇撞库攻击,13万数据泄露;2015,乌云网上爆出网易邮箱过亿用户数据由于撞库泄露;数据泄露愈演愈烈,撞库登录成为网站的一大安全威胁,今天小编就和大家探讨一下如何才能够有效的防止撞库攻击。俗语知己知彼,百战不殆,小编在网上找了个撞库教程整理给大家看看…

【UTM使用_入侵防御策略】

UTM使用入侵防御策略 一、网络拓扑图 二、需求描述 外部用户在访问内部的server时启用入侵防御检查&#xff1b;入侵防御策略使用全策略&#xff1b; 三、实验步骤&#xff1a; 配置接口eth1、eth2为路由模式&#xff0c;并设置所需的IP地址 新建IP映射策略&#xff0c;…

网络防御与蓝队实践:探讨网络防御策略、入侵检测系统、安全事件响应等蓝队方面的实际案例和方法

第一章&#xff1a;引言 网络安全一直是当今信息社会中至关重要的话题。随着技术的不断发展&#xff0c;网络威胁也愈发复杂和隐匿。在这样的背景下&#xff0c;网络防御变得尤为重要&#xff0c;蓝队作为网络防御的重要一环&#xff0c;起着至关重要的作用。本文将深入探讨网…

安全世界观 | 常见WEB安全问题及防御策略汇总

1、安全世界观 继上一篇: 我用一个小小的开放设计题&#xff0c;干掉了40%的面试候选人 聊到了Web安全之后&#xff0c;好多朋友也在关注这个话题&#xff0c;今天特意再写一篇。 安全世界观一词是《白帽子讲Web安全》一书的开篇章节&#xff0c;多年后再读经典&#xff0c;仍然…

深度学习的黑魔法防御术:恶意样本(Adversarial Example) 的防御策略综述

随着深度学习&#xff08;Deep Learning&#xff09;研究的深入&#xff0c;相关应用已经在许多领域展现出惊人的表现。一方面&#xff0c;深度神经网络&#xff08;DNN&#xff09;的强大能力着实吸引着学术界和产业界的眼球。另外一方面&#xff0c;深度学习的安全问题也开始…

CC攻击原理以及如何防御策略

CC攻击原理以及如何防御策略 CC 攻击是一种 DDoS&#xff08;分布式拒绝服务&#xff09;&#xff0c;它似乎比其他 DDoS 攻击更具技术性。在这种攻击中&#xff0c;看不到假IP&#xff0c;看不到特别大的异常流量&#xff0c;但会导致服务器无法正常连接。 很多创业公司辛辛苦…

服务器安全:浏览器同源策略与跨域请求、XSS攻击原理及防御策略、如何防御CSRF攻击

主要包括 浏览器同源策略与跨域请求XSS攻击原理及防御策略如何使用SpringSecurity防御CSRF攻击CC/DDOS攻击与流量攻击什么是SSL TLS HTTPS&#xff1f; 一、浏览器的同源策略 请求方式&#xff1a;HTTP&#xff0c;HTTPS&#xff0c;Socket等 HTTP请求特点&#xff1a;无状…

常见Web安全问题及防御策略

1、安全世界观 安全世界观一词是《白帽子讲Web安全》一书的开篇章节&#xff0c;多年后再读经典&#xff0c;仍然受益匪浅! 正如开篇所说的&#xff1a;“互联网本来是安全的&#xff0c;自从有了研究安全的人&#xff0c;互联网就不安全了。” 世上没有攻不破的系统&#xff0…

基于联邦学习中毒攻击的防御策略

文章目录 联邦学习简介FL&#xff08;federal learning)和模型中毒攻击的背景针对模型中毒攻击的防御策略局部模型更新的评估方法基于光谱异常检测的方法&#xff08; Spectral Anomaly Detection Based Method&#xff09;基于真理推理的评估方法基于熵的滤波方法基于余弦相似…