当前位置: 首页 > news >正文

【Vue】如何使用vuex解决兄弟组件传值?

目录

 vuex全局数据管理

vuex介绍

组件关系和通信方案

vuex使用场景

vuex使用流程

vuex核心概念-state

getters派生状态(计算属性)

vuex核心概念-Mutations

vuex辅助函数-mapState

vuex核心概念actions

actions介绍

vuex核心概念modules

使用modules语法如下

访问数据和修改数据的调整

mapState的其他用法

Vuex-辅助函数mapState对数据重命名

Vuex-map函数用法汇总

vuex使用总结


vuex全局数据管理

vuex作用:实现所有组件间的数据共享

vuex介绍

组件关系和通信方案

序号组件关系数据通信
1父子关系子传父:$emit ; 父传子:props
2非父子关系eventBus: $on + $emit
3非父子关系vuex

和父子通信和兄弟通信类似,vuex也是一种组件通信解决方案

  • 1.vuex的作用是解决多组件状态共享的问题,在大型的项目中,组件通讯会变得很混乱,使用vuex可以统一管理组件之间的通讯

    • 它是独立于组件而单独存在的,所有的组件都可以把它当作一座桥梁来进行通讯。

  • 2.使用vuex好处

    • 响应式 : 只要vuex中的数据变化,对应的组件会自动更新(类似于vue数据驱动)

    • 操作更简洁 : 类似于sessionStorage,只有几个方法

vuex使用场景

实际开发中,组件传值大多数情况下还是使用 父子组件传值

少部分情况下会用vuex. (数据需要在非常多的页面使用,比如用户头像,好几个页面都要显示那种)

  • 1.不是所有的场景都适用于vuex,只有在必要的时候才使用vuex,如果不必要,尽量别用

    • 使用了vuex之后,会一定程度上增加了项目的复杂度

  • 2.适合使用vuex场景

    • 这个数据需要在很多个地方使用,如果采用组件传值方式,写起来很麻烦,而且多个地方都要写

      • 例如:用户信息(姓名,头像),可能会在很多个地方使用(个人页面,评论页面等)

  • 3.不适合使用vuex场景

    • 这个数据不需要多个地方使用,如果某个数据仅仅只是在两个组件之间通讯,优先使用props或$emit

  • 4.vuex特点

    • (1)所有组件数据共享

    • (2)响应式: 一旦vuex数据修改,所有使用的地方都会自动更新

vuex使用流程

使用步骤:

  1. vue-cli中整合==(如果使用vue ui创建创建,直接勾选vuex,会自动帮我们完成配置)==

    1. vue add vuex

      1. 如果提示,选择y

      2. 创建了/src/store/index.js

      3. main.js导入并挂载到Vue实例上

    2. state中定义数据

  2. 任意组件中

    1. this.$store.state.xxx即可取值改值

    2. template中可以不用写this

    3. 可以通过计算属性简化编码

  3. .js文件中

    1. 导入store对象即可获取属性

注意:

  1. vue-cli创建的项目中如何整合vuex

    1. vue add vuex

  2. vuex的数据定义在哪里?

    1. state

  3. 组件中如何获取vuex中的数据?

    1. this.$store.state.xxx

    2. html结构中this可以省略

vuex核心概念-state

state作用: 存储公共数据

getters派生状态(计算属性)

语法如下:

1.现在getters中声明一个计算属性

new Vuex.store({
  // 省略其他...
  getters: {
    // state 就是上边定义的公共数据state
    计算属性名: function(state) {
      return 要返回的值
    }
  }
})

2.使用getter中的计算属性

$store.getters.getter的名字

vuex核心概念-Mutations

1.Mutation作用:更新state中的数据

  • 疑问?: 既然可以直接通过this.$store.state来修改,为什么不能这么写呢?

  • 原因: 在组件中直接state,我们的vue tools不会追踪数据的修改,这样不便于维护(不知道这个全局数据什么时候被修改了,再加上vuex是全局响应式的,一旦修改所有使用的地方全部修改。非常不便于维护)

    • 另外:在严格模式下,直接修改state会报错

2.Mutation语法如下:

分两个格式: 注册的格式,调用的格式

定义格式: 如下

