Vue通信、传值的多种方式,详解

Vue通信、传值的多种方式,详解

转自:https://blog.csdn.net/qq_35430000/article/details/79291287

 

一、通过路由带参数进行传值

①两个组件 A和B,A组件通过query把orderId传递给B组件(触发事件可以是点击事件、钩子函数等)

this.$router.push({ path: '/conponentsB', query: { orderId: 123 } }) // 跳转到B

②在B组件中获取A组件传递过来的参数

this.$route.query.orderId

 

二、通过设置 Session Storage缓存的形式进行传递

①两个组件A和B,在A组件中设置缓存orderData

  1. const orderData = { 'orderId': 123, 'price': 88 }
  2. sessionStorage.setItem('缓存名称', JSON.stringify(orderData))

 

②B组件就可以获取在A中设置的缓存了

const dataB = JSON.parse(sessionStorage.getItem('缓存名称'))

此时 dataB 就是数据 orderData

朋友们可以百度下 Session Storage(程序退出销毁) 和 Local Storage(长期保存) 的区别。

三、父子组件之间的传值

(一)父组件往子组件传值props

①定义父组件,父组件传递 number这个数值给子组件,如果传递的参数很多,推荐使用json数组{}的形式

②定义子组件,子组件通过 props方法获取父组件传递过来的值。props中可以定义能接收的数据类型,如果不符合会报错。

③假如接收的参数 是动态的,比如 input输入的内容 v-model的形式

注意:传递的参数名称不识别驼峰命名,推荐使用横杠-命名

④父子组件传值,数据是异步请求,有可能数据渲染时报错

原因:异步请求时,数据还没有获取到但是此时已经渲染节点了

解决方案:可以在 父组件需要传递数据的节点加上  v-if = false,异步请求获取数据后,v-if = true

(二)、子组件往父组件传值,通过emit事件

四、不同组件之间传值,通过eventBus(小项目少页面用eventBus,大项目多页面使用 vuex)

①定义一个新的vue实例专门用于传递数据,并导出

②定义传递的方法名和传输内容,点击事件或钩子函数触发eventBus.emit事件

③接收传递过来的数据

注意:enentBus是一个另一个新的Vue实例,区分两个this所代表得vue实例

五、vuex进行传值

为什么使用vuex?

vuex主要是是做数据交互,父子组件传值可以很容易办到,但是兄弟组件间传值(兄弟组件下又有父子组件),或者大型spa单页面框架项目,页面多并且一层嵌套一层的传值,异常麻烦,用vuex来维护共有的状态或数据会显得得心应手。

需求:两个组件A和B,vuex维护的公共数据是 餐馆的名称 resturantName,默认餐馆名称是 飞歌餐馆,那么现在A和B页面显示的就是飞歌餐馆。如果A修改餐馆名称 为 A餐馆,则B页面显示的将会是 A餐馆,反之B修改同理。这就是vuex维护公共状态或数据的魅力,在一个地方修改了数据,在这个项目的其他页面都会变成这个数据。

         

①使用 vue-cli脚手架工具创建一个工程项目,工程目录,创建组件A和组件B路由如下:

路由如下:

  1. import Vue from 'vue'
  2. import Router from 'vue-router'
  3. import componentsA from '@/components/componentsA'
  4. import componentsB from '@/components/componentsB'
  5. Vue.use(Router)
  6. export default new Router({
  7. mode: 'history',
  8. routes: [
  9. {
  10. path: '/',
  11. name: 'componentsA',
  12. component: componentsA
  13. },
  14. {
  15. path: '/componentsA',
  16. name: 'componentsA',
  17. component: componentsA
  18. },
  19. {
  20. path: '/componentsB',
  21. name: 'componentsB',
  22. component: componentsB
  23. }
  24. ]
  25. })

app.vue

  1. <template>
  2. <div id="app">
  3. <router-view/>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'App'
  9. }
  10. </script>
  11. <style>
  12. #app {
  13. font-family: 'Avenir', Helvetica, Arial, sans-serif;
  14. -webkit-font-smoothing: antialiased;
  15. -moz-osx-font-smoothing: grayscale;
  16. text-align: center;
  17. color: #2c3e50;
  18. margin-top: 60px;
  19. }
  20. </style>

②开始使用vuex,新建一个 sotre文件夹,分开维护 actions mutations getters

②在store/index.js文件中新建vuex 的store实例

*as的意思是 导入这个文件里面的所有内容,就不用一个个实例来导入了。

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. import * as getters from './getters' // 导入响应的模块,*相当于引入了这个组件下所有导出的事例
  4. import * as actions from './actions'
  5. import * as mutations from './mutations'
  6. Vue.use(Vuex)
  7. // 首先声明一个需要全局维护的状态 state,比如 我这里举例的resturantName
  8. const state = {
  9. resturantName: '飞歌餐馆' // 默认值
  10. // id: xxx 如果还有全局状态也可以在这里添加
  11. // name:xxx
  12. }
  13. // 注册上面引入的各大模块
  14. const store = new Vuex.Store({
  15. state, // 共同维护的一个状态,state里面可以是很多个全局状态
  16. getters, // 获取数据并渲染
  17. actions, // 数据的异步操作
  18. mutations // 处理数据的唯一途径,state的改变或赋值只能在这里
  19. })
  20. export default store // 导出store并在 main.js中引用注册。

③actions

  1. // 给action注册事件处理函数。当这个函数被触发时候,将状态提交到mutations中处理
  2. export function modifyAName({commit}, name) { // commit 提交;name即为点击后传递过来的参数,此时是 'A餐馆'
  3. return commit ('modifyAName', name)
  4. }
  5. export function modifyBName({commit}, name) {
  6. return commit ('modifyBName', name)
  7. }
  8. // ES6精简写法
  9. // export const modifyAName = ({commit},name) => commit('modifyAName', name)

④mutations

  1. // 提交 mutations是更改Vuex状态的唯一合法方法
  2. export const modifyAName = (state, name) => { // A组件点击更改餐馆名称为 A餐馆
  3. state.resturantName = name // 把方法传递过来的参数,赋值给state中的resturantName
  4. }
  5. export const modifyBName = (state, name) => { // B组件点击更改餐馆名称为 B餐馆
  6. state.resturantName = name
  7. }

⑤getters

  1. // 获取最终的状态信息
  2. export const resturantName = state => state.resturantName

⑥在main.js中导入 store实例

  1. // The Vue build version to load with the `import` command
  2. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
  3. import Vue from 'vue'
  4. import App from './App'
  5. import router from './router'
  6. import store from './store'
  7. Vue.config.productionTip = false
  8. /* eslint-disable no-new */
  9. new Vue({
  10. el: '#app',
  11. router,
  12. store, // 这样就能全局使用vuex了
  13. components: { App },
  14. template: '<App/>'
  15. })

 

④在组件A中,定义点击事件,点击 修改 餐馆的名称,并把餐馆的名称在事件中用参数进行传递。

 

...mapactions 和 ...mapgetters都是vuex提供的语法糖,在底层已经封装好了,拿来就能用,简化了很多操作。

其中...mapActions(['clickAFn']) 相当于this.$store.dispatch('clickAFn',{参数}),mapActions中只需要指定方法名即可,参数省略。

...mapGetters(['resturantName'])相当于this.$store.getters.resturantName

  1. <template>
  2. <div class="componentsA">
  3. <P class="title">组件A</P>
  4. <P class="titleName">餐馆名称:{{resturantName}}</P>
  5. <div>
  6. <!-- 点击修改 为 A 餐馆 -->
  7. <button class="btn" @click="modifyAName('A餐馆')">修改为A餐馆</button>
  8. </div>
  9. <div class="marTop">
  10. <button class="btn" @click="trunToB">跳转到B页面</button>
  11. </div>
  12. </div>
  13. </template>
  14. <script>
  15. import {mapActions, mapGetters} from 'vuex'
  16. export default {
  17. name: 'A',
  18. data () {
  19. return {
  20. }
  21. },
  22. methods:{
  23. ...mapActions( // 语法糖
  24. ['modifyAName'] // 相当于this.$store.dispatch('modifyName'),提交这个方法
  25. ),
  26. trunToB () {
  27. this.$router.push({path: '/componentsB'}) // 路由跳转到B
  28. }
  29. },
  30. computed: {
  31. ...mapGetters(['resturantName']) // 动态计算属性,相当于this.$store.getters.resturantName
  32. }
  33. }
  34. </script>
  35. <!-- Add "scoped" attribute to limit CSS to this component only -->
  36. <style scoped>
  37. .title,.titleName{
  38. color: blue;
  39. font-size: 20px;
  40. }
  41. .btn{
  42. width: 160px;
  43. height: 40px;
  44. background-color: blue;
  45. border: none;
  46. outline: none;
  47. color: #ffffff;
  48. border-radius: 4px;
  49. }
  50. .marTop{
  51. margin-top: 20px;
  52. }
  53. </style>

    B组件同理

  1. <template>
  2. <div class="componentsB">
  3. <P class="title">组件B</P>
  4. <P class="titleName">餐馆名称:{{resturantName}}</P>
  5. <div>
  6. <!-- 点击修改 为 B 餐馆 -->
  7. <button class="btn" @click="modifyBName('B餐馆')">修改为B餐馆</button>
  8. </div>
  9. <div class="marTop">
  10. <button class="btn" @click="trunToA">跳转到A页面</button>
  11. </div>
  12. </div>
  13. </template>
  14. <script>
  15. import {mapActions, mapGetters} from 'vuex'
  16. export default {
  17. name: 'B',
  18. data () {
  19. return {
  20. }
  21. },
  22. methods:{
  23. ...mapActions( // 语法糖
  24. ['modifyBName'] // 相当于this.$store.dispatch('modifyName'),提交这个方法
  25. ),
  26. trunToA () {
  27. this.$router.push({path: '/componentsA'}) // 路由跳转到A
  28. }
  29. },
  30. computed: {
  31. ...mapGetters(['resturantName']) // 动态计算属性,相当于this.$store.getters.resturantName
  32. }
  33. }
  34. </script>
  35. <!-- Add "scoped" attribute to limit CSS to this component only -->
  36. <style scoped>
  37. .title,.titleName{
  38. color: red;
  39. font-size: 20px;
  40. }
  41. .btn{
  42. width: 160px;
  43. height: 40px;
  44. background-color: red;
  45. border: none;
  46. outline: none;
  47. color: #ffffff;
  48. border-radius: 4px;
  49. }
  50. .marTop{
  51. margin-top: 20px;
  52. }
  53. </style>

最后:本文完全手打,如需转载请注明出处,谢谢,如果不明白的地方欢迎给我留言哦。

github项目仓库地址:https://github.com/byla678/vuexdemo.git

转载于:https://www.cnblogs.com/whyuyan/p/9672177.html

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

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

相关文章

python 文件读写(追加、覆盖)

很明了的一个常用参数图标&#xff1a; 更像细的一个参数说明&#xff1a; 由于文件读写时都有可能产生IOError&#xff0c;一旦出错&#xff0c;后面的f.close()就不会调用。所以&#xff0c;为了保证无论是否出错都能正确地关闭文件&#xff0c;我们可以使用try ... finally来…

前端知识点总结

1、DOM结构 —— 两个节点之间可能存在哪些关系以及如何在节点之间任意移动。(通俗易懂的来讲讲DOM、两个节点之间可能存在哪些关系以及如何在节点之间任意移动) DOM: Document Object Module, 文档对象模型。 节点的关系:父(parent)、子(child)和同胞(sibling)等节…

Python爬虫自学之第(①)篇——爬虫伪装和反“反爬”

有些网站是防爬虫的。其实事实是&#xff0c;凡是有一定规模的网站&#xff0c;大公司的网站&#xff0c;或是盈利性质比较强的网站&#xff0c;都是有高级的防爬措施的。总的来说有两种反爬策略&#xff0c;要么验证身份&#xff0c;把虫子踩死在门口&#xff1b;要么在网站植…

Spring 事务相关及@Transactional的使用建议

使用步骤&#xff1a; 步骤一、在spring配置文件中引入<tx:>命名空间<beans xmlns"http://www.springframework.org/schema/beans" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns:tx"http://www.springframework.org/schema/…

谷歌浏览器安装Vue Devtools插件(国内的谷歌浏览器如何安装插件)

分享给大家一个谷歌插件网站&#xff0c;适合国内谷歌浏览器无法安装插件的问题&#xff0c;你懂的 点击这里下载Vue.js Devtools插件&#xff0c; 喜欢的可以收藏这个插件资源网站&#xff0c;分享给大家 第一步&#xff1a;下载后解压获得CRX文件&#xff0c;如下图 第二步…

MySQL操作权限整理

用户权限管理主要有以下作用&#xff1a; 1. 可以限制用户访问哪些库、哪些表 2. 可以限制用户对哪些表执行SELECT、CREATE、DELETE、DELETE、ALTER等操作 3. 可以限制用户登录的IP或域名 4. 可以限制用户自己的权限是否可以授权给别的用户 一、用户授权 mysql> grant a…

vue报错 TypeError: merge is not a function

利用ncu -u升级去年的vue项目package.json里的所有依赖&#xff0c;目的是想增删改它去做另一个项目&#xff0c; 却发生了这样一个错误&#xff1a;&#xff08;如下&#xff09; 查找问题原因&#xff1a; 这是webpack配置中区分环境配置文件中的插件webpack-merge的报错&a…

Invalid options object. Copy Plugin has been initialized using an options object that does not match

