8.vue和react一起学 (*^_^*)

11 篇文章 0 订阅

嵌套逐级传递props的场景&refs

  1. 嵌套逐级传递props的场景
    以组件为单元开发的react和vue都存在嵌套逐级传递props的场景。但它们在简化这种复杂场景的方法有不同。
  2. refs
    react与vue都有引用的概念,其用法有不同。

react

  1. 嵌套逐级传递props的场景
    react解决嵌套逐级传递props的场景采用最外层创建context的方法结合发布订阅的设计模式。
    所有包含在发布者(provider)内的订阅者(consumer)在发布的数据源变化时,都能够重新渲染ui界面。
    从创建context到使用context数据。涉及到四个api,分别是:React.createContext、、MyContext.Provider、MyContext.Consumer、MyContext.displayName。具体看以下demo。

// src\ctx-refs\ctx.js

import React from "react";

// 只有在未提供Provider时,默认值才会生效
// 此处可以注释掉MyContext.Provider尝试默认值
const MyContext = React.createContext(2);

// 类似于vue选项name,此处也要给Context一个名字以区分调试
MyContext.displayName = "Count";

class Son extends React.Component{
    static contextType = MyContext;
    render(){
        // 生命周期rende函数ctx指向的数据能够相应变化
        console.log(this.context)
        return(<MyContext.Consumer>
            {value => <span>{ value }</span>}
        </MyContext.Consumer>)
    }
}

function Father(props) {
return(<div>{props.children}</div>)
}

function Home() {
     return(<Father><Son/></Father>)
}

export default class Demo extends React.Component{
    state = {
        value: 1
    }
    render() {
        let { value } = this.state
        return(<div>
             <button onClick={()=>{this.setState({value: ++value})}}>改变最上层ctx数据</button>
            <MyContext.Provider value = {value}>
                <Home/>
            </MyContext.Provider>
        </div>)
    }
}

图1-1为Context在react-devtooll展示名:
在这里插入图片描述

图1-1
  1. refs
    react中的ref通过api创建,然后绑定到对应组件或dom上,多层组件还有传递ref这一说。详细请看以下demo。
import React from "react";
class Son extends React.Component {
    state = {
        age:1
    }

    grow = () => {
        let { age } = this.state;
        this.setState({age: ++age})
    }

    render(){
        const { age } = this.state;
        const { forwardedRef } = this.props;
        return(
        <>
        <div>Son, age: { age }</div>
        <GrandSon ref = {forwardedRef} />
        </>
        )
    }
}


class GrandSon extends Son {
    render(){
        const { age } = this.state;
        return(
        <div>GrandSon, age: { age }</div>
        )
    }
}

const refSon = React.createRef();
const refGrandSon = React.createRef();
export default class Father extends React.Component {
    render(){
        return(<div>
            <button onClick = {() => {refSon.current.grow()}}>养育儿子</button>
            <button onClick = {() => {refGrandSon.current.grow()}}>养育孙子</button>
            {/* ref为绑定ref, forwardedRef为传递给子组件ref */}
            <Son ref = {refSon} forwardedRef = {refGrandSon}></Son>
        </div>)
    }
}

Vue

  1. 嵌套逐级传递props的场景
    render函数写法可以避免出现逐级传递props,因为所有的createElement都能直接访问顶层组件的作用域,也就是tempalte里面无限组件插槽嵌套。想想就觉得恐怖。如下面的写法,实际上我也只是在GrandSon上直接访问顶层组件传递了一次props,没有经过Son。
//函数式组件、render写法
import Vue from "vue";
let _c = Vue.extend.bind(Vue);
const Son = _c({
    render(h){
        return h("div", ["儿子", this.$slots.default])
    }
});
const GrandSon = _c({
    render(h){
        return h("div", ["孙子", this.customProps])
    },
    props:["customProps"]
});
const Container = _c({
    // functional: true,
    // render(h,ctx){
    //     return h(Son, ctx.data, [h(GrandSon, ctx.data)])
    // }
    // or
    render(h){
        return h(Son, {nativeOn:{click:()=>{++this.customProps}}},[h(GrandSon,{props:{customProps:this.customProps}})])
    },
    data(){
        return{
            customProps:1
        }
    }
})

export default Container

vue还可以通过$attrs传递中间组件未接受使用的属性到更深的组件:

<template>
    <div>
        <Son v-bind="$attrs" />
    </div>
</template>
<script>
import Vue from "vue";
Vue.component("Son",{
    render(h) {
        return h("div",["子组件"])
    },
    mounted(){
        console.log(this.customProps)
        console.log(this.$attrs)
    },
    props:["customProps"]
})
export default {
    data(){
        return{}
    }
}
</script>
  1. refs
    vue的ref就很简单了
<template>
    <div>
        <Son ref="son" />
    </div>
</template>
<script>
mounted(){
// 内部子组件不用通过父组件为其转发ref。直接通过逐级访问ref就能访问到内部组件的引用。
	console.log(this.$refs["son"])
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值