React和Vue特性和书写差异
Vue均使用ES6语法,主要以单文件组件为例,写法上优先使用缩写。
React使用TS语法。
生命周期
- Vue
 

- React
 

入口&根实例
- Vue
 
const app = new Vue({
  /* 选项 */
  render: (h) => h(App) // App为根组件
}).$mount('#app')
- React
 
ReactDOM.render(
<App/>, // App为根组件
document.getElementById('app')
)
组件定义
- Vue
 
// 定义组件构造器
var MyComponent = Vue.extend({/* 选项 */}) // 注册全局组件
Vue.component('my-component', {/* 选项 */})
<!-- 单文件组件 -->
<template>
<div class="my-component">hello</div>
</template>
<script>
export default {
/* 选项 */
}
</script>
- React
 
// 无状态组件
const Foo = () => {
return <div className='foo'></div>
}
// 完整组件
class Foo extends React.Component<{}, void> {
render () {
return <div className='foo'>hello</div>
}
}
组件引用
- Vue
 
<!-- 以单文件组件为例:Foo.js -->
<template>
<div class="Foo">
<!-- 必须小写,不能自闭合 -->
<bar></bar>
</div>
</template>
<script>
// 引入组件
import Bar from './Bar' export default {
name: 'Foo',
components: {Bar}
}
</script>
- React
 
import Bar from './Bar'
class Foo extends React.Component<{}, void> {
  render () {
    return (
      <div className='foo'>
        {/* 组件约定大写开头,可自闭合 */}
        <Bar/>
      </div>
    )
  }
}
组件内部状态
- Vue
 
<template>
<div class="foo">
<p class='name'>{{name}}</p>
<p class='age'>
{{age}}
<button @click="onAdd">add</button>
</p>
</div>
</template>
<script>
export default {
data () {
return {
name: 'Tom',
age: 18
}
},
methods {
onAdd () {
// 直接修改
this.age++
}
}
}
</script>
- React
 
interface IFooState {
  name: string,
  age: number
}
class Foo extends React.Component<{}, IFooState> {
  state = {
    name: 'tom',
    age: 18
  }
  onAdd = () => {
    // 必须通过setState修改
    this.setState({
      age: this.state.age + 1
    })
  }
  render () {
    const {name, age} = this.state
    return (
      <div className='foo'>
        <p class='name'>{name}</p>
        <p class='age'>
          {age}
          <button onClick={this.onAdd}>add</button>
        </p>
      </div>
    )
  }
}
父子组件通讯
- Vue
 
<!-- Parent.vue -->
<template>
<div class="parent">
<child name='tom' :age='18' @click="onAdd"></child>
</div>
</template>
<script>
export default {
data () {
return {
age: 18
}
},
methods {
onAdd () {
this.age++
}
}
}
</script>
<!-- Child.vue -->
<template>
<div class="child">
<p class='name'>{{name}}</p>
<p class='age'>
{{age}}
<button @click="onAdd">add</button>
</p>
</div>
</template>
<script>
export default {
props: {
name: {type: String},
age: {type: Number, default: 18}
},
methods {
onAdd () {
this.$emit('click')
}
}
}
</script>
- React
 
interface IChildProps {
  name: string,
  age?: number,
  onAdd?: () => void
}
class Child extends React.Component<IChildProps, void> {
  static defaultProps = {
    age = 18,
    onAdd: () => {}
  }
  render () {
    const {name, age} = this.props
    return (
      <div className='child'>
        <p class='name'>{name}</p>
        <p class='age'>
          {age}
          <button onClick={this.onAdd}>add</button>
        </p>
      </div>
    )
  }
}
interface IParentState {
  age: number
}
class Parent extends React.Component<{}, IParentState> {
  state = {
    age: 18
  }
  onAdd = () => {
    this.setState({
      age: this.state.age + 1
    })
  }
  render () {
    const {name, age} = this.state
    return (
      <div className='parent'>
        <Child name='Tom' age={18} onAdd={this.onAdd}></Child>
      </div>
    )
  }
}
模板/JSX语法
- Vue
 
<!-- 可搭配其他模板语言,如Pug等 -->
<template>
<!-- 变量 -->
<div>{{name}}</div>
<!-- 表达式 -->
<div>{{ ok ? 'YES' : 'NO' }}</div>
<!-- HTML -->
<div v-html="rawHtml"></div>
<!-- 属性:属性名必须小写(kebab-case) -->
<div id="app"></div>
<div :id="dynamicId"></div>
<foo :task-count="18"></foo>
<foo :class="['item', foo]"></foo>
<foo :style="{'margin-top': '10px'}"></foo>
<!-- 事件 -->
<foo @action="onAction"></foo>
</template>
- React
 
render () {
  return (
    <!-- 变量 -->
    <div>{name}</div>
    <!-- 表达式 -->
    <div>{ ok ? 'YES' : 'NO' }</div>
    <!-- HTML -->
    <div dangerouslySetInnerHTML={rawHtml}></div>
    <!-- 属性 -->
    <div id='app'></div>
    <div id={dynamicId}></div>
    <foo taskCount={18}></foo>
    <foo className={'item ' + foo}></foo>
    <foo style={{marginTop: 10}}></foo>
    <!-- 事件 -->
    <foo onAction="onAction"></foo>
  )
}
条件渲染
- Vue
 
<template>
<div v-if="foo">foo</div>
</template> <template>
<div v-if="foo">foo</div>
<div v-else-if="bar">bar</div>
</template> <template>
<div v-if="foo">foo</div>
<div v-else-if="bar">bar</div>
<div v-else>other</div>
</template>
- React
 
render () {
  return foo && <div>foo</div>
}
render () {
  return foo ? <div>foo</div> : <div>bar</div>
}
render () {
  return (
    { foo ? <div>foo</div>
      : bar
      ? <div>bar</div>
      : <div>other</div>
    }
  )
}
列表渲染
- Vue
 
<template>
<div class='list'>
<div v-for="item in list" :key="item">{{item}}</div>
</div>
</template>
- React
 
render () {
  return (
    <div className='list'>
      {list.map((item) => <div key={item}>{item}</div>)}
    </div>
  )
}
// 或者
render () {
const items = list.map((item) => <div key={item}>{item}</div>) return (
<div className='list'>
{items}
</div>
)
}
表单&双向绑定
- Vue
 
<!-- 表单 -->
<template>
<form>
<input v-model="name">
<!--
相当于以下的语法糖:
<input v-bind:value="name" v-on:input="name = $event.target.value">
在组件中相当于
<foo v-bind:value="name" v-on:input="name = arguments[0]"></foo>
-->
</form>
</template>
<script>
export default {
data () {
return {
name: ''
}
}
}
</script>
<!-- Vue 2.3.0+ --> <!-- Parent.vue -->
<template>
<child :foo.sync="bar"></child>
<!--
sync只是语法糖,实际上拓展为:
<child :foo="bar" @update:foo="val => bar = val"></child>
-->
</template> <!-- Child.vue -->
<script>
export default {
methods: {
onChange () {
this.$emit('update:foo', newValue)
}
}
}
</script>
- React
 
interface IFooState {
  name: string
}
class Foo extends React.Component<{}, IFooState> {
  onChange = (e) => {
    const name = e.target.value
    this.setState({name})
  }
  render () {
    const {value} = this.state
    return (
      <div>
        <input value={value} onChange={this.onChange}/>
      </div>
    )
  }
}
内容分发
- Vue
 
<!-- Child -->
<template>
<!-- 必须有根元素 -->
<div class="child">
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
</template>
<script>
export default {}
</script> <!-- Parent -->
<template>
<div class="parent">
<child>
<p slot="header">header</p>
<p>content</p>
<p slot="footer">footer</p>
</child>
</div>
</template>
<script>
import Child from './Child'
export default {
components: {Child}
}
</script>
- React
 
interface IChildProps {
  header?: React.Node,
  children?: React.Node,
  footer?: React.Node
}
class Child extends React.Component<IChildProps, void> {
  render () {
    const {header, children, footer} = this.props
    return (
      <div className='child'>
        {header}
        {children}
        {footer}
      </div>
    )
  }
}
class Parent extends React.Component<{}, void> {
  render () {
    return (
      <div className='parent'>
        <Child
          className='child'
          header='header'}
          footer={<p>footer</p>}>
          <p>content</p>
        </Child>
      </div>
    )
  }
}
React和Vue特性和书写差异的更多相关文章
- 2017 年比较 Angular、React、Vue 三剑客(转载)
		
为 web 应用选择 JavaScript 开发框架是一件很费脑筋的事.现如今 Angular 和 React 非常流行,并且最近出现的新贵 VueJS 同样博得了很多人的关注.更重要的是,这只是一些 ...
 - 理解MVVM在react、vue中的使用
		
理解MVVM在react.vue中的使用 一:什么是MVC.为什么不用MVC 1:MVC的含义: M(modal):是应用程序中处理数据逻辑的部分. V (view) :是应用程序中数据显示的部分. ...
 - [译] 2017 年比较 Angular、React、Vue 三剑客
		
原文地址:Angular vs. React vs. Vue: A 2017 comparison 原文作者:Jens Neuhaus 译文出自:掘金翻译计划 本文永久链接:github.com/xi ...
 - React 还是 Vue: 你应该选择哪一个Web前端框架?
		
学还是要学的,用的多了,也就有更多的认识了,开发中遇到选择的时候也就简单起来了. 本文作者也做了总结: 如果你喜欢用(或希望能够用)模板搭建应用,请使用Vue 如果你喜欢简单和“能用就行”的东西 ...
 - 前端框架:react还是vue?
		
之前写了一篇前端框架的大汇总,主要介绍了当下主流的框架和其特性.最近除了bootstrap,就属react和vue最为热门,这篇就主要拿这两个框架来做一下详细对比. 究竟如何正确使用?作为小白的我们从 ...
 - 【转】前端框架天下三分:Angular React 和 Vue的比较
		
前端框架天下三分:Angular React 和 Vue的比较 原文链接:http://blog.csdn.net/haoshidai/article/details/52346865 前端这几年的技 ...
 - 【repost】前端学习总结(二十三)——前端框架天下三分:Angular React 和 Vue的比较
		
目录(?)[+] 前端这几年的技术发展很快,细分下来,主要可以分成四个方面: 1.开发语言技术,主要是ES6&7,coffeescript,typescript等: 2.开发框架,如Ang ...
 - react和vue的异同点
		
一.相似处1.使用Virtual DOM,都有jsx,性能好.2.提供了响应式(reactive)和可组合的视图组件(composable view component).3.将注意力集中保持在核心库 ...
 - 【总结】前端框架:react还是vue?
		
之前写了一篇前端框架的大汇总,主要介绍了当下主流的框架和其特性.最近除了bootstrap,就属react和vue最为热门,这篇就主要拿这两个框架来做一下详细对比. 究竟如何正确使用?作为小白的我们从 ...
 
随机推荐
- mysql内连接、左连接、右连接
			
内连接(INNER JOIN)(典型的连接运算,使用像 = 或 <> 之类的比较运算符).包括相等连接和自然连接. 内连接使用比较运算符根据每个表共有的列的值匹配两个表中的 ...
 - Android View坐标系详解(getTop()、getX、getTranslationX...)
			
View 提供了如下 5 种方法获取 View 的坐标:1. View.getTop().View.getLeft().View.getBottom().View.getRight();2. View ...
 - BAT修改文本内容
			
@echo off (for /f "delims=" %%a in (文件名) do ( set "str=%%a" setlocal enabledelay ...
 - 二维码扫描开源库ZXing定制化【转】
			
转自:http://www.cnblogs.com/sickworm/p/4562081.html 最近在用ZXing这个开源库做二维码的扫描模块,开发过程的一些代码修改和裁剪的经验和大家分享一下. ...
 - [转]hadoop新手错误解决方法
			
解决Exception: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z 等一系列问题,lja ...
 - PHP跨域访问
			
1.允许所有域名访问 header('Access-Control-Allow-Origin: *'); 2.允许单个域名访问 header('Access-Control-Allow-Origin: ...
 - PHP与MySQL设计模式:代理模式
			
一.数据库连接通用类 重要的接口: 接口用来存储MySQL连接数据.实现这个接口的类都可以使用这些数据. 通过接口可以隔离出程序中一个简单而必要的部分,任何程序都可以实现这个接口. 接口通过inter ...
 - HTML5本地存储localStorage、sessionStorage及IE专属UserData
			
By:王美建 from:http://www.cnblogs.com/wangmeijian/p/4518606.html 转载请保留署名和出处! 在客户端存储数据用的最普遍的方式非cookie莫属, ...
 - Jmeter脚本录制方法(一)分别使用Badboy录制和Jmeter自带的代理服务器录制
			
Jmeter录制方式分三种,分别是:使用Badboy录制.Jmeter自带的代理服务器录制和手工录制,今天先介绍前两种录制方法. Badboy录制 Badboy是用C++开发的动态应用测试工具, 其拥 ...
 - 七夕情人节表白-纯JS实现3D心形+图片旋转
			
七夕情人节就快到了,这里献上纯js表白神器-心里都是你,预览: 技术点:css-3d.js-随机色.js-transform 1.html: <div class="heart&quo ...