报错&#xff1a; 报错文件和代码&#xff1a;查看了官网也没有看出所以然&#xff0c;最后在npm官网上找打了原因 错误配置&#xff1a; 怎么看都没有错误 最后参看一下这个npn官网找打了原因&#xff0c;地址&#xff1a;https://www.npmjs.com/package/copy-webpack-plugin …

后台返回数据打印是[object object]的,报错:SyntaxError: JSON.parse: expected property name or ‘}‘ at line 1 column

今天基于这个问题纠结了一下午&#xff0c;导致这个问题的坑也是挺深的&#xff0c;查找问题最好是从这条数据的存储开始查找 问题1&#xff1a;先确定后台接收数据后存储到数据库里有没有自动转义特殊字符&#xff0c;比如 原始数据是&#xff1a;[{"user_id":20,…

Java开发框架和中间件面试题(4)

27.如何自定义Spring Boot Starter&#xff1f; 1.实现功能 2.添加Properties 3.添加AutoConfiguration 4.添加spring.factory 在META INF下创建spring.factory文件 6.install 28.为什么需要spring boot maven plugin? spring boot maven plugin 提供了一些像jar一样打包…

第二周每周例行报告

1.本周PSP 类型任务开始时间结束时间间隔时间净时间准备工作复习C#&#xff0c;看书2018.9.19 17&#xff1a;032018.9.19 18&#xff1a;17 0min74min编程编写功能一2018.9.20 18&#xff1a;072018.9.20 22&#xff1a;4323min253min编程完善修改功能一2018.9.21…

poj 1083 Moving Tables

题目 两种做法&#xff0c;开始用贪心做的&#xff0c;有种情况没考虑到&#xff0c;结果排序错了。 这个例子&#xff0c;感觉上有三个交点&#xff0c;以为是30&#xff0c;其实是20. 贪心代码&#xff1a; #include <iostream> #include <cstdio> #include <…

oracle parallel_index hint在非分区表的生效

之前没特别注意&#xff0c;在有些场景下希望使用并行索引扫描的时候&#xff0c;发现parallel_index hint并没有生效&#xff0c;于是抽空看了下文档&#xff1a;The PARALLEL_INDEX hint instructs the optimizer to use the specified number of concurrent servers to para…

eclipse 界面设置与字体更改

目录 eclipse 界面设置与字体更改更改界面颜色&#xff08;Windows&#xff09;windows下全设置窗口颜色eclipse下设置Console窗口颜色设置字体与字号安装Courier New字体设置字体eclipse 界面设置与字体更改 每天换一个新的环境总是要重新设置eclipse的各种配置&#xff0c;最…

HTTP和HTTPS协议及工作原理分析

HTTP协议概念 HTTP协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff0c;属于应用层&#xff09;是用于从服务器传输超内容到本地浏览器的传送协议。是一个无状态的协议 想了解http&#xff0c;就需要了解TCP&#xff0c;IP协议。因为http是基…

前端兼容性问题

一、CSS 1、浏览器的兼容性问题-CSS 盒子模型(Box Model) 一旦为页面设置了恰当的 DTD&#xff0c;大多数浏览器都会按照上面的图示来呈现内容。然而 IE 5 和 6 的呈现却是不正确的。根据 W3C 的规范&#xff0c;元素内容占据的空间是由 width 属性设置的&#xff0c;而内容周…

索引原理及几种索引类型区别

在关系数据库中&#xff0c;索引是一种单独的、物理的对数据库表中的一列或多列的值进行排序的一种存储结构&#xff0c; 它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录&#xff0c;可以根据目录中的页码…

Android Studio Intent使用(显式、隐式)

https://blog.csdn.net/u012005313/article/details/47006689 使用Intent能够使程序在不同活动中跳转&#xff0c;意及能够使用不同界面。Intent用法分为显示和隐式 Intent概念&#xff1a;Intent是Android程序中各组件之间进行交互的一种重要方式&#xff0c;不仅可以指明当前…

淘宝首页的HTML以及CSS技术点

1、 一个网页的开发流程 内容结构&#xff0c;比如js、css页面结构。自上而下&#xff0c;从左往右。&#xff08;内容、颜色块、间距、边框&#xff09; 2、 line-height的5种设置方式及区别 normal || 1.5 || 150% || 50px || 5em 初始化元素的时候&#xff0c;一般使用 l…

Windows+Python 3.6环境下安装PyQt4

第一步&#xff1a;下载.whl&#xff0c;地址&#xff1a;https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyqt4&#xff0c;这里可以下载不同的python版本对应的包。 第二步&#xff1a;选择一个目录&#xff0c;将下载好的文件放到该目录下&#xff0c;然后cmd下&#xff0c;c…