Vue2.0 多种组件传值方法-不过如此的 Vuex
码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14404397.html
在vue项目中了解组件间通讯很重要,也是最基础的面试题,可以大致总结为以下几种情况和方法:
一、父向子传值
父 to 子
:通过动态绑定属性
的方式,子组件在props
中去接收,占为已用
// father.vue
<child :name="name" />
data() {
return {
name:'Echoyya',
}
}
// child.vue
export default {
props: ['name'],
mounted() {
console.log(this.name) // Echoyya
}
}
二、子向父传值 - 1. 事件分发 emit
子 to 父
:通过.emit('事件名称', 传递的参数)事件分发
的方式, 父组件当中,调用子组件标签上绑定自定义事件,其中包含一个参数
,即子组件传递过来的数据
emit 只能接受两个参数,其余不生效,第一个参数:事件名称,第二个: 传递的数据
事件分发,不一定要通过点击事件,也可使用钩子函数等
需要传递多个参数时,emit第二个参数可选择数组或是对象
// father.vue
<child @send="getChildData" />
methods: {
getChildData(data){
console.log('子组件传递过来的数据:' + data);
}
}
// child.vue
<button @click="send">发送数据</button>
export default {
data() {
return {
year:2021
};
},
methods:{
send(){
this.$emit('send',this.year)
}
}
};
三、子向父传值 - 2. 父组件动态绑定方法
除了平时常见的emit 事件分发的方式实现子向父传值,还有一种不太常见的方式
在前面有提到过,父向子传值可以通过在标签上动态绑定属性的方式,同样也可以
动态绑定方法
,在子组件props
中接收在根据实际情况,在子组件中调用该方法,并传值,此时父组件执行对应的方法及参数的处理,该参数便是子向父传递的数据
// father.vue
<child :fn="getChildData" />
methods: {
getChildData(data){ // 子组件传递过来的数据
console.log(data); // 子组件 - 2021
}
}
// child.vue
export default {
props: ['fn'],
mounted(){
this.fn('子组件 - 2021')
}
};
四、(主动)父组件主动获取子组件的数据和方法
父组件中调用子组件,绑定一个
ref
属性主动获取属性:
this.$refs.ref名称.属性
主动调用方法:
this.$refs.ref名称.方法()
// father.vue
<child :name="name" ref="child" />
mounted() {
console.log(this.$refs.child.year); // 2021
this.$refs.child.showName() // Echoyya:2021
}
// child.vue
export default {
data(){
return {
year:2021
}
},
methods:{
showName(){
console.log('Echoyya:'+ this.year);
}
}
};
五、(主动)子组件主动获取父组件的数据和方法
子组件中调用父组件,使用
this.$parent
主动获取属性:
this.$parent.属性
主动调用方法:
this.$parent.方法()
,还可以向父组件传递参数
// father.vue
<div id="app">
<child />
</div>
<script>
import child from "./components/child";
export default {
components: {
child
},
data() {
return {
name:'Echoyya',
};
},
methods: {
parentMethod(data){
// 可以接收子组件调用时传递的参数
console.log(data); // 2021
}
}
};
</script>
// child.vue
export default {
mounted(){
console.log(this.$parent.name); // Echoyya
this.$parent.parentMethod(2021); // 2021
}
};
六、EventBus 传值
多层级组件之间相互传值,或兄弟组件之间传值,通常使用EventBus
,实际上就是 vm,即 Vue 的实例,通过发布订阅者模式,实现任意两组件之间的通讯,父子亦可。
首先创建EventBus文件,导出vm 实例
在需要通讯的两组件中分别引入该文件
通过发布订阅
.$emit
和.$on
实现传值 ,操作的事件名需相同。
// EventBus.js
import Vue from 'vue'
var vm = new Vue()
export default vm
// App.vue
<template>
<div id="app">
<bus-one />
<bus-two />
</div>
</template>
<script>
import busOne from "./components/bus1";
import busTwo from "./components/bus2";
export default {
components: {
busOne,
busTwo
}
}
</script>
// bus1.vue
<template>
<div>
组件 1 发布
<button @click="sendNum">通讯发送数据</button>
</div>
</template>
<script>
import eb from "../EventBus";
export default {
methods:{
sendNum(){
eb.$emit('sendData',111)
}
}
};
</script>
// bus2.vue
<template>
<div>
组件 2 订阅
</div>
</template>
<script>
import eb from "../EventBus";
export default {
created(){
eb.$on('sendData',function(data){
console.log(data); // 111
})
}
};
</script>
EventBus 内部实现原理
手动模拟一个 EventBus,实现发布订阅的效果,创建一个 myEventBus 文件
创建一个对象,分别设置发布、订阅的事件,以及事件存储的对象,通过事件订阅将事件存储至事件对象中,
事件发布时,自动调用事件对象中相同 key 的所有事件
myEventBus.html
<script>
var eventbus = {
fnObj:{
//abc:[fn1,fn2], 可以多次订阅同一个事件,因此每个 key 对应一个数组
},
$on: function (id, fn) {
if(!this.fnObj[id]){
this.fnObj[id] = [fn]
}else{
this.fnObj[id].push(fn)
}
},
$emit: function (id, data) {
if(this.fnObj[id]){
var fnArr = this.fnObj[id]
// 当事件触发时,循环执行每个 key 对应的 所有function
for(var i = 0;i<fnArr.length;i++){
var fn = fnArr[i]
fn(data)
}
}else{
console.log('异常,函数不存在')
}
}
}
eventbus.$on('abc',function(data){
console.log(1)
})
eventbus.$on('abc',function(data){
console.log(2)
})
eventbus.$on('abc',function(data){
console.log(3)
})
eventbus.$on('abc',function(data){
console.log(4)
})
eventbus.$emit('abc','123')
</script>
不过如此的 Vuex
Vuex 应用程序开发的 状态管理模式,集中式管理应用所有组件的状态,进行组件通讯
安装插件,引入 Vuex,创建 store 实例,配置到 Vue 实例中
为防止状态,方法声明等过分重复和冗余,Vuex 提供了一些辅助函数,
mapState
,mapGetters
,mapMutations
,mapActions
,可使用扩展运算符展开,其中:mapState
,mapGetters
声明在 computed 中mapMutations
,mapActions
声明在 methods 中
创建 store 实例,核心属性:
State
:一个对象,包含全部的应用状态。作为唯一数据源
存在。store实例会注入到根组件下的所有子组件Getters
:state 中数据派生出一些状态类似计算属性,返回值会根据它的依赖被缓存起来,只有依赖发生改变时才会被重新计算,state 作为其第一个参数.Mutations
:更改 store 中的状态,store.commit('事件名',payload参数可选)
触发,只做同步操作,Actions
:类似于Mutations, 提交的是 mutation,而不是直接变更状态,可以包含任意异步操作。this.$store.dispatch
分发,异步执行完毕,返回封装的promise 对象。接受一个与 store 实例具有相同方法和属性的对象Modules
:为防止 store 对象过于复杂,可将其分割成模块,每个模块都有自己的State,Getters,Mutations,Actions,甚至可以嵌套子模块
// main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex'
import numModule from './numModule.js'
Vue.use(Vuex)
var store = new Vuex.Store({
modules:{
numModule
}
})
new Vue({
store,
render: h => h(App)
}).$mount('#app')
// numModule.js
export default {
state: {
num: 1
},
getters: {
getNum(state) { // 可以返回一些派生状态
return state.num
}
},
mutations: {
// 同步修改状态的函数
changeNum(state, payload) {
state.num += payload.num
},
// 异步时,开发工具会遗漏快照,不便于调试(不推荐)
testAsync(state, data) {
// 模拟服务器获取数据
setTimeout(function () {
state.num += data
}, 0)
}
},
actions: {
// 异步获取数据,提交给 mutation 进行修改
incNumByService(store) {
setTimeout(function () {
var serviceData = 0.1
store.commit('changeNum', {
num: serviceData
})
}, 0)
}
}
}
// App.vue
<template>
<div id="app">
第一组件
<p>state:{{$store.state.numModule.num}}</p>
<!-- getters:方式为只读,数据更安全 -->
<p>getters:{{$store.getters.getNum}}</p>
<p>MapGetters:{{gn}}</p>
<button @click="changeNum">mutation同步</button>
<button @click="testAsync">mutation异步</button>
<button @click="testActions">action异步</button>
<Son />
</div>
</template>
<script>
import { mapGetters } from "vuex";
import Son from "./components/son";
export default {
components: {
Son
},
methods: {
changeNum() {
this.$store.commit({
type: "changeNum",
num: 1
});
//效果同上
// this.$store.commit("changeNum",{
// num: 1
// });
},
testAsync() {
this.$store.commit("testAsync", 10);
},
testActions() {
// dispatch 异步执行完毕,返回 封装的promise 对象
this.$store.dispatch("incNumByService").then(res => {
alert("dispatch执行完毕");
});
}
},
computed: {
//使用对象展开运算符将 getter 混入 computed 对象中
//如果想将一个 getter 属性另取一个名字,使用对象形式:
...mapGetters({
gn: "getNum" // 把 `this.gn` 映射为 `this.$store.getters.getNum`
})
}
};
</script>
// Son.vue
<template>
<div class="hello">
第二组件
<button>state:{{$store.state.numModule.num}}</button>
<!-- getters:方式为只读,数据更安全 -->
<button>getters:{{$store.getters.getNum}}</button>
<button @click="clickMe">MapGetters:{{gn}}</button>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
computed: {
...mapGetters({
gn: "getNum"
})
}
};
</script>
Vue2.0 多种组件传值方法-不过如此的 Vuex的更多相关文章
- vue.js+koa2项目实战(五)axios 及 vue2.0 子组件和父组件之间的传值
axios 用法: 1.安装 npm install axios --save-dev 2.导入 import axios from 'axios'; 3.使用 axios.post(url,para ...
- 手把手教你撸个vue2.0弹窗组件
手把手教你撸个vue2.0弹窗组件 在开始之前需要了解一下开发vue插件的前置知识,推荐先看一下vue官网的插件介绍 预览地址 http://haogewudi.me/kiko/inde... 源码地 ...
- vue2.0父子组件通信的方法
vue2.0组件通信方法:props传值和emit监听.(.sync方法已经移除.详情请点击)(dispatch-和-broadcast方法也已经废弃) props方法传值:Props 现在只能单项传 ...
- vue2.0 子组件和父组件之间的传值(转载)
Vue是一个轻量级的渐进式框架,对于它的一些特性和优点在此就不做赘述,本篇文章主要来探讨一下Vue子父组件通信的问题 首先我们先搭好开发环境,我们首先得装好git和npm这两个工具(如果有不清楚的同学 ...
- Vue2.0 子组件和父组件之间的传值
Vue是一个轻量级的渐进式框架,对于它的一些特性和优点在此就不做赘述,本篇文章主要来探讨一下Vue子父组件通信的问题 首先我们先搭好开发环境,我们首先得装好git和npm这两个工具(如果有不清楚的同学 ...
- vue2.0 子组件 父组件之间的传值
常用的子组件给父组件传值/调父组件方法 //子组件let val = "";//可以是任意类型this.$emit('fatherFun', val); //父组件<fath ...
- vue2.0 父子组件数据传递prop
vue的一个核心概念就是组件,而组件实例的作用域是孤立的,所以组件之间是不能直接引用其他组件的数据的.极端点举例来说,就是可以在同一个项目中,每一个组件内都可以定义相同名称的数据. data () { ...
- 基于vue2.0前端组件库element中 el-form表单 自定义验证填坑
eleme写的基于vue2.0的前端组件库: http://element.eleme.io 我在平时使用过程中,遇到的问题. 自定义表单验证出坑: 1: validate/resetFields 未 ...
- vue2.0父子组件之间通信
父组件是通过props属性给子组件通信的来看下代码: 父组件: <parent> <child :child-com="content"></chil ...
随机推荐
- MySQL中UPDATE语句里SET后使用AND的执行过程和结果分析
使用SQL中的UPDATE关键字更新多个字段值时,SET后面的更新字段应该使用逗号而不能用AND.虽然用AND不会报错,但会使更新结果错误,下面我将通过场景来分析当我们使用AND时SQL的执行过程和为 ...
- Scrapy——將爬取圖片下載到本地
1. Spider程序: 1 import scrapy, json 2 from UnsplashImageSpider.items import ImageItem 3 4 class Unspl ...
- tcpdump 参数详解及使用案例
参数 -A 以ASCII码方式显示每一个数据包(不会显示数据包中链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据(nt: 即Handy for capturing web pages ...
- 从零开始学Java (三)基础语法
1. 基本数据类型 整数类型:byte,short,int,long 浮点数类型:float,double 字符类型:char 布尔类型:boolean java最小单位是bit,一个byte占用8个 ...
- poj 2112 最优挤奶方案
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 16550 Accepted: 5945 ...
- IDEA中jdk设置
电脑运行环境是8, 但是IDEA提醒说1.5已经过时,IDEA中jdk设置还是比较麻烦 https://blog.csdn.net/u012365843/article/details/8138883 ...
- Python3 如何查看内置函数都有哪些?
数据科学交流群,群号:189158789,欢迎各位对数据科学感兴趣的小伙伴的加入! 上代码: 1 import builtins 2 num = len(dir(builtins)) 3 print( ...
- Poem 01(转)
Dear Sunshine The way you glow through my blinds in the morning. It makes me feel like you missed me ...
- Spring 启动脚本
if [ $# != 3 ];then echo 'option-1: start,stop or restart.' echo 'option-2: 请传入jar路径' echo 'option-3 ...
- linux(5)查看历史命令执行记录history
前言 我们每次敲打linux命令的时候,有时候想用之前用过的命令,一般情况下,我们都会按↑↓箭头来寻找历史的命令记录,那如果我想用1天前执行的某条命令,难道还要按↑100次?显示这样是不现实的,我们可 ...