61阅读

PS入门实例教程-React 入门实例教程

发布时间:2017-12-09 所属栏目:react

一 : React 入门实例教程

React 入门实例教程 现在最热门的前端框架,毫无疑问是

react React 入门实例教程

。[www.61k.com)

上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑。

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。

这个项目本身也越滚越大,从最早的UI引擎变成了一整套前后端通吃的 Web App 解决方案。衍生的 React Native 项目,目标更是宏伟,希望用写 Web App 的方式去写 Native App。如果能够实现,整个互联网行业都会被颠覆,因为同一组人只需要写一次 UI ,就能同时运行在服务器、浏览器和手机(参见《也许,DOM 不是答案》)。

react React 入门实例教程

既然 React 这么热门,看上去充满希望,当然应该好好学一下。(www.61k.com)从技术角度,

react React 入门实例教程

可以满足好奇心,提高技术水平;从职业角度,有利于求职和晋升,有利于参与潜力大的项目。但是,好的 React 教程却不容易找到,这一方面因为这项技术太新,刚刚开始走红,大家都没有经验,还在摸索之中;另一方面因为 React 本身还在不断变动,API 一直在调整,至今没发布1.0版。

react React 入门实例教程

我学习 React 时,

react React 入门实例教程

就很苦恼。(www.61k.com)有的教程讨论一些细节问题,

react React 入门实例教程

对入门没帮助;有的教程写得不错,但比较短,无助于看清全貌。我断断续续学了几个月,看过二十几篇教程,在这个过程中,将对自己有帮助的 Demo 都收集下来,做成了一个库 React 。

下面,我就根据这个库,写一篇全面又易懂的 React 入门教程。你只需要跟着每一个 Demo 做一遍,就能初步掌握 React 。当然,前提是你必须拥有基本 JavaScript 和 DOM 知识,但是你读完就会发现,React 所要求的预备知识真的很少。 零、安装

React 的安装包,可以到官网下载。不过, 已经自带 React 源码,不用另外安装,只需把这个库拷贝到你的硬盘就行了。

react React 入门实例教程

$ git clone git@github.com:ruanyf/react-demos.git 如果你没安装

react React 入门实例教程

git, 那就直接下载 zip 压缩包。(www.61k.com)

下面要讲解的10个例子在各个 Demo 子目录,每个目录都有一个 index.html 文件,在浏览器打开这个文件(大多数情况下双击即可),就能立刻看到效果。 需要说明的是,React 可以在浏览器运行,也可以在服务器运行,但是本教程只涉及浏览器。一方面是为了尽量保持简单,另一方面 React 的语法是一致的,服务器的用法与浏览器差别不大。Demo11 是服务器首屏渲染的例子,有兴趣的朋友可以自己去看源码。

react React 入门实例教程

一、HTML 模板

使用 React 的网页源码,结构大致如下。(www.61k.com)

<!DOCTYPE html>

<html>

<head>

<script src="../build/react.js"></script>

<script src="../build/JSXTransformer.js"></script> </head>

<body>

<div id="example"></div>

<script type="text/jsx">

// ** Our code goes here! **

</script>

</body>

</html>

上面代码有两个地方需要注意。首先,最后一个 script 标签的 type 属性为 text/jsx 。这是因为 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/jsx" 。

其次,React 提供两个库: react.js 和 JSXTransformer.js ,它们必须首先加载。其中,JSXTransformer.js 的作用是将 JSX 语法转为 JavaScript 语法。这一步很消耗时间,实际上线的时候,应该将它放到服务器完成。

$ jsx src/ build/

上面命令可以将 src 子目录的 js 文件进行语法转换,转码后的文件全部放在 build 子目录。

二、React.render()

react React 入门实例教程

React.render 是

react React 入门实例教程

React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。(www.61k.com]

React.render(

<h1>Hello, world!</h1>,

document.getElementById('example')

);

上面代码将一个 h1 标题,插入 example 节点(查看 demo01),运行结果如下。

三、JSX 语法

上一节的代码, HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,它允许 HTML 与 JavaScript 的混写(查看 Demo02 )。

var names = ['Alice', 'Emily', 'Kate'];

React.render(

<div>

{

names.map(function (name) {

return <div>Hello, {name}!</div>

})

}

</div>,

document.getElementById('example')

);

react React 入门实例教程

上面代码体现了 JSX 的基本语法规则:遇到

扩展:react native入门实例 / react 入门实例 / react native入门教程

react React 入门实例教程

HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。(www.61k.com)上面代码的运行结果如下。

JSX 允许直接在模板插入 JavaScript 变量。如果这个变量是一个数组,则会展开这个数组的所有成员(查看 demo03 )。