定义格式**: 如下new Vue.store({
  // 省略其他...
  mutations:{
    // 每一项都是一个函数,可以声明两个形参
  	mutation名1:function(state [, 载荷]) {
  
  },
    mutation名2:function(state [, 载荷]) {

    },
}
})

每一项都是一个函数,可以声明两个形参:

  • 第一个参数是必须的,表示当前的state。在使用时不需要传入

  • 第二个参数是可选的,表示载荷,是可选的。在使用时要传入的数据

    • 专业术语载荷:表示额外的参数

使用格式 :

this.$store.commit('mutation名', 载荷实参 )

这个事件名就是Mutation中的函数名。(类似于$emit的一种事件通知机制)

问:为啥是$store.commit('mutations的名字')而不是$store.mutations的名字()?

答:Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。

问:数据不可以该在组件内部直接修改吗?

答:不能。虽然语法上不报错,也有响应式的特点。但是不推荐。特别是在严格模式下会报错。若将vue创建 store 的时候传入 strict: true, 开启严格模式,那么任何修改state的操作,只要不经过 mutation的函数,vue就会报错

问:可以传递多个数据吗?

答:参数只能有一个:下面的写法是不对的:

this.$store.commit('setUser', name, age) // age这个参数将无法被接收到 

如果希望传递复杂的数据,第二个参数可以是对象,例如下面的写法

this.$store.commit('setUser', { name, age} )

vuex辅助函数-mapState

1.mapState作用: 将vuex中的数据映射到组件的计算属性

  • 我们在组件中访问vuex数据,需要通过this.$store.state.属性名,单词太常,写起来很麻烦。

  • 通过mapState函数,可以在组件中直接通过this.属性名来访问vuex中的数据

2.mapState语法

💎在要使用的组件中导入mapState辅助函数: import { mapState } from 'vuex'

💎在这个组件的computeds中来映射计算属性

export default {
  name: "my",
  computed:{
    //计算属性
    //2.将vuex中的user映射成计算属性(与下面代码完全等价)
    ...mapState(['user'])

    //计算属性:本质还是访问vuex中的数据
    // user(){
    //   return this.$store.state.user
    // }
  }
};

...mapState( ['属性名a' , '属性名b'] )

这行代码相当于自动帮你生成一个对应的计算属性 属性名(){ return this.$store.state.属性名 }

vuex核心概念actions

actions介绍

  • 1.actions与mutations相同点 :都是修改state数据

  • 2.actions与mutations不同点

    • mutations:同步更新

    • actions: 异步更新(例如你的数据来源于ajax)

为什么要有actions, 假如你有一个数据,需要通过ajax请求来获取。然后你想存入vuex,应该怎么做?

方案一:

1.在组件的created钩子中发送ajax请求

2.服务器响应数据之后,调用$store.commit()提交给mutations更新(手动挡)

方案二:

1.直接在actions中发送ajax请求

2.actions会自动帮你把数据提交到mutations更新(自动挡)

你会选择手动更新?还是自动更新呢?

一定要记住:只有你的ajax数据需要存入vuex,才需要在actions中发送ajax请求。 如果不想存入vuex,还是在组件的created钩子中发送。(vuex说:你又不用我,你想干啥与我何干?)

actions语法如下:

(1)定义格式

  • 这个地方的载荷一般为ajax接口需要的参数,如果没有就不用传

new Vuex.store({
  // 省略其他...
  actions: {
    // context对象会自动传入,它与store实例具有相同的方法和属性
    action的名字: function(context, 载荷) {
      // 1. 发异步请求, 请求数据
      
      // 2. commit调用mutation来修改数据
      
      // context.commit('mutation名', 载荷)
    }
  }
})

(2)调用格式

  • 在组件中通过this.$store.dispatch('actions的名字', 参数)来调用action

vuex核心概念modules

modules作用:模块化处理vuex数据

为什么要有vuex? 假设你的项目非常的复杂,分为四个大模块:首页、个人中心、订单列表、设置中心

每一个模块有10个数据需要使用vuex,那么你的vuex的state中就需要声明40个属性。(是不是非常麻烦呢?)

  • 当vuex中需要存储的数据很多的时候,就需要使用moudles进行模块化处理

    • 一般实际开发中moudles使用不多哈。 只有那种特别复杂,庞大的项目才可能用到

