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特性和书写差异的更多相关文章

  1. 2017 年比较 Angular、React、Vue 三剑客(转载)

    为 web 应用选择 JavaScript 开发框架是一件很费脑筋的事.现如今 Angular 和 React 非常流行,并且最近出现的新贵 VueJS 同样博得了很多人的关注.更重要的是,这只是一些 ...

  2. 理解MVVM在react、vue中的使用

    理解MVVM在react.vue中的使用 一:什么是MVC.为什么不用MVC 1:MVC的含义: M(modal):是应用程序中处理数据逻辑的部分. V (view)  :是应用程序中数据显示的部分. ...

  3. [译] 2017 年比较 Angular、React、Vue 三剑客

    原文地址:Angular vs. React vs. Vue: A 2017 comparison 原文作者:Jens Neuhaus 译文出自:掘金翻译计划 本文永久链接:github.com/xi ...

  4. React 还是 Vue: 你应该选择哪一个Web前端框架?

    学还是要学的,用的多了,也就有更多的认识了,开发中遇到选择的时候也就简单起来了. 本文作者也做了总结: 如果你喜欢用(或希望能够用)模板搭建应用,请使用Vue    如果你喜欢简单和“能用就行”的东西 ...

  5. 前端框架:react还是vue?

    之前写了一篇前端框架的大汇总,主要介绍了当下主流的框架和其特性.最近除了bootstrap,就属react和vue最为热门,这篇就主要拿这两个框架来做一下详细对比. 究竟如何正确使用?作为小白的我们从 ...

  6. 【转】前端框架天下三分:Angular React 和 Vue的比较

    前端框架天下三分:Angular React 和 Vue的比较 原文链接:http://blog.csdn.net/haoshidai/article/details/52346865 前端这几年的技 ...

  7. 【repost】前端学习总结(二十三)——前端框架天下三分:Angular React 和 Vue的比较

    目录(?)[+]   前端这几年的技术发展很快,细分下来,主要可以分成四个方面: 1.开发语言技术,主要是ES6&7,coffeescript,typescript等: 2.开发框架,如Ang ...

  8. react和vue的异同点

    一.相似处1.使用Virtual DOM,都有jsx,性能好.2.提供了响应式(reactive)和可组合的视图组件(composable view component).3.将注意力集中保持在核心库 ...

  9. 【总结】前端框架:react还是vue?

    之前写了一篇前端框架的大汇总,主要介绍了当下主流的框架和其特性.最近除了bootstrap,就属react和vue最为热门,这篇就主要拿这两个框架来做一下详细对比. 究竟如何正确使用?作为小白的我们从 ...

随机推荐

  1. springcloud使用Hystrix实现微服务的容错处理

    使用Hystrix实现微服务的容错处理 容错机制 如果服务提供者相应非常缓慢,那么消费者对提供者的请求就会被强制等待,知道提供者相应超时.在高负载场景下,如果不作任何处理,此类问题可能会导致服务消费者 ...

  2. javascript-词法分析解析

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 洛谷P2613有理数取余

    传送门 #include <iostream> #include <cstdio> #include <cstring> #include <algorith ...

  4. android之ExpandableListView 无法展开

    1.Button 对,没错,就是这个button组件,不知道出现都少次过问题,很多都是它造成的! 最常见的问题:ExpandableListView无法展开,OnItemClickListener不响 ...

  5. SqlServer自定义函数Function中调用with as

    SET QUOTED_IDENTIFIER ON 标识符可以由双引号分隔,而文字必须由单引号分隔 SET QUOTED_IDENTIFIER OFF 标识符不可加引号,且必须遵守所有 Transact ...

  6. 《深入分析JavaWeb技术内幕》学习笔记

    第一章 深入Web请求过程 1.1 B/S网站架构概述 HTTP协议采用无状态的短连接的通信方式.通常一次请求就完成一次数据交互,通常也对应一个业务逻辑. 当在浏览器里输入一个URL,首先会请求DNS ...

  7. 第一届CCF软件能力认证

    1.相反数 问题描述 有 N 个非零且各不相同的整数.请你编一个程序求出它们中有多少对相反数(a 和 -a 为一对相反数). 输入格式 第一行包含一个正整数 N.(1 ≤ N ≤ 500). 第二行为 ...

  8. nginx log 错误502 upstream sent too big header while reading response header from upstream

    cookies的值超出了范围我是说 看看了一下日志 错误502 upstream sent too big header while reading response header from upst ...

  9. 【LOJ】#2492. 「BJOI2018」二进制

    题解 每次开这样的数据结构题感想都大概是如下两点 1.为什么别人代码长度都是我的1/2???? 2.为什么我运行时间都是他们的两倍???? 简单分析一下,我们关注一个区间是否合法只关注这个区间有多少个 ...

  10. Successor hdu 4366 线段树

    题意: 现在n个人,其中编号0的是老板,之后n-1个员工,每个员工只有一个上司,有一个忠诚值和能力值.每次要解雇一个人的时候,从他的下属中选取能力值大于他的且忠诚值最高的一个,若不存在则输出-1.共m ...