var arr = [

<h1>Hello world!</h1>,

<h2>React is awesome</h2>,

];

React.render(

<div>{arr}</div>,

document.getElementById('example')

);

上面代码的arr变量是一个数组,结果 JSX 会把它的所有成员,添加到模板,运行结果如下。

react React 入门实例教程

react React 入门实例教程

四、组件

React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件。(www.61k.com)React.createClass 方法就用于生成一个组件类(查看 demo04)。

var HelloMessage = React.createClass({

render: function() {

return <h1>Hello {this.props.name}</h1>;

}

});

React.render(

<HelloMessage name="John" />,

document.getElementById('example')

);

上面代码中,变量 HelloMessage 就是一个组件类。模板插入 <HelloMessage /> 时,会自动生成 HelloMessage 的一个实例(下文的"组件"都指组件类的实例)。所有组件类都必须有自己的 render 方法,用于输出组件。

组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如

<HelloMessage name="John" /> ,就是 HelloMessage 组件加入一个 name 属性,值为 John。组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取。上面代码的运行结果如下。

react React 入门实例教程

);

}

});

React.render(

<NotesList>

<span>hello</span>

<span>world</span>

react React 入门实例教程

</NotesList>, document.body

react React 入门实例教程

);

上面代码的 NoteList 组件有两个 span 子节点,它们都可以通过

this.props.children 读取,运行结果如下。(www.61k.com]

这里需要注意,只有当子节点多余1个时,this.props.children 才是一个数组,否则是不能用 map 方法的, 会报错。

六、React.findDOMNode()

组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。

但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 React.findDOMNode 方法(查看demo06 )。

var MyComponent = React.createClass({

handleClick: function() {

React.findDOMNode(this.refs.myTextInput).focus();

},

render: function() {

return (

<div>

react React 入门实例教程

<input type="text" ref="myTextInput" />

<input type="button" value="Focus the text input"

onClick={this.handleClick} />

</div>

);

}

});

React.render(

<MyComponent />,

document.getElementById('example')

);

上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。(www.61k.com]这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就指向这个虚拟 DOM 的子节点,最后通过 React.findDOMNode 方法获取真实 DOM 的节点。

需要注意的是,由于 React.findDOMNode 方法获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个方法,否则会返回 null 。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会调用 React.findDOMNode 方法。

React 组件支持很多事件,除了 Click 事件以外,还有 KeyDown 、Copy、Scroll 等,完整的事件清单请查看官方文档。

七、this.state

组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI (查看 demo07 )。

var LikeButton = React.createClass({

getInitialState: function() {

react React 入门实例教程

return {liked: false};

},

handleClick: function(event) {

this.setState({liked: !this.state.liked});

},

render: function() {

var text = this.state.liked ? 'like' : 'haven\'t liked'; return (

<p onClick={this.handleClick}>

You {text} this. Click to toggle.

</p>

);

}

});

React.render(

<LikeButton />,

document.getElementById('example')

);

上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。[www.61k.com)当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。

扩展:react native入门实例 / react 入门实例 / react native入门教程

由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

八、表单

用户在表单填入的内容,属于用户跟组件的互动,所以不能用 this.props 读取(查看 demo08)。

var Input = React.createClass({

react React 入门实例教程

getInitialState: function() {

return {value: 'Hello!'};

},

handleChange: function(event) {

this.setState({value: event.target.value});

},

render: function () {

var value = this.state.value; return (

<div>

<input type="text" value={value} onChange={this.handleChange} />

<p>{value}</p>

</div>

); }

});

React.render(<Input/>, document.body);

上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。[www.61k.com)textarea 元素、select元素、radio元素都属于这种情况,更多介绍请参考官方文档。

九、组件的生命周期

组件的生命周期分成三个状态:

?

?

? Mounting:已插入真实 DOM Updating:正在被重新渲染 Unmounting:已移出真实 DOM

React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。

? componentWillMount()

react React 入门实例教程

?

?

?

? componentDidMount() componentWillUpdate(object nextProps, object nextState) componentDidUpdate(object prevProps, object prevState) componentWillUnmount()

此外,React 还提供两种特殊状态的处理函数。[www.61k.com) ? componentWillReceiveProps(object nextProps):已加载组件收到新的参数

时调用

shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用 ?

这些方法的详细说明,可以参考官方文档。下面是一个例子(查看 demo09 )。

var Hello = React.createClass({

getInitialState: function () {

return {

opacity: 1.0

};

},

componentDidMount: function () {

this.timer = setInterval(function () {

var opacity = this.state.opacity;

opacity -= .05;

if (opacity < 0.1) {

opacity = 1.0;

}

this.setState({

opacity: opacity

});

}.bind(this), 100);

},

render: function () {

react React 入门实例教程

return (

<div style={{opacity: this.state.opacity}}>

Hello {this.props.name}

</div>

);

}

});

