我说这是全网最全vue组件通信方式

我说这是全网最全vue组件通信方式,第1张

prop

event

style和class

natvie修饰符

$listeners

v-model

sync修饰符

$parent 和 $children

$slots 和 $scopedSlots

ref

最常见的组件通信方式,由父组件向子组件传递。prop可接收一个数组或对象

子组件向父组件发送通知,并传递参数

子组件

父组件

父组件可以向子组件传递style 和 class ,style 和 class将合并到子组件根元素

父组件

子组件

最终渲染结果

父组件在使用子组件时,在子组件上定义一些属性,这些属性将作用于子组件的根元素上,但是不包括style和class

父组件

子组件

最终渲染结果

Tip:子组件可以通过定义 inheritAttrs:false 来紧张 attribute 附着在子组件根元素上 但不影响通过 $attrs 获取数据

在注册事件时,父组件可以通过 navite 修饰符,将事件注册到子组件根元素上

父组件

子组件

子组件可以通过 $listeners 获取父组件传递过来的所有处理函数

父组件在使用子组件时,可以在子组件上绑定v-model,子组件通过定义model的prop和event还获取父组件定义的值

父组件

<compn v-model=" "datas" />

子组件

和 v-model类似,用于双向数据绑定,不同点在于 v-model只能针对一个数据进行绑定,而 sync 修饰符没有限制

子组件

父组件

在组件内部,可以通过$parent 和$children属性,分别获取当前组件的父组件和子组件实例

ref

在使用组件时,可以通过在组件上定义ref来获取组件实例

provide和inject 可以实现深层组件通信,顶层组件只需定义provide,底层组件通过inject接受数据

顶层组件

如果一个组将改变了地址栏,所有监听地址栏的组将都会做出相应的改变,

vuex 过于笨重,通常不建议在小型项目中使用,小型项目可以使用store 或 eventbus代替vuex,vuex本质上就是一个数据仓库。在此不做过多赘述,先挖一个坑,下回再叙。

store模式其实就是一个普通的js模块,各组件可以导入该模块,将数据放到data里面,此时store就具有响应式了。

tip: store模式的缺点是无法跟踪数据的改变,因为所有组件都可以更改数据

一、选取 DOM 元素

在 jQuery 中,我们已经熟悉了使用 sizzle 选择器来完成 DOM 元素的选取。而在 React 中,我们可以使用 ref 来更有针对性的获取元素。

