用TypeScipt和AMD模块化理念实现React官方教程(三)静态页面
来源:互联网 发布:在美国程序员的工资 编辑:程序博客网 时间:2024/06/01 16:39
现在我们可以象用C#开发那样来开发React应用了,我们的目的就是将 React官方教程整个迁移到typescript上实现:
创建第一个组件
在IDE的新建项中,我们可以找到TypeScript JSX文件,扩展名为tsx,如图:
在js目录下创建如下文件:
CommentBox.tsx
现在我们不需要象原教程那样命名.js文件了。完全可以按类来命名文件,这就是发挥TypeScript中Type 的力量的时候了!
文件内容如下:
/// <reference path="../typings/react/react-global.d.ts"/>export =CommentBox;class CommentBox extends React.Component<any, any> { render() { return <div className="commentBox">我是一个评论框。 </div>; }}
注意HTML元素我们用小写字母开头,而自定义的Ract类我们用大写字母开头。
另外创建如下文件作为主文件:
main.tsx
文件内容如下:
/// <reference path="../typings/react/react-global.d.ts"/>import CommentBox = require("./CommentBox");ReactDOM.render(<CommentBox />, document.getElementById('content'));
这时点按运行,不出意外的话,浏览器将显示正常结果,内容为:我是一个评论框。
组合组件
让我们跟随示例创建CommentList 和 CommentForm如下:
CommentList.tsx
文件内容如下:
/// <reference path="../typings/react/react-global.d.ts"/>export =CommentList;class CommentList extends React.Component<any, any> { render() { return <div className="commentList">你好,我是一个评论列表。</div>; }}
CommentForm.tsx
文件内容如下:
/// <reference path="../typings/react/react-global.d.ts"/>export =CommentForm;class CommentForm extends React.Component<any, any> { render() { return <div className="commentForm">你好,我是一个评论表单。</div>; }}
接下去修改CommentBox.tsx,如下:
/// <reference path="../typings/react/react-global.d.ts"/>import CommentList = require("./CommentList");import CommentForm = require("./CommentForm");export =CommentBox;class CommentBox extends React.Component<any, any> { render() { return ( <div className="commentBox"> <h1>评论</h1> <CommentList /> <CommentForm /> </div> ); }}
使用props
现在让我们他建Comment组件,它将使用从父组件那里传入的数据。从父组件那里传入的数据将作为”属性(propery)”存在于子组件中。这些属性(properties)通过this.props访问。使用props,我们可以从CommentList传入的数据读取到Comment中,将生成一些标记:
Comment.tsx
文件内容如下:
/// <reference path="../typings/react/react-global.d.ts"/>export =Comment;class Comment extends React.Component<any, any> { render() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> {this.props.children} </div> ); }}
组件属性
上面我们已经定义好了Comment
组件,我们想要将作者名字和评论文本传入。这样可以让我们为每个单独的评论重用想同的代码。现在让我们在CommentList
中添加一些评论:
CommentList.tsx
/// <reference path="../typings/react/react-global.d.ts"/>import Comment = require('./Comment');export =CommentList;class CommentList extends React.Component<any, any> { render() { return ( <div className="commentList"> <Comment author="Eureka Chen">这是其中一个评论</Comment> <Comment author="Jordan Walke">这是 *另一个* 评论</Comment> </div> ); }}
添加Markdown解析
在index.html我们引用了第三方的marked库,将Markdown文件转化为Html。将comment.tsx改写成:
/// <reference path="../typings/react/react-global.d.ts"/>/// <reference path="../typings/marked/marked.d.ts"/>export =Comment;class Comment extends React.Component<any, any> { render() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> { marked(this.props.children.toString())} </div> ); }}
注意在html中添加对maked.js的引用。
现在我们得到如图示的结果:
但是这里有个问题!从如图的输出中,直接输出了Html标签。我们需要他们生成Html。这是因为React防止XSS攻击,这里有个方法,但框架警告你不要这样。
/// <reference path="../typings/react/react-global.d.ts"/>/// <reference path="../typings/marked/marked.d.ts"/>export =Comment;class Comment extends React.Component<any, any> { rawMarkup() { var rawMarkup = marked(this.props.children.toString(), { sanitize: true }); return { __html: rawMarkup }; } render() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHTML={this.rawMarkup() } /> </div> ); }}
这是API特意让原生HTML难以插入,但marked可以利用这个后门。
挂接到数据模型
到现在我们是直接在源代码中插入评论。现在,让我们使用JSON数据插入评论中。最终这些数据会来自服务器,但现在,我们写在源码中:
我们在main.tsx中加入data,如下:
/// <reference path="../typings/react/react-global.d.ts"/>import CommentBox = require("./CommentBox");var data = [ { id: 1, author: "Eureka Chen", text: "这是一个评论" }, { id: 2, author: "Jordan Walke", text: "这是 *另一个* 评论" }];ReactDOM.render(<CommentBox data={data} />, document.getElementById('content'));
然后在CommentBox.tsx中改为:
/// <reference path="../typings/react/react-global.d.ts"/>import CommentList = require("./CommentList");import CommentForm = require("./CommentForm");export =CommentBox;class CommentBox extends React.Component<any, any> { render() { return ( <div className="commentBox"> <h1>评论</h1> <CommentList data={this.props.data} /> <CommentForm /> </div> ); }}
现在数据传到了CommentList,让我们动态生成评论,CommentList.tsx如下:
/// <reference path="../typings/react/react-global.d.ts"/>import Comment = require('./Comment');export =CommentList;class CommentList extends React.Component<any, any> { render() { var commentNodes = this.props.data.map( function (comment) { return ( <Comment author={comment.author} key={comment.id}> {comment.text} </Comment> ); }); return ( <div className="commentList"> {commentNodes} </div> ); }}
最终结果如下:
下一次我们开始讲从服务器获取数据。
- 用TypeScipt和AMD模块化理念实现React官方教程(三)静态页面
- 用TypeScipt和AMD模块化理念实现React官方教程(二)教程服务器搭建
- 用TypeScipt和AMD模块化理念实现React官方教程(五)提交和更新数据
- 用TypeScipt和AMD模块化理念实现React官方教程(四)获取数据
- 用TypeScipt和AMD模块化理念实现React官方教程(一)环境搭建
- 初识AMD和CMD模块化
- 前端模块化、AMD和CMD
- Javascript模块化编程系列三: CommonJS & AMD 模块化规范描述
- AMD- 模块化
- JavaScript中的模块化之AMD和CMD
- javascript模块化编程:CommonJS和AMD规范
- 初识模块化AMD和require.js
- CommonJs和AMD(requireJS)模块化
- react理念
- Dojo中AMD模块化和本地变量的命名规范
- JavaScript模块化编程 - CommonJS, AMD 和 RequireJS之间的关系
- JavaScript模块化编程 - CommonJS, AMD 和 RequireJS之间的关系
- 前端模块化开发(AMD和CDM规范)
- 定时器iOS
- windows下,用eclipse连接虚拟机中的hadoop
- IOMeter存储测试工具
- hdu 1010 java版
- JSBadgeView适配iOS7、8,和超快速使用
- 用TypeScipt和AMD模块化理念实现React官方教程(三)静态页面
- 第三届蓝桥杯初赛6大数乘法填空题
- bzoj2005 能量采集
- 实例说明jvm内存模型
- javascript null
- HYSBZ 1588 营业额统计
- 使用ssh-keygen和ssh-copy-id三步实现SSH无密码登录
- LeetCode Substring with Concatenation of All Words
- 简单说说服务治理