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的多种用法归纳整理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)