import React from 'react';class Demo extends ReactCompoent {

getDomNode() { return thisrefsroot; // 获取 Dom Node }

render() { return ( <div ref="root">just a

demo</div> ); }}

这是最简单的获取 node 的方式,如果有多层结构嵌套呢?没有关系。

import React from 'react';class Demo extends ReactCompoent {

getRootNode() { return thisrefsroot; // 获取根节点 Dom Node }

getLeafNode() { return thisrefsleaf; // 获取叶节点 Dom Node }

render() { return ( <div ref="root">

<div ref="leaf">just a demo</div>

</div> ); }}

如果是组件和组件嵌套呢?也没关系,父组件仍然可以拿到子组件的根节点。

import React from 'react';import ReactDOM from 'react-dom';class Sub

extends ReactCompoent { render() { return (

<div>a sub component</div> ); }}class Demo extends

ReactCompoent { getDomNode() { return thisrefsroot; // 获取

Dom Node } getSubNode() { return

ReactDOMfindDOMNode(thisrefssub); // 获取子组件根节点 } render() {

return ( <div ref="root"> <Sub

ref="sub" /> </div> ); }}

上面使用了比较易懂的 API 来解释 Ref 的用法,但里面包含了一些现在 React 不太推荐和即将废弃的方法,如果用 React 推荐的写法,我们可以这样写。

import React from 'react';import ReactDOM from 'react-dom';class Sub

extends ReactCompoent { getDomNode() { return thisrootNode;

} render() { return ( <div ref={(c) =>

thisrootNode = c}>a sub component</div> ); }}class

Demo extends ReactCompoent { getDomNode() { return

thisrootNode; // 获取 Dom Node } getSubNode() { return

thissubgetDomNode(); // 获取子组件根节点 } render() { return (

<div ref={(c) => thisrootNode = c}>

<Sub ref={(c) => thissub = c} /> </div>

); }}

有人可能会问,那子组件怎么拿父组件的 Dom Node 呢,从 React

的单向数据流角度出发,遇到这种情况我们应该通过回调通知给父组件,再由父组件自行判断如何修改 Node,其实父组件拿子组件的 Node

情况也很少,大多数情况下我们是通过 props 传递变化给子组件,获取子组件

Node,更多的情况下是为了避开大量重新渲染去修改一些Node的属性(比如 scrollLeft)。

二、DOM *** 作

jQuery 中提供了丰富的 *** 作方法,但一个个 *** 作 DOM 元素有的时候真的很烦人并且容易出错。React 通过数据驱动的思想,通过改变 view 对应的数据,轻松实现 DOM 的增删 *** 作。

class Demo extends ReactCompoent { constructor(props) {

super(props); thisstate = { list: [1, 2, 3],

}; thisaddItemFromBottom = thisaddItemFromBottombind(this);

thisaddItemFromTop = thisaddItemFromTopbind(this);

thisdeleteItem = thisdeleteItembind(this); }

addItemFromBottom() { thissetState({ list:

thisstatelistconcat([4]), }); } addItemFromTop() {

thissetState({ list: [0]concat(thisstatelist),

}); } deleteItem() { const newList =

[thisstatelist]; newListpop(); thissetState({

list: newList, }); } render() { return (

<div> {thisstatelistmap((item) =>

<div>{item}</div>)} <button

onClick={thisaddItemFromBottom}>尾部插入 Dom 元素</button>

<button onClick={thisaddItemFromTop}>头部插入 Dom

元素</button> <button

onClick={thisdeleteItem}>删除 Dom 元素</button>

</div> ); }} 三、事件的监听

React 通过根节点代理的方式,实现了一套很优雅的事件监听方案,在组件 unmount 时也不需要自己去处理内存回收相关的问题,非常的方便。

import React from 'react';class Demo extends ReactComponent {

constructor(props) { super(props); thishandleClick =

thishandleClickbind(this); } handleClick() {

alert('我是d窗'); } render() { return ( <div

onClick={thishandleClick}>点击我d出d框</div> ); }}

这里有一个小细节就是

bind 的时机,bind 是为了保持相应函数的上下文,虽然也可以在 onClick 那里 bind,但这里选择在 constructor 里

bind 是因为前者会在每次 render 的时候都进行一次 bind,返回一个新函数,是比较消耗性能的做法。

React 的事件监听,毕竟只能监听至 root component,而我们在很多时候要去监听 window/document 上的事件,如果

resize、scroll,还有一些 React 处理不好的事件,比如

scroll,这些都需要我们自己来解决。事件监听为了屏蔽差异性需要做很多的工作,这里像大家推荐一个第三方库来完成这部分的工作,

add-dom-event-listener ,用法和原生的稍有区别,是因为这个库并不旨在做 polyfill,但用法还是很简单。

var addEventListener = require('add-dom-event-listener');var handler =

addEventListener(documentbody, 'click', function(e){

consolelog(etarget); // works for ie consolelog(enativeEvent); //

native dom event});handlerremove(); // detach event listener

另一个选择是 bean ,达到了 IE6+ 级别的兼容性。

四、事件的触发

和事件监听一样,无论是 Dom 事件还是自定义事件,都有很优秀的第三方库帮我们去处理,如果是 DOM 事件,推荐 bean ,如果是自定义事件的话,推荐 PubSubJS 。

五、documentready

React

作为一个 view 层框架,通常情况下页面只有一个用于渲染 React 页面组件的根节点 div,因此

documentready,只需把脚本放在这个 div 后面执行即可。而对于渲染完成后的回调,我们可以使用 React 提供的

componentDidMount 生命周期。

import React from 'react';class Demo

extends ReactComponent { constructor(props) { super(props);

} componentDidMount() { doSomethingAfterRender(); //

在组件渲染完成后执行一些 *** 作,如远程获取数据,检测 DOM 变化等。 } render() { return (

<div>just a demo</div> ); }} 六、attr 方法

jQuery 使用 attr 方法,获取 Dom 元素的属性。在 React 中也可以配合 Ref 直接读取 DOM 元素的属性。

import React from 'react';class Demo extends ReactComponent {

constructor(props) { super(props); }

componentDidMount() { thisrootNodescrollLeft = 10; //

渲染后将外层的滚动调至 10px } render() { return ( <div

ref={(c) => thisrootNode = c}

style={{ width: '100px', overflow: 'auto' }} >

<div style={{ width: '1000px' }}>just a demo</div>

</div> ); }}

但是,在大部分的情况下,我们完全不需要做,因为 React 的单向数据流和数据驱动渲染,我们可以不通过 DOM,轻松拿到和修改大部分我们需要的 DOM 属性。

import React from 'react';class Demo extends ReactComponent {

constructor(props) { super(props); thisstate = {

link: '//>

以前的字符串式refs(thisrefsxxx)已被遗弃,这里整理的都是最新版本的用法

前言:

先说下React refs的主要用途吧,主要用于直接调用某个节点或者组件实例。

我把它的各种用法大致分为了两大类

一类:是没有跨越中间子组件的节点或实例,也就是单个组件内部调用其直接return中包含的React元素,或者是return中包含其他自定义组件。

二类:是跨越了中间子组件的节点或实例,如:父组件调用自定义组件中的某个React元素。

特别说明:ref是不能作用到函数组件上的,但是可以在函数组件中使用ref,因为函数组件没有实例。ref本身返回也是某个节点,或者某个组件的实例。

这样说着似乎有些抽象空洞,下边上张对比图好了

下边具体笔录下这2类具体的用法

1:常规用法

ReactcreateRef() 和 ref的配合使用

用例:

2:ref回调(个人最爱的一种方式)

这种低版本的React也是支持的,它不同于createRef(),它接受一个函数,以dom元素或者React组件实例作为参数,以使它们能在其他地方被存储和访问。

一种:ref转发

主要通过forwardRef 和 createRef的配合使用

官方并不推荐使用它,下边是官方的建议内容!

当你开始在组件库中使用 forwardRef 时,你应当将其视为一个破坏性更改,并发布库的一个新的主版本。  这是因为你的库可能会有明显不同的行为(例如 refs 被分配给了谁,以及导出了什么类型),并且这样可能会导致依赖旧行为的应用和其他库崩溃。

出于同样的原因,当 ReactforwardRef 存在时有条件地使用它也是不推荐的:它改变了你的库的行为,并在升级 React 自身时破坏用户的应用。

用例:

在高阶组件中转发 refs 

用例:

二种:将ref的值作为组件的属性往下传递到目标节点或者实例。

1:传递createRef

用例:

2:传递ref回调

用例:

需求是这样的,一个聊天窗口,对话框你一句我一句,然后这个对方的回答可能很长,这个时候要检测对方的回答渲染上去后,对应的那条话dom高度有没有超出指定高度,如果超出,就给他多余部分隐藏,并且那条话显示查看更多的按钮,

一开始想的是每一句对话都用各自的ref,然后useEffect每次都去检测ref上的高度,但是其实这样不对,ref如果先绑上了,ref上的属性再变动,是不会触发重新render的也就没法检测到,

看到一个大佬的博客

>

在vue中可以通过给标签加ref属性,就可以在js中利用ref去引用它,从而 *** 作该dom元素。

以下是个例子:

Vue系列产品为3D自然环境的动画制作和渲染提供了一系列的解决方案。Vue系列有很多不同的产品,这是为了满足不同阶层的用户的需要:可以满足专业的制作工作室,同样也能满足3D自由艺术家。

参与项目:

《阿凡达》《2012》《赤壁》《斯巴达克斯》《死不瞑目》《尸城30夜》《功夫熊猫》《异形大战铁血战士》《微光城市》《神奇四侠》《致命拜访》《冒牌天神》《与王一夜》《老友与钱》《加勒比海盗》《ALAUID》《假结婚》《特种部队》《失落的大陆》《终结者》《坠入地狱》《Dragonball Evolution》《女同志吸血鬼杀手》《爱丽丝梦游仙境》《诸神之战》《驯龙记》《狼人》《闰年》《可爱的骨头》《魔法奇幻秀》《美少女特工队》《吉诺密欧与朱丽叶》《纳尼亚传奇》《猫头鹰王国》《歪小子斯科特》《卑鄙的我》《最后的风之子》《怪物史瑞克》《波斯王子》《饥饿游戏》《地心历险记》《雨果》《亚瑟圣诞》《丁丁历险记》《惊天战神》《超级8》《雷神》《大战外星人》《本杰明·巴顿奇事》《马达加斯加》《澳洲乱世情》《空中杀手》《夺宝奇兵》《奇幻精灵事件簿》

不是,ref的意思是这个元素已经在别的地方定义过了(通常是全局定义,定义的时候没有声明父元素和子元素),现在只是引用定义过的这个元素,来说明元素属于哪个父元素。这些元素只显示一次。

上面的代码和下面等价:

<xml version="10">

<xs:schema xmlns:xs=">

以上就是关于我说这是全网最全vue组件通信方式全部的内容,包括:我说这是全网最全vue组件通信方式、如何在 React 中做到 jQuery-free、React Refs的多种用法归纳整理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9479453.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存