vue2 组件通信

2024-09-09 06:28

本文主要是介绍vue2 组件通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

props + emits

  • props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’
  • emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新)

props检查属性

属性名类型描述默认值
typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean, Object, Array, Function, 或它们的构造函数。
defaultany / Function指定 prop 的默认值。可以是一个值,也可以是一个返回值的函数。
requiredBoolean指定 prop 是否必须传递。false
validatorFunction一个验证函数,用于更复杂的验证逻辑。函数应该返回一个布尔值,表示验证是否通过。

说明

  • type: 确保 prop 符合预期的数据类型,有助于在开发过程中捕获错误。
  • default: 当父组件没有传递相应的 prop 时,提供一个回退值,确保组件即使在没有接收到外部数据的情况下也能正常运行。
  • required: 标记为 true 时,如果父组件没有提供该 prop,Vue 会在控制台中显示警告,这有助于避免因缺少必要数据而导致的错误。
  • validator: 提供了一个更灵活的验证机制,允许开发者定义复杂的验证逻辑,确保 prop 符合特定的条件或规则。

示例

<template><div><!-- 使用对象语法统一传递多个 props <child-component v-bind="propsData"></child-component>--><child-component :size.sync="size":height="height" @my_event ="height = height + $event"></child-component>//:size.sync = :size="size" +  @update:size="size = $event"//vue3 废弃</div>
</template><script>
// 导入子组件
import ChildComponent from './ChildComponent.vue'; // 确保文件路径正确export default {data() {return {propsData: {size: 10,myMessage: "test",height: 50,age: 10}};},components: {ChildComponent // 注册子组件}
};
</script>
子–Children
<script>
export default {// props: ['size', 'myMessage'], //简易声明props: {size: Number,// 类型检查height: Number,// 类型检查 + 其他验证age: {type: Number, // 指定 prop 类型为 Numberdefault: 0,   // 如果没有提供 age,将使用默认值 0required: true, // 指定 age 必须传递validator: value => {return value > 0; // 验证 age 必须大于 0}}  },methods:{ChangeElements(){this.$emit('update:size',v);//:size.sync="size"this.$emit('my_event',v);//:height="height" @my_event ="height = height + $event"}}
}
</script>

.sync

  • 一个语法糖
  • :value.sync=‘value’ <==> :value=“calue” @update:value=“value = $event”

说明:

  1. 父组件模板:使用 v-bind 指令(或简写为 :)和对象语法来统一传递 propsData 对象中的所有属性作为 props。v-bind="propsData" 会将 propsData 对象中的所有属性作为独立的 props 传递给子组件。
  2. 父组件数据:在 data 返回的对象中定义了一个 propsData 对象,包含了所有要传递给子组件的属性。
  3. 子组件 props:子组件定义了 sizemyMessageheightage 四个 props,这些 props 用于接收从父组件传递的数据。

--------非父子通信-------

provide + inject

  • 跨层级共享数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 普通类型非响应式
  • 复杂类型响应式
  • 引用传递