使用modules语法如下

export default new Vuex.Store({
  // state: 用来保存所有的公共数据
  state: {},
  getters: {},
  mutations: {},
  actions: {},
  modules: {
  	模块名1: {
    		// namespaced为true,则在使用mutations时,就必须要加上模块名
      	namespaced: true, 
  		  state: {},
  			getters: {},
  			mutations: {},
  			actions: {},
  			modules: {}
  	},
    模块名2: {
        // namespaced不写,默认为false,则在使用mutations时,不需要加模块名
  		  state: {},
  			getters: {},
  			mutations: {},
  			actions: {},
         modules: {}
  	}  
  }
})

访问数据和修改数据的调整

访问模块中的数据,要加上模块名

获取数据项:  {{$store.state.模块名.数据项名}}
获取getters: {{$store.getters['模块名/getters名']}}

访问模块中的mutations/actions:

  • 如果namespaced为true,则需要额外去补充模块名

  • 如果namespaced为false,则不需要额外补充模块名

$store.commit('mutations名')        // namespaced为false
$store.commit('模块名/mutations名')  // namespaced为true

mapState的其他用法

mapState只是起到简化代码作用,实际开发中这是可选的。

用 或 不用,对我们使用vuex没有影响

Vuex-辅助函数mapState对数据重命名

场景

vuex中的数据与本组件内的数据名相同

格式

...mapState({'新名字': 'xxx'})

Vuex-map函数用法汇总

如何使用全局state

  • 直接使用: this.$store.state.xxx;

  • map辅助函数:

computed: { 
  ...mapState(['xxx']), 
  ...mapState({'新名字': 'xxx'})
}

如何使用modules中的state

  • 直接使用: this.$store.state.模块名.xxx;

  • map辅助函数:

computed: { 
  ...mapGetters(['xxx']), 
  ...mapGetters({'新名字': 'xxx'})
}

vuex使用总结

 

相关文章:

  • CDH 08Cloudera Manager freeIPAKerberos安装配置(markdown新版)
  • 给你一个购物车模块,你会如何设计测试用例?【测试用例设计】
  • steam搬砖汇率差项目详解
  • NodeJS 环境准备
  • RestFul风格
  • git提交代码版本冲突问题
  • 交换机与路由技术-29-OSPF虚链路
  • Centos6普通用户获取最高权限方法
  • 极致CMS1.7 另一处前台SQL注入
  • 基于javaweb,ssm鲜花销售系统
  • 数据结构与算法:大小根堆和快速排序 解决TopK问题
  • 【ArkUI】对于Flex布局与基础组件声明式UI-组件封装父子组件相互绑定的运用【OpenHarmony/HarmonyOS】
  • java基于ssm+vue的企业通用进销存管理系统 element
  • K8S搭建
  • Python之简单飞机行李托运计费系统
  • Centos6.8 使用rpm安装mysql5.7
  • ECS应用管理最佳实践
  • github从入门到放弃(1)
  • HTML-表单
  • Linux CTF 逆向入门
  • SpiderData 2019年2月13日 DApp数据排行榜
  • TCP拥塞控制
  • vue--为什么data属性必须是一个函数
  • 服务器之间,相同帐号,实现免密钥登录
  • 聊一聊前端的监控
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • Spring Batch JSON 支持
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • #1014 : Trie树
  • (2)(2.10) LTM telemetry
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • ***利用Ms05002溢出找“肉鸡
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .jks文件(JAVA KeyStore)
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .net 设置默认首页
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET多线程执行函数
  • .net和php怎么连接,php和apache之间如何连接
  • @JsonSerialize注解的使用
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [ 攻防演练演示篇 ] 利用通达OA 文件上传漏洞上传webshell获取主机权限
  • [AIGC 大数据基础]hive浅谈
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)
  • [C#][opencvsharp]opencvsharp sift和surf特征点匹配
  • [EFI]MSI GF63 Thin 9SCXR电脑 Hackintosh 黑苹果efi引导文件
  • [HAOI2016]食物链
  • [IE技巧] 如何关闭Windows Server版IE的安全限制