React.render(

<Hello name="world"/>,

document.body

);

上面代码在hello组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒,就重新设置组件的透明度,从而引发重新渲染。[www.61k.com)

另外,组件的style属性的设置方式也值得注意,不能写成

style="opacity:{this.state.opacity};"

而要写成

style={{opacity: this.state.opacity}}

这是因为 React 组件样式是一个对象,所以第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象。

十、Ajax

组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以使用

componentDidMount 方法设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI (查看 demo10 )。

var UserGist = React.createClass({

react React 入门实例教程

getInitialState: function() {

return {

username: '',

lastGistUrl: ''

};

},

componentDidMount: function() {

$.get(this.props.source, function(result) {

var lastGist = result[0];

if (this.isMounted()) {

this.setState({

username: lastGist.owner.login,

lastGistUrl: lastGist.html_url

});

}

}.bind(this));

},

render: function() {

return (

<div>

{this.state.username}'s last gist is

<a href={this.state.lastGistUrl}>here</a>.

</div>

);

}

});

React.render(

<UserGist source="https://api.github.com/users/octocat/gists" />, document.body

);

react React 入门实例教程

上面代码使用 jQuery 完成 Ajax 请求,这是为了便于说明。(www.61k.com)React 没有任何依赖,完全可以使用其他库。

扩展:react native入门实例 / react 入门实例 / react native入门教程

二 : 天轰穿2011欢喜上演- WinForm全实例入门DotNet4趣味c#编程系列视频教程

课程是免费的,但是希望大家也举手之劳,帮忙活跃网站,有朋友用得上的话帮忙推荐下。[www.61k.com)

大家有问题随时在论坛上去问,有专人守着回答滴。

  课程需要云朵(积分),购买课程所需要云朵(积分)的获取灰常简单,发帖、回帖、发博客、每日登陆、邀请好友注册等等都有,当然还有最简单最快捷的方法,就是直接购买学币兑换云朵。 

  1学币 = 1元RMB = 100云朵 

   课程URL 

http://www.ixueyun.com/community/lessons.php?mod=detail&lessonId=500

  另外,这个课程为了真正趣味起来,在第二讲中有“重口味”的实例,请女生谨慎哦!

简单介绍下这个系列的教学风格:

1. 幽默,嘿嘿,我还是尽量的见缝插针的填充一些幽默的东西进去。

2. 结合实体教学中遇到的问题,在教程中经常有提醒大家把视频暂停下来自己思考或者练习的地方;

3. 学习本系列教程你的脑子基本上无法偷懒,因为在教程中经常会有我们刻意留下来的问题,有的在本级中可以找到答案,但有些问题可能会在下一级或者后面几级才能够找到答案。

4. 尽量的承前启后,让知识衔接更加的紧密。

5. 完全是随着视频录制一起手敲代码,不知道可以叫“纯手工”不。

6. 整个知识体系我们垂直划分为三个部分,我只讲一个最具代表性的部分,要求大家做其余两个部分;

7. 有一个作业,要求大家根据我们的讲解,一步步的完成这个作业,最终交给我评审;

8. 中间我们尽量接近现实,记事本模仿对象是windows记事本,浏览器模仿的是常见的火狐、360等浏览器,编辑工具为Microsoft Visual Studio 2010(当然,你采用任何一款都可以)我们力求达到很多同学可以边看视频边完成自己的项目的目的。

9. 本系列最大的另外一个特色,是结合了我在实际教学中最大的收获,哪就是将励志和教学结合起来,在我们每一集的最后,都有一句我领悟到、学习到的、甚至正在努力践行的励志名言。 

====================目标学员================================

本课程的主力用户群:学了C#基础,觉得啥都会,但有觉得啥都做不出来的初学者、在校大学生。

1.基本熟悉Microsoft Visual Studio 2010编程环境;

2.学习时间要求10-50个小时(非连续时间);

3.最好是具备ADO.NET和数据库相关知识,当然不具备也行

4.具备c# 编程基础,比如变量、数据类型、分支、循环、方法、类等;

=====================课程大纲===============================

第一讲:Windows窗体                  学习时间:1-2小时

学习目标:

  1. a) 学会使用Microsoft Visual Studio 2010这个工具做基本的操作
  2. b) 学会窗体和控件的常见属性和方法
  3. c) 熟悉创建一个项目的基本流程
  4. d) 能够独立玩起来

教学过程描述:

a)    Windows桌面应用编程基础知识

b)   Windows窗体及控件常用属性

c)    Windows窗体及控件常用事件

d)    输入//输出//触发事件的简单控件

e)   控件的定位//停靠和对齐

f) 结合上面的控件制作一个录入用户信息的程序

第二讲:举一反三之恶搞简单控件

一、学习目标:

a)  熟悉控件属性的操作

b)  熟悉控件的事件玩法

c)  熟悉对控件的动态操作

二、教学过程描述:

a)    动态改变它们的属性

b)    上有政策,下有对策

c)  哪里有压迫哪里就有反抗

d)    学舌鹦鹉

e)    会拉客的控件

f)  动态添加控件

g)    动态删除//隐藏 控件

第三讲 : 打造个人专属记事本  上                 学习时间:1-2小时

一、  学习目标:

a)    学会使用下例控件,学一些基本的编程技巧

b)   MenuStrip控件 -菜单栏

c)  ToolStrip控件 - 工具栏

d)   StatusStrip控件 -状态栏

e)  ContextMenuStrip控件 --右键菜单

f)  RichTextBox 控件

二、 教学过程描述:

a)  MenuStrip控件 -菜单栏

b)   ToolStrip控件 - 工具栏

c)  StatusStrip控件 -状态栏

d)   ContextMenuStrip控件 --右键菜单

e)  RichTextBox 控件

第四 、 五 讲 : 打造个人专属记事本  中/下         学习时间:2-6小时

一、   学习目标:

a)   会更多控件的使用

b)    学习到如何来制作这些常见的功能

二、  教学过程描述:

a)  对话框组件

b)   openFileDialog

c)  saveFileDialog

d)   fontDialog

e)  字节流处理类

f)  StreamWriter

g)   StreamReader

h)   关于窗体

i)  设置全局变量

j)    使用字节流实现打开、保存和新建

k)   实现菜单条、工具条、右键菜单的复制、剪切、粘贴、全选

l)  设置字体

m)  实现状态栏字数统计

n)   实现在线帮助和状态栏广告

o)   实现退出和关闭窗体事件

p)   实现查找和关于

第六 讲 : 打造超级裸奔浏览器-简单        学习时间:2-4小时

一、   学习目标:

a)  熟悉WebBrowser控件的基本方法、属性的使用

b)  制作一个具备基本功能的个人专属浏览器

二、  教学过程描述:

a)  浏览器内核(WebBrowser)

b)   WebBrowser 事件,属性,方法

c)  分析IE和FireFox 得到基本功能需求

d)   制作软件界面

e)  为软件实现每个功能(编写事件代码)

f)  实现前进、后退、刷新、访问主页

g)   转到和捕获回车事件

h)   实现搜索

i)  实现进度条

j)  时间广告

第七 讲 : 打造超级裸奔浏览器-进阶          学习时间:2-6小时

一、   学习目标:

a)  熟悉容器类控件的动态操作

b)  实现浏览器多选项卡浏览

二、 教学过程描述:

a)  TabControl控件

b)   控件的获取

c)  控件事件

d)    添加TabControl控件

e)  添加一个默认的WebBorwser控件

f)  设置TabControl控件的父容器的双击事件

g)   添加新的选项卡

h)   添加新的WebBorwser控件

i)  设置TabPage的双击事件

j)  获得当前激活状态下的TabPage中的WebBorwser控件

k)   使用这个WebBorwser控件

l)  修正之前的所有功能

第八 讲 :打包成安装程序               学习时间:1-2小时

三、   学习目标:

a)  将做出来的应用程序打包并安装到其它计算机上

四、  教学过程描述:

a)  介绍Winform系统打包和部署的概念,通过实例介绍如何进行打包和部署的方法。

b)   本章的学习目标:

  1.     了解打包和部署的概念
  2.     掌握简单打包和部署的方法
  3.     掌握复杂打包和部署的方法

本课程共   八    讲,建议学习时间(至少)  10~20   小时以上

============================教学目标=========================

学员在学完本课程后,能够有一个实现整个程序的清晰思路,能够独立完成简单的Windows桌面应用程序,学习到常用的控件使用以及扩展学习的能力,并且以前零散的数据库和C#基础知识整合起来,培养学员从前期需求分析到具体程序实现并安装的整体能力,为下个项目课程打下良好的基础;具体细化如下:

1.学员能够编写简单Windows桌面应用程序;

2.学习到常用的控件使用以及扩展学习的能力;

3.学会使用应用程序配置文件为程序服务;

4.掌握C#编写Windows桌面应用程序的技巧;

5.学会如何在以后的学习过程中采用更有趣,更高效的学习方法

=================教学成果===================

简单实用的记事本

  1. 新建
  2. 保存
  3. 全选
  4. 剪切
  5. 复制
  6. 粘贴
  7. 设定字体
  8. 是否换行
  9. 在线帮助
  10. 搜索
  11. 广告

 

超级裸奔但功能强大的网页浏览器

  1. 按地址访问
  2. 响应回车
  3. 前进
  4. 后退
  5. 刷新
  6. 停止
  7. 右键’
  8. 读取网页标题到浏览器
  9. 搜索
  10. 加载进度
  11. 多选项卡切换


请在学习过程中注意以下几点:

1: 举一反三,学习到一个知识点,就尽量延伸相关的一切可能,但请记住,发现问题是由于所学有限,而且差距很大的话,请马上停止,继续学习本系列后面的东西,不要偏离太远,这会让你的信心受打击的。

2: 当教程中一个知识点讲完,请暂停视频,按照你自己的理解赶紧去做一下

3: 虽然每节课的代码资料都是提供了的,但是我希望大家不要在开始就看我的代码,请跟着我一起来做,而不是看着我的代码听我的讲解,那会让你事倍功半的。

4: 遇到错误,除非万不得已,请不要问我,当然也不要去麻烦别人,因为你要知道,排错,解决问题的能力也是你日后最大的本钱之一。否则就算你拿到博士学位,没有良好的解决问题的能力和习惯,不客气的说,你也不会有什么出息。 哪么这样说是不是一定要自己逼得要死去解决呢?当然不是,你要学会在网上搜索答案,最重要的是你要学会用好动态帮助,也就是MSDN。如果实在不行了,再求教与人。

5: 我们一直会有在线答疑的时间,但是请记住,任何问题我都不会直接告诉你答案,你能够得到的仅仅是思路,甚至是一顿批评(对于我认为值得培养的人,我从来不吝啬时间来激怒你)。

6: 面对问题,你需要记住,我随时愿意帮助你,所以不要放弃,不要气馁

7: 面对成绩,小骄傲一下就行了,否则小心被我批得一文不值。

8: 按时完成你的作业。

   课程URL 

http://www.ixueyun.com/community/lessons.php?mod=detail&lessonId=500

三 : AVR Studio 快速入门教程实例

AVRStudio软件下载及安装方法请参考:AVR开发软件的选择与安装。[www.61k.com]

软件安装好后,你就能在电脑上看到如下的功能菜单:

avr单片机教程 AVR Studio 快速入门教程实例 

功能一:编写、编译汇编工程项目。 (不推荐使用)

操作方法:在菜单 Project --> New Project 打开如下界面。输入项目名按Fishish后出现汇编代码的编辑窗口。

注意:由于本功能仅适合于汇编语言。我们不推荐使用汇编开发AVR,故不推荐大家使用这个功能。我们这里也不加描述。详细原因请参考我们网站的文章:为何开发AVR使用C而不是使用汇编?

avr单片机教程 AVR Studio 快速入门教程实例

功能二: 使用STK500、JTAG或JTAG mkII 下载

avr单片机教程 AVR Studio 快速入门教程实例

Connect 与 Auto Connect 的区别,是每次都会提示选择的设备名称与连接端口。 Auto Conect 会自动使用上一次的设置,提高操作效率。

使用Connect 会弹出如下的界面:

avr单片机教程 AVR Studio 快速入门教程实例

Port 口我们选择 Auto 即可。

如果你没有连接 STK500、JTAG、mkII 等设备,可以使用 Disconnected Mode (脱机模式)进入查看操作界面。

详细的下载方法,请参考本网站新手入门范例的有关介绍。

扩展:avr单片机快速入门 / avr单片机快速入门pdf / avr studio

四 : CMake快速入门教程:实战

0. 前言

一个多月前,由于工程项目的需要,匆匆的学习了一下cmake的使用方法,现在有时间拿出来整理一下。本文假设你已经学会了cmake的使用方法,如果你还不会使用cmake,请参考相关资料之后再继续向下看。

本文中介绍的是生成可执行程序的方法和步骤,生成动态库和静态库的方法与此有所不同,随后会介绍动态库和静态库项目中cmake的编写方法。

本文参考《CMake Practice》这篇文章完成,旨在指导用户快速使用CMake,如果需要更详细的内容,请通读《CMake Practice》这篇文章。下载路径:http://sewm.pku.edu.cn/src/paradise/reference/CMake%20Practice.pdf

1. 项目目录结构

我们项目的名称为CRNode,假设我们项目的所有文件存放再~/workspace/CRNode,之后没有特殊说明的话,我们所指的目录都以此目录为相对路径。

我们的目录结构如下:

~/workspace/CRNode ├─ src │ ├─ rpc │ │ ├─ CRMasterCaller.h │ │ ├─ CRMasterCaller.cc │ │ ├─ CRNode.h │ │ ├─ CRNode.cc │ │ ├─ Schd_constants.h │ │ ├─ Schd_constants.cc │ │ ├─ CRMaster.h │ │ ├─ CRMaster.cc │ │ ├─ CRNode_server.skeleton.h │ │ ├─ CRNode_server.skeleton.cc │ │ ├─ Schd_types.h │ │ └─ Schd_types.cc │ ├─ task │ │ ├─ TaskExecutor.h │ │ ├─ TaskExecutor.cc │ │ ├─ TaskMonitor.h │ │ └─ TaskMonitor.cc │ ├─ util │ │ ├─ Const.h │ │ ├─ Const.cc │ │ ├─ Globals.h │ │ ├─ Globals.cc │ │ ├─ Properties.h │ │ ├─ Properties.cc │ │ ├─ utils.h │ │ └─ utils.cc │ ├─ main.cc │ └─ CMakeLists.txt ├─ doc │ └─ crnode.txt ├─ COPYRIGHT ├─ README ├─ crnode.sh └─ CMakeLists.txt

其中,src存放源代码文件和一个CMakeLists.txt文件,CMakeLists文件的编写我们稍候介绍;doc目录中存放项目 的帮助文档,该文档以及COPYRIGHT和README一起安装到/usr/share/doc/crnode目录中;COPYRIGHT文件存放项目 的版权信息,README存放一些说明性文字;crnode.sh存放CRNode的启动命令;CMakeLists.txt文件稍候介绍。

除此之外,项目还依赖两个外部库:Facebook开发的thrift库,其头文件存放在/usr/include/thrift目录中;log4cpp库,其头文件存放再/usr/include下。

2. CMakeLists.txt文件

本工程中使用了两个CMakeLists.txt文件,分别项目的根目录(即~/workspace/CRNode目录,下同)和src目录中 (参考以上目录结构)。我们先给出两个CMakeLists.txt的内容,在下一节中再对两个CMakeLists.txt进行详细介绍。两个 CMakeLists.txt文件的内容分别如下:

2.1 根目录中CMakeLists内容

1234567891011121314cmake_minimum_required (VERSION 2.6)project (CRNode)ADD_SUBDIRECTORY(src bin)#SET(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR})SET(CMAKE_INSTALL_PREFIX /usr/local)INSTALL(PROGRAMS crnode.sh DESTINATION bin)INSTALL(FILES COPYRIGHT README DESTINATION share/doc/crnode)INSTALL(DIRECTORY doc/ DESTINATION share/doc/crnode)

2.2 src/CMakeLists.txt内容

123456789101112131415161718192021222324INCLUDE_DIRECTORIES(/usr/include/thrift)SET(SRC_LIST main.cc rpc/CRMasterCaller.cpp rpc/CRNode_server.skeleton.cpp rpc/Schd_constants.cpp rpc/CRMaster.cpp rpc/CRNode.cpp rpc/Schd_types.cpp task/TaskExecutor.cpp task/TaskMoniter.cpp util/Const.cpp util/Globals.cc util/utils.cc util/Properties.cpp )ADD_EXECUTABLE(crnode ${SRC_LIST})TARGET_LINK_LIBRARIES(crnode log4cpp thrift)INSTALL(TARGETS crnode RUNTIME DESTINATION bin)

3. CMake语法

A. 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名;

B. 指令(参数 1 参数 2…),参数使用括弧括起,参数之间使用空格或分号分开;

C. 指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令。

4. CMakeLists.txt剖析

4.1 cmake_minimum_required命令

1cmake_minimum_required (VERSION 2.6)

规定cmake程序的最低版本。这行命令是可选的,我们可以不写这句话,但在有些情况下,如果CMakeLists.txt文件中使用了一些高版本cmake特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行cmake。

4.2 project命令

3project (CRNode)

指定项目的名称。项目最终编译生成的可执行文件并不一定是这个项目名称,而是由另一条命令确定的,稍候我们再介绍。

但是这个项目名称还是必要的,在cmake中有两个预定义变量:< projectname >_BINARY_DIR以及< projectname >_SOURCE_DIR,在我们的项目中,两个变量分别为:CRNode_BINARY_DIR和CRNode_SOURCE_DIR。内部编译 情况下两者相同,后面我们会讲到外部编译,两者所指代的内容会有所不同。要理解这两个变量的定义,我们首先需要了解什么是“外部构建(out-of- source build)”,我们将在下一小节中介绍“外部构建”。

同时cmake还预定义了PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR变量。在我们的项目 中,PROJECT_BINARY_DIR等同于CRNode_BINARY_DIR,PROJECT_SOURCE_DIR等同于 CRNode_SOURCE_DIR。在实际的应用用,我强烈推荐使用PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR变 量,这样即使项目名称发生变化也不会影响CMakeLists.txt文件。

4.3 外部构建

假设我们此时已经完成了两个CMakeLists.txt文件的编写,可以执行cmake命令生成Makefile文件了。此时我们由两种方法可以执行cmake、编译和安装:

12cmake .make

或者

1234mkdir buildcd buildcmake ..make

两种方法最大的不同在于执行cmake和make的工作路径不同。第一种方法中,cmake生成的所有中间文件和可执行文件都会存放在项目 目录中;而第二种方法中,中间文件和可执行文件都将存放再build目录中。第二种方法的优点显而易见,它最大限度的保持了代码目录的整洁。同时由于第二 种方法的生成、编译和安装是发生在不同于项目目录的其他目录中,所以第二种方法就叫做“外部构建”。

回到之前的疑问,再外部构建的情况下,PROJECT_SOURCE_DIR指向的目录同内部构建相同,仍然为~/workspace /CRNode,而PROJECT_BINARY_DIR则有所不同,指向~/workspace/CRNode/build目录。

当然,cmake强烈推荐使用外部构建的方法。

4.4 ADD_SUBDIRECTORY命令

5ADD_SUBDIRECTORY(src bin)

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。 EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除。比如,工程的 example,可能就需要工程构建完成后,再进入 example 目录单独进行构建。

在我们的项目中,我们添加了src目录到项目中,而把对应于src目录生成的中间文件和目标文件存放到bin目录下,在上一节举例中“外部构建”的情况下,中间文件和目标文件将存放在build/srcobj目录下。

4.5 SET命令

8SET(CMAKE_INSTALL_PREFIX /usr/local)

现阶段,只需要了解SET命令可以用来显式的定义变量即可。在以上的例子中,我们显式的将CMAKE_INSTALL_PREFIX的值定 义为/usr/local,如此在外部构建情况下执行make install命令时,make会将生成的可执行文件拷贝到/usr/local/bin目录下。

当然,可执行文件的安装路径CMAKE_INSTALL_PREFIX也可以在执行cmake命令的时候指定,cmake参数如下:

cmake -DCMAKE_INSTALL_PREFIX=/usr ..

如果cmake参数和CMakeLists.txt文件中都不指定该值的话,则该值为默认的/usr/local。

4.6 INCLUDE_DIRECTORIES命令

1INCLUDE_DIRECTORIES(/usr/include/thrift)

INCLUDE_DIRECTORIES类似gcc中的编译参数“-I”,指定编译过程中编译器搜索头文件的路径。当项目需要的头文件不在 系统默认的搜索路径时,需要指定该路径。在我们的项目中,log4cpp所需的头文件都存放在/usr/include下,不需要指定;但thrift的 头文件没有存放在系统路径下,需要指定搜索其路径。

4.7 ADD_EXECUTABLE和ADD_LIBRARY

3456789101112131415161718SET(SRC_LIST main.cc rpc/CRMasterCaller.cpp rpc/CRNode_server.skeleton.cpp rpc/Schd_constants.cpp rpc/CRMaster.cpp rpc/CRNode.cpp rpc/Schd_types.cpp task/TaskExecutor.cpp task/TaskMoniter.cpp util/Const.cpp util/Globals.cc util/utils.cc util/Properties.cpp )ADD_EXECUTABLE(CRNode ${SRC_LIST})

ADD_EXECUTABLE定义了这个工程会生成一个文件名为 CRNode 的可执行文件,相关的源文件是 SRC_LIST 中定义的源文件列表。需要注意的是,这里的CRNode和之前的项目名称没有任何关系,可以任意定义。

4.8 EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH

我们可以通过 SET 指令重新定义 EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH 变量来指定最终的目标二进制的位置(指最终生成的CRNode可执行文件或者最终的共享库,而不包含编译生成的中间文件)。

命令如下:

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

需要注意的是,在哪里 ADD_EXECUTABLE 或 ADD_LIBRARY,如果需要改变目标存放路径,就在哪里加入上述的定义。

4.9 TARGET_LINK_LIBRARIES命令

20TARGET_LINK_LIBRARIES(CRNode log4cpp thrift)

这句话指定在链接目标文件的时候需要链接的外部库,其效果类似gcc的编译参数“-l”,可以解决外部库的依赖问题。

4.10 INSTALL命令

在执行INSTALL命令的时候需要注意CMAKE_INSTALL_PREFIX参数的值。该参数在3.5中已经有所介绍。其命令形式如下:

INSTALL(TARGETS targets...[[ARCHIVE|LIBRARY|RUNTIME][DESTINATION < dir >][PERMISSIONS permissions...][CONFIGURATIONS[Debug|Release|...]][COMPONENT < component >][OPTIONAL]] [...])

参数中的 TARGETS 后面跟的就是我们通过 ADD_EXECUTABLE 或者 ADD_LIBRARY 定义的目标文件,可能是可执行二进制、动态库、静态库。

DESTINATION 定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候CMAKE_INSTALL_PREFIX 其实就无效了。如果你希望使用 CMAKE_INSTALL_PREFIX 来定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是${CMAKE_INSTALL_PREFIX} /< destination 定义的路径>

你不需要关心 TARGETS 具体生成的路径,只需要写上 TARGETS 名称就可以了。

非目标文件的可执行程序安装(比如脚本之类):

INSTALL(PROGRAMS files... DESTINATION < dir >[PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][COMPONENT < component >][RENAME < name >] [OPTIONAL])

跟上面的 FILES 指令使用方法一样,唯一的不同是安装后权限为OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 权限目录的安装。

安装一个目录的命令如下:

INSTALL(DIRECTORY dirs... DESTINATION < dir >[FILE_PERMISSIONS permissions...][DIRECTORY_PERMISSIONS permissions...][USE_SOURCE_PERMISSIONS][CONFIGURATIONS [Debug|Release|...]][COMPONENT < component >][[PATTERN < pattern > | REGEX < regex >][EXCLUDE] [PERMISSIONS permissions...]] [...])

DIRECTORY 后面连接的是所在 Source 目录的相对路径,但务必注意:abc 和 abc/有很大的区别。如果目录名不以/结尾,那么这个目录将被安装为目标路径下的 abc,如果目录名以/结尾,代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。我们来看一个例子:

12345INSTALL(DIRECTORY icons scripts/ DESTINATION share/myprojPATTERN "CVS" EXCLUDEPATTERN "scripts/*"PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READGROUP_EXECUTE GROUP_READ)

这条指令的执行结果是:

将 icons 目录安装到 < prefix >/share/myproj,将 scripts/中的内容安装到< prefix >/share/myproj,不包含目录名为 CVS 的目录,对于 scripts/*文件指定权限为 OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ。

因为crnode.txt 要安装到/< prefix >/share/doc/crnode,所以我们不能直接安装整个 doc 目录,这里采用的方式是安装 doc 目录中的内容,也就是使用”doc/”在工程文件中添加:

1INSTALL(DIRECTORY doc/ DESTINATION share/doc/crnode)

5. 编译安装

编译安装结果如下:

[root@sim91 build]# cmake ..-- Configuring done-- Generating done-- Build files have been written to: /home/fify/workspace/CRNode/build[root@sim91 build]# makeScanning dependencies of target crnode[ 7%] Building CXX object srcobj/CMakeFiles/crnode.dir/main.cc.o[ 15%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRMasterCaller.cpp.o[ 23%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRNode_server.skeleton.cpp.o[ 30%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/Schd_constants.cpp.o[ 38%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRMaster.cpp.o[ 46%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/CRNode.cpp.o[ 53%] Building CXX object srcobj/CMakeFiles/crnode.dir/rpc/Schd_types.cpp.o[ 61%] Building CXX object srcobj/CMakeFiles/crnode.dir/task/TaskExecutor.cpp.o[ 69%] Building CXX object srcobj/CMakeFiles/crnode.dir/task/TaskMoniter.cpp.o[ 76%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Const.cpp.o[ 84%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Globals.cc.o[ 92%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/utils.cc.o[100%] Building CXX object srcobj/CMakeFiles/crnode.dir/util/Properties.cpp.oLinking CXX executable crnode[root@sim91 build]# make install[100%] Built target crnodeInstall the project...-- Install configuration: ""-- Installing: /usr/local/bin/crnode.sh-- Installing: /usr/local/share/doc/crnode/COPYRIGHT-- Installing: /usr/local/share/doc/crnode/README-- Installing: /usr/local/share/doc/crnode-- Installing: /usr/local/share/doc/crnode/crnode.txt-- Installing: /usr/local/bin/crnode

大功告成!更多内容请参考《CMake Practice》,再次对《CMake Practice》的作者表示感谢!

五 : PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

画框图软件 PS图像处理软件入门大全教程之实例(35)用图层样式打造个性画框

扩展:画框样式 / 图层样式 / ps图层样式

本文标题:PS入门实例教程-React 入门实例教程
本文地址: http://www.61k.com/1169688.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1