<script>
export default{provide(){return{//普通类型[非响应式]age:120,//复杂类型[响应式]a:{b:2,c:3}}  }
}</script>
后代
<script>
export default{inject:['age','a'],created(){console.log(this.age,this.a);this.age = 20; //报错不可更改this.a.b = 110;//界面会响应,父类的age同步更改}
}
</script>

event bus

  • 事件总线, 在非父子组件之间通信

事件总线

//创建一个都可以访问到的事件总线(空的 Vue实例)
import Vue from 'vue'
const Bus = new Vue();
export default Bus

A组件

<script>
import Bus from 'bus地址'
export default{created(){Bus.$on('AMsg',(msg)=>{console.log(msg)}) }
}
</script>

B组件

<script>
import Bus from 'bus地址'
export default{methods:{sendAMsg(){Bus.$emit('AMsg',"你的消息")  }}
}
</script>

Vuex

  • 是什么

    • 复杂场景组件之间通信

    • vuex是vue的一个状态管理工具,状态就是数据

    • 大白话: vuex是一个插件,可以帮助我们管理 vue通用数据(多组件数据共享)

  • 场景

    • 某个状态在多个组件使用(个人信息)
    • 多个组件 共同维护 一份数据(购物车)
  • 优势

    • 数据集中化管理
    • 响应式
  • vuex遵循单向数据流

初始配置

  1. 安装 vuex

    • npm install vuex@next --save # 对于 Vue 3
    • npm install vuex --save # 对于 Vue2
  2. 新建vue模块

    • 新建store/index.js文件 专门存放 Vuex
  3. 创建仓库

    // store/index.js
    // 导入 Vuex,它是 Vuex 状态管理库的核心
    import Vuex from 'vuex';// 创建一个新的 Vuex.Store 实例
    // 这个实例将作为全局状态管理器
    export default new Vuex.Store({// 定义应用的状态(state)state: {// 一个名为 count 的状态,初始值为 0count: 0},// 定义更改状态的方法(mutations)mutations: {// increment 方法用于更新 count 状态// state 是 Vuex state 对象,v 是传递给 mutation 的参数increment(state, v) {// 将 count 状态更新为传入的参数 vstate.count = v;}},// 定义异步提交状态更改的方法(actions)actions: {// increment 方法用于异步提交 increment mutationincrement({ commit }) {// 调用之前定义的 increment mutationcommit('increment',10);}},// 定义从状态派生的状态(getters)getters: {// doubleCount 方法返回 count 的两倍// state 是 Vuex state 对象doubleCount(state) {// 返回 count 状态的两倍return state.count * 2;}}
    });
    
  4. 挂载main.js

// main.js
import Vue from 'vue';
import App from './App.vue';
import store from './store/index';// 使用 Vuex 插件
Vue.use(Vuex);new Vue({store,render: h => h(App)
}).$mount('#app');

配置项

  • new Vuex.Store({配置项})
配置项类型描述
stateObject根状态对象,包含所有的状态数据
gettersObject根getter函数,允许从state派生出一些状态
mutationsObject同步函数,用于变更state中的状态数据在 ;Vue 3 中,mutations 应改为 actionscommit,因为 Vue 3 的 Vuex 4 中不再使用 mutations
actionsObject异步操作或复杂逻辑的提交(调用mutation)的包裹函数
modulesObject命名空间模块对象,用于将store分割成模块
pluginsArray自定义插件数组,用于进一步处理 actions
strictBoolean是否开启严格模式,开启后在mutation之外修改state将抛出错误
devtoolsBoolean / Object是否启用 Vue Devtools 支持,可以传递选项对象
state
  • 根状态对象,包含所有的状态数据

  • 核心配置项(必要的)

  • 获取数据

    • 通过this.$store.属性名
    • 通过 import 导入 store 然后使用
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex); // 使用 Vuex 插件const store = new Vuex.Store({state: {count: 1},
});
getters
  • 根getter函数,允许从state派生出一些状态
  • 对数据进一步,派生状态
  • 使用
    • $store.getters.filterList()
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex); // 使用 Vuex 插件const store = new Vuex.Store({state: {list: [1,2,3,4,5,6,7,8,9]},getters:{//过滤 <= 5 的数据filterList(state){return state.list.filter(item=> item > 5)}}
});
mutations/actions
  • 用于变更state中的状态数据

  • actions:异步操作或复杂逻辑的提交(调用mutation)的包裹函数

  • Mutations:通常使用全小写字母,并且可以使用下划线来分隔单词,例如 update_count

    • 第一个参数是state也就是状态 ,通过state 来调用数据
  • Actions:可以使用驼峰命名法,并且通常在名称中包含动词,以表明它们执行的操作,例如 updateCount

    • 第一个参数是context 是上下文,和 state相似
import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex); // 使用 Vuex 插件const store = new Vuex.Store({state: {count: 10},actions: {async updateCount({ commit }, n) {commit('update_count', n);},async updateCount2(context, n) {context.commit('update_count', n);}},mutations: {//可以同名,但是不推荐update_count(state, n) {state.count = n;}}
});export default store;
modules

分模块

  • Vue 使用单一状态树,当项目比较大时,状态会集中,从而导致项目臃肿
  • 将vuex配置文件导入 根配置下的 modules 就可以了
导入模块
// store/modules/user.js
const state = { ... };
const mutations = { ... };
const actions = { ... };
const getters = { ... };export default {state,mutations,actions,getters
};
// store/index.js 根模块
import Vuex from 'vuex';
import user from './modules/user'; 
const store = new Vuex.Store({modules: {user}
});
export default store;
使用
  • 子模块state

    • $store.state.模块名.属性名
    • mapState映射:
      mapState('模块名',['属性名']);
      this.属性名 就可以访问数据了
  • 子模块getters

    • $store.getters['模块名/属性名称']
    • mapGetters映射:
      mapGeters(‘模块名’,[‘属性名’,‘属性2’])
      this.属性名 就可以获得数据
    • 模块名/属性名称:是因为命名是时候就是这命名的
  • 子模块mutations

    • $store.commit['模块名/属性名称']
    • mapMutations映射:
      mapMutations(‘模块名’,[‘函数名’,‘函数2’])
      this.函数名() 就可以调用函数了
    • 模块名/属性名称:是因为命名是时候就是这命名的
  • 子模块actions

    • $store.dispatch['模块名/属性名称']

    • mapActions映射:
      mapActions(‘模块名’,[‘函数名’,‘函数名2’])

      this.函数名() 就可以调用函数了

    • 模块名/属性名称:是因为命名是时候就是这命名的

数据的更改

  • this.$emit() 是 Vue 组件中用来触发自定义事件的方法。当调用 this.$emit('eventName', param) 时,它会向父组件发出一个事件,父组件可以监听这个事件并做出响应。
  • 同步:
    • 而在 Vuex 中,this.$store.commit('mutationName', param) 用于触发状态变更。这里的 commit 方法用于调用 store 中定义的 mutations,mutations 是同步函数,用于更改 store 中的状态(state)。
  • 异步:
    • this.$store.dispatch('actionName', payload) 来分发 actions。这会告诉 Vuex 执行相应的 action 函数。

辅助函数

mapState
  • 将store中的数据,自动映射到 组件的 计算属性中
  • 可以直接this.属性名 来访问数据
//引入mapState
import { mapState } from 'vuex';//使用
export default {computed: {// 使用对象展开运算符将所有映射的状态转为计算属性...mapState([// 映射 this.count 为 store.state.count'count']),// 映射 this.doubleCount 为 store.getters.doubleCount...mapState({'doubleCount': state => state.count * 2})}
}
//-------------------
computed:{ ...mapState['状态名'] }
//# 等价
computed:{ '状态名'(){return this.$store.state.count
}}
mapMutatuons
  • 将mutations同步函数 中的方法,映射到 methods
  • 可以直接this.函数名(n) 来调用函数
//引入 mapMutatuons
import {mapMutatuons} from 'vuex'
//使用
export default {methods: {...mapMutations(['update_count' // 直接使用 mutation 名称]),...mapMutations({'set_count': 'update_count' // 为 mutation 提供一个别名}),increment() {this.update_count(1); // 调用 Vuex store 的 mutation},decrement() {this.set_count(-1); // 使用别名调用 mutation}}
}
//---------------------------------
methods:{...mapMutations(['方法名'])  
}//等价
methods:{'方法名'(参数){this.$store.commit('方法名',参数)}
}
mapActions
  • 将actions异步操作中的方法,映射到 methods
  • 可以直接this.函数名(n) 来调用函数
//导入mapActions
import { mapActions } from 'vuex';//使用
export default {methods: {...mapActions(['UpdateCount' // 将 `this.update_count` 映射为 `this.$store.update_count('actionName',obj)`]),...mapActions({'mappedActionName': 'UpdateCount' // 将 `this.mappedActionName` 映射为 `this.$store.dispatch('update_count')`}),}
}
//--------------------
methods:{..,mapActions([方法名])
}
# 等价
methods:{'方法名'(参数){this.$store.dispatch('方法名',参数)}
}
mapGetters
  • 将getters中的函数 中的方法,映射到 computed
  • 可以直接this.函数名(n) 来调用函数
示例
<template></template>
<script>
import {mapState,mapMutations,MapActions,MapGetters} form 'vuex'
export default{name:'test',computed:{...mapState(['count']),...maoGetters(['filterList'])},methods:{...mapMutations('updata_count'),...MapActions('UpdataCount')}
}
</script>

$refs获取dom

  • ref和$refs
  • 获取dom元素组件实例
    • ref和$refs=> 当前组件内 (更精确)
    • document => 当前页 (范围广)
  • 和 id 的用法相似
<template><div ref="MyDom" id="MyDom"></div><TestEl ref="MyEl"></TestEl></template><script>
export default{mounted(){// dom元素this.$ref.MyDom//等价document.getElementById('myDom')//组件实例let vm = this.$ref.MyElvm.get_methods();//可以调用TestEl里面的数据},components:{TestEl}}</script>

$nextTick异步跟新

  • Vue采用的是异步跟新
<template><div><div v-if="isShow" ref="_1"> ...  </div><div v-else ref="_2"> ...  </div></div>
</template><script>export default{data(){return {isShow:true}},methods:{change(){this.isShow = false;this.$ref._2.focus();//警告this.$ref._2为 undefined//因为采用的是异步跟新,所以当前还没有跟新 _2这个元素this.$nextTick(()=>{ //当异步跟新完成后的回调this.$ref._2.focus();})//可以的}}}
</script>

这篇关于vue2 组件通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1150414

相关文章

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

HTML中meta标签的常见使用案例(示例详解)

《HTML中meta标签的常见使用案例(示例详解)》HTMLmeta标签用于提供文档元数据,涵盖字符编码、SEO优化、社交媒体集成、移动设备适配、浏览器控制及安全隐私设置,优化页面显示与搜索引擎索引... 目录html中meta标签的常见使用案例一、基础功能二、搜索引擎优化(seo)三、社交媒体集成四、移动

HTML input 标签示例详解

《HTMLinput标签示例详解》input标签主要用于接收用户的输入,随type属性值的不同,变换其具体功能,本文通过实例图文并茂的形式给大家介绍HTMLinput标签,感兴趣的朋友一... 目录通用属性输入框单行文本输入框 text密码输入框 password数字输入框 number电子邮件输入编程框

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

HTML5 中的<button>标签用法和特征

《HTML5中的<button>标签用法和特征》在HTML5中,button标签用于定义一个可点击的按钮,它是创建交互式网页的重要元素之一,本文将深入解析HTML5中的button标签,详细介绍其属... 目录引言<button> 标签的基本用法<button> 标签的属性typevaluedisabled

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

CSS place-items: center解析与用法详解

《CSSplace-items:center解析与用法详解》place-items:center;是一个强大的CSS简写属性,用于同时控制网格(Grid)和弹性盒(Flexbox)... place-items: center; 是一个强大的 css 简写属性,用于同时控制 网格(Grid) 和 弹性盒(F

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求