We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在上一篇 #103 中,我们已经掌握了“如何解析渲染一段 JSX 结构”。今天,我们进一步研究:如何解析、渲染和更新组件。
在研究组件解析之前,我们先来看个更简单的例子。
import {h, render, Component} from '../../preact'; class Person extends Component { constructor() { super(); this.state = { name: "youngwind" } } render() { return ( <div> {this.state.name} </div> ) } } render(<Person />, document.body);
问题:在渲染 Person 组件的时候,如何将 this.state.name 解析成真实值 "youngwind" 呢?是用正则匹配替换吗? 答案:不需要处理,因为 babel 已经帮我们处理好了。 请看编译后的代码。
由图中我们可以看出:由于 this.state.name被当做函数参数传递给 h 函数,因此 h 函数在执行的时候会对其进行自动求值。也就是说,对于变量的解析,我们并不需要做任何特殊处理。
this.state.name
再看一个更复杂的例子。
import {h, render, Component} from '../../preact'; class Person extends Component { constructor() { super(); this.state = { name: "youngwind", age: 25 } } render() { return ( <div> <Name name={this.state.name}/> <Age age={this.state.age}/> </div> ) } } class Name extends Component { render(props) { return ( <div> {props.name} </div> ) } } class Age extends Component { render(props) { return ( <div> {props.name} </div> ) } } render(<Person />, document.body);
编译后的代码如下:
由图中我们可以发现:babel 进行 JSX 解析时,对普通标签和组件标签的处理是类似的,只不过有两点不同。
有了上面的基础,我们来看看如何实现组件的渲染和更新,举个例子。
import {h, render, Component} from '../../preact'; class Person extends Component { constructor() { super(); this.state = { name: "youngwind", age: 25 } } change() { let {name, age} = this.state; this.setState({ name: name + '啦', age: age + 1 }); } render() { return ( <div> <button onclick={this.change.bind(this)}>改变</button> <Name name={this.state.name}/> <Age age={this.state.age}/> </div> ) } } class Name extends Component { render(props) { return ( <div> <label>姓名:</label> <span>{props.name}</span> </div> ) } } class Age extends Component { render(props) { return ( <div> <label>年龄:</label> <span>{props.age}</span> </div> ) } } render(<Person />, document.body);
这段代码,我们期望的功能是:
具体的实现逻辑较为繁复,难以用文字描述清楚,我画了个流程图,可以对比着我实现的代码看。
最终实现的效果如下所示。(注意,效果图中控制台会输出一些生命周期的信息,这部分的代码我在 demo 中省略了,完整的代码请参考这里。 )
虽然在本文中已经实现了组件的更新,但是,并没有应用虚拟 DOM 的 diff 算法,之后有时间再去研究研究。
The text was updated successfully, but these errors were encountered:
感谢博主分享的文章,真是简洁明了。我照着您的源码重新实现,在过程中遇到一个疑问,想请教博主一下: 在源码 91~96行, build函数中
build
// 判断新子节点是否已经存在原有 DOM 中 newChildren.forEach((newChild, i) => { if (children[i] !== newChild) { out.appendChild(newChild); } });
这里为什么要使用appendChild,不应该直接用 newChildren 替换掉 children么。
appendChild
newChildren
children
Sorry, something went wrong.
No branches or pull requests
在上一篇 #103 中,我们已经掌握了“如何解析渲染一段 JSX 结构”。今天,我们进一步研究:如何解析、渲染和更新组件。
变量的解析
在研究组件解析之前,我们先来看个更简单的例子。
问题:在渲染 Person 组件的时候,如何将 this.state.name 解析成真实值 "youngwind" 呢?是用正则匹配替换吗?
答案:不需要处理,因为 babel 已经帮我们处理好了。
请看编译后的代码。
由图中我们可以看出:由于
this.state.name
被当做函数参数传递给 h 函数,因此 h 函数在执行的时候会对其进行自动求值。也就是说,对于变量的解析,我们并不需要做任何特殊处理。组件标签的解析
再看一个更复杂的例子。
编译后的代码如下:
由图中我们可以发现:babel 进行 JSX 解析时,对普通标签和组件标签的处理是类似的,只不过有两点不同。
组件的渲染与更新
有了上面的基础,我们来看看如何实现组件的渲染和更新,举个例子。
这段代码,我们期望的功能是:
具体的实现逻辑较为繁复,难以用文字描述清楚,我画了个流程图,可以对比着我实现的代码看。
效果
最终实现的效果如下所示。(注意,效果图中控制台会输出一些生命周期的信息,这部分的代码我在 demo 中省略了,完整的代码请参考这里。
)
后话
虽然在本文中已经实现了组件的更新,但是,并没有应用虚拟 DOM 的 diff 算法,之后有时间再去研究研究。
The text was updated successfully, but these errors were encountered: