vue/react 组件子父之间的数据传递,事件传递

应用场景

  1. 一个单组件 拆分成三个组件 a,b,c
  2. c组件负责整体页面, 是a ,b的父组件 a,b是同级的两个组件
  3. a点击按钮 ,要实现b的缩放
  4. 缩放之间 依靠一个 boolen型的变量 collapse

父组件将数据传递给子组件

确保 a,b绑定通相同 ,变量同步

  • 父组件中
data(){
	return{
		collapse:false
	}
},
components:{
    a,b
  },

c 的页面中定义 :子组件变量名=“绑定的父组件变量名” (动态绑定)

<a :collapse="collapse"></a>
<b :collapse="collapse"></b>
  • 子组件中 在props中 声明要接收的变量 ,然后可作为data中的变量直接使用
props:{
    collapse:Boolean
  },
  <div  v-if="!collapse"></div>
此时a 建立方法 点击 只有本地值发生变化, 要想能够同步
  1. 在父组件中 创建能够改变变量 collapse 的方法 ,由a去调用c的方法 ,从而使得全局a,b,c,的变量改变,达到a控制b的效果 (父向子传递事件)
  2. a去改变c(父组件)的值,从而实现全局的变量改变 (子向父传值)

1 父向子传递事件

  • 父组件中
    定义的事件
methods: {
    toShrink(){
      this.collapse=true;
    }toRecover(){
      this.collapse=false;
    }
}

页面中 @子组件接收的事件名=父组件中要传递的事件”

<a :collapse="collapse" @fatherToShark="toShrink" @fatherToRecover="toRecover"></a>
<b :collapse="collapse" @fatherToShark="toShrink" @fatherToRecover="toRecover"></b>
  • 子组件中:在自定义的事件中调用父组件的事件
 <span @click="recover"><i class="el-icon-s-unfold"> </i></span>
 methods:{
    shrink(){
      this.$emit("fatherToShark");
    },
    recover(){
      this.$emit("fatherToRecover");
    },
  }

子向父传值

利用自组件调用父组件事件(事件中 形参给数据赋值 在子组件调用中,形参为自己的数据)

methods:{
    test(count){
    this.count=count
  }
}

<a @aa="test"> </a>  // 注意此处父组件方法 test不能写为test()

子组件

data(){
	return{
		countChild:100
	}
}
methods:{
	testChild(){
	this.$emit('aa',this.countChild)
}

}

使用第三方插件 pubsub-js

使用此插件可在任意子父兄关系之间来回传递值

接受者:
导入插件

import  PubSub from  'pubsub-js'

订阅消息 在页面初始化完成后调用

npm install pubsub-js --save
create(){
	this.token = PubSub.subscribe('my_msg'(订阅消息名称),(_(订阅消息名称 ,可用形参接收 此处不需要 用——占位),stateObj(发送方传递的数据))=>{
            this.data.***=stateObj.***
		})

token是这个订阅的标识 用于再组件结束时 关闭此订阅
}
beforeDestroy(){
	PubSub.unsubscribe(this.token)
}

发送方:

import PubSub from 'pubsub-js'

得到数据后 发布将消息发布

PubSub.publish('my_msg',{users:res.data.***,isLoding:false})

由原来的兄弟组件之间的数据传递 要将数据放到父组件 改为 直接通过消息订阅发布 数据直接放入使用方

react同理

例 搜索框Search搜索 List结果展示:

App.jsx

import React, { Component } from 'react'
import Search from './components/Search'
import List from './components/List'

export default class App extends Component {
	render() {
		return (
			<div className="container">
				<Search/>
				<List/>
			</div>
		)
	}
}

Search

import React, { Component } from 'react';
import axios from 'axios'
import PubSub from 'pubsub-js'

class Search extends Component {
    search=()=>{
        const {keyWordElement:{value:key}} =this
    
        axios.get(`http://localhost:3000/search/users?q=${key}`).then(
            res=>{
                PubSub.publish('my_msg',{users:res.data.items,isLoding:false})
           },
           err=>{
            PubSub.publish('my_msg',{err:err.message,isLoding:false})
        }
        )
    }
    render() {
        return (
            <div>
                 <section className="jumbotron">
                 
                        <input type="text" placeholder="enter the name you search" ref={c=>this.keyWordElement=c}/>&nbsp;<button onClick={this.search}>Search</button>
                    </section>
            </div>
        );
    }
}

export default Search;

List

import React, { Component } from 'react'
import PubSub from 'pubsub-js'
import './index.css'

export default class List extends Component {

	state = { //初始化状态
		users:[], //users初始值为数组
		isFirst:true, //是否为第一次打开页面
		isLoading:false,//标识是否处于加载中
		err:'',//存储请求相关的错误信息
	} 

	componentDidMount(){
		this.token = PubSub.subscribe('my_msg',(_,stateObj)=>{
			this.setState(stateObj)
		})
	}

	componentWillUnmount(){
		PubSub.unsubscribe(this.token)
	}

	render() {
		const {users,isFirst,isLoading,err} = this.state
		return (
			<div className="row">
				{
					isFirst ? <h2>欢迎使用,输入关键字,随后点击搜索</h2> :
					isLoading ? <h2>Loading......</h2> :
					err ? <h2 style={{color:'red'}}>{err}</h2> :
					users.map((userObj)=>{
						return (
							<div key={userObj.id} className="card">
								<a rel="noreferrer" href={userObj.html_url} target="_blank">
									<img alt="head_portrait" src={userObj.avatar_url} style={{width:'100px'}}/>
								</a>
								<p className="card-text">{userObj.login}</p>
							</div>
						)
					})
				}
			</div>
		)
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值