大家好,都吃晚饭了吗?我是Kaiqisan,是一个已经走出社恐的一般生徒,今天还是说说Taro的一些东西

之前在写项目的时候试图修改某个块的样式,首先想到的就是使用ref来获取DOM节点修改,但想想使用DOM修改样式是最nc最消耗性能的,于是我就直接使用了state参数来修改.

后来,回过头来想重新来学下ref的使用方法,于是有了今天的博客

本篇博客素材来自官网 Refs 引用

Ref其实有多种引用方法,其实最简单的就是直接引用,就和vue一样,直接引用,直接使用
(代码是ts,如果您是js选手请手动过滤掉多余部分)

  • 方法一:直接引用法

type PageOwnProps = {}

type PageState = {
    // num: number
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

interface Index {
    props: IProps;
}

@connect(({counter}) => ({
    counter
}), (dispatch) => ({
    add() {
        dispatch(add())
    },
    dec() {
        dispatch(minus())
    },
    asyncAdd() {
        dispatch(asyncAdd())
    }
}))
class Index extends Component<IProps, PageState> {
    constructor(props) {
        super(props);
        this.state = {
            // num: 10
        };
        this.comp = {}
    }

    componentDidMount(): void {
        console.log(this.refs.demoDOM);
    }

    render() {
        return (
            <View className='index'>
                <View className='demoDOM' ref='demoDOM'>内容</View>
            </View>
        );
    }
}

其实核心部分的代码就是这两个部分

<View className='demoDOM' ref='demoDOM'>内容</View>
console.log(this.refs.demoDOM);

这样就可以直接获取想要的节点的DOM信息了

PS:由于Taro能够实现多端打包,所以,对于小程序和H5两个端,它们获取到的元素是不同的,如果您使用TS来书写代码的话,需要格外注意这一点,因为不同的端获取到的DOM元素的数据类型并不相同,在小程序端获取到的就是wx.createSeletorQuery获取到的小程序原生的组件,如果在H5端,获取到的就是@tarojs/components 的组件实例。

如果您有多端打包的需求,请这么写

if (process.env.TARO_ENV === 'weapp') {
	// 小程序端
} else if (process.env.TARO_ENV === 'h5') {
	// 网页端
}
  • 方法二:函数创建法

type PageStateProps = {
    counter: {
        num: number
    }
}

type PageDispatchProps = {
    add: () => void
    dec: () => void
    asyncAdd: () => any
}

type PageOwnProps = {}

type PageState = {
    // num: number
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

interface Index {
    props: IProps;
}

@connect(({counter}) => ({
    counter
}), (dispatch) => ({
    add() {
        dispatch(add())
    },
    dec() {
        dispatch(minus())
    },
    asyncAdd() {
        dispatch(asyncAdd())
    }
}))
class Index extends Component<IProps, PageState> {
    constructor(props) {
        super(props);
        this.state = {
            // num: 10
        };
    }

    componentDidMount(): void {
        console.log(this.comp); // 输出一个组件的所有信息,可以使用这个方法实现父子组件的传值。
    }
	
	comp: Comp;
	refComp= (node) => this.comp = node

    render() {
        return (
            <View className='index'>
                <Comp ref={this.refComp} />
            </View>
        );
    }
}

type CompState = {
    // num: number
}

class Comp extends Component<IProps, CompState> {
    constructor(props) {
        super(props);
        this.state = {
            // num: 10
        }
    }

    render() {
        return <View className='app'>dd</View>;
    }
}

东西有点多了,咱接着简化一下!只看重点部分!

  • 首先是ref元素的注册部分
comp: Comp; // ts语法,声明部分,js直接写一个comp就可以了
refComp= (node) => this.comp = node // 待传给子组件的函数,希望子组件执行
  • 应用部分
<CompDemo2 ref={this.comp} num2={10}/>
  • 组件部分
// 就是一个正常的组件
class Comp extends Component<IProps, CompState> {
    constructor(props) {
        super(props);
        this.state = {
            // num: 10
        }
    }

	getNum(): number {
		return 10
	}

    render() {
        return <View className='app'>dd</View>;
    }
}

这样,我们就把子组件里面的所有信息都传入参数comp,获得了以下结果

在这里插入图片描述
所以,我们就可以肆无忌惮地从子组件获取信息了

  • 方法三:使用useRef创建一个ref实例(官网说使用createRef 但是似乎不能使用)

function Comp() {
    const el = useRef(null);

    let getInfo = () => {
        console.log(el);
    };

    return <View>
        <Input onClick={getInfo} ref={el} />
    </View>
}

注意点

userRef以及上面的第二种方法只能在子组件是class组件和原生DOM中使用,子组件是函数式组件是不能用的。因为写过ts的都知道,这个ref其实它的数据类型以及定好了,对象内部有什么什么属性,而函数式组件并没有继承React.Component所以没有生命周期,props, state, ref(这个是主要原因)啥的,所以只能适用于DOM元素或class子组件。

Logo

前往低代码交流专区

更多推荐