vue和react的区别

1、 创建组件
React
React 有两种类型的组件,分别是functional component, class component,所以有两种定义方式:

functional component

function Test(props) {
return (


{props.name}

)
}

ReactDOM.render(
,
document.getElementById(‘app’)
)
class component
用构造函数 + 原型实现继承

// 注意:基于 ES6 中的class,需要配合 babel 将代码转化为浏览器识别的ES5语法
// 安装:npm i -D babel-preset-env
class Test extends React.Component() {
constructor(props) {
// super一定要写,继承React.Component
super(props);
// state在里面定义
this.state = { name : ‘daisy’};
}
// class创建的组件中 必须有render方法,且显示return内容或者null
render() {
return (


{this.state.name}

)
}
}
React中要求组件名字一定是大写,这样来跟原生的html元素做区分。

Vue
分为局部注册跟全局注册

全局注册

Vue.component(‘my-component-name’, { /* … */ })
局部注册

var ComponentA = { /* … */ }

new Vue({
el: ‘#app’,
components: {
‘component-a’: ComponentA,
}
})
全局注册就是在注册之后,各个地方都可以使用。而局部注册就是只在这个vue 实例中才能使用。

2、数据绑定
React跟vue的思想都是开发者只需要去操作数据,至于数据在网页中如何更新,就是它们的事情了,这个就要靠数据绑定。

那么在React/vue中如何做到数据绑定呢。

React
采用JSX语法,变量用{}包裹即可。

const name = ‘Josh Perez’;
const element =

Hello, {name}

;

ReactDOM.render(
element,
document.getElementById(‘root’)
);
注: {}里字可以是js表达式,不能是语句,这个跟vue一样。

Vue
使用Mustache(插值语法) {{ }}从数据对象data中获取数据,当这个数据发生改变,插值处的内容就会更新。

注:{{ }}只能出现JS表达式,不能是js语句

Hello, {{ msg }}.

{{ message.split('').reverse().join('') }}

//错误。js语句不支持
{{ var a = 1 }}
3、 模板语法
模板语法里分别从下面几个方面进行对比:

原始html
条件渲染
html属性
绑定事件
React
原始html: 使用dangerouslySetInnerHTML

render() {
const isLoggedIn = this.state.isLoggedIn;
return (


isHappy ?
yes i am
:
no


);
}

render() {
const isLoggedIn = this.state.isLoggedIn;
return (


isShow &&
hello word


);
}
html 属性:跟原生一样直接写不过要换成驼峰式tab-index => tabIndex,React 16以后还支持自定义属性。

绑定事件:直接写,但是改成驼峰onClick这样的形式,同时传入的不是字符串,而是传入一个函数作为事件处理函数

// 原生html

Activate Lasers

// React

Activate Lasers

既然说到了事件,就多撤一句。如果你需要阻止默认事件,
不能用return false的方式,而需要显式使用preventDefault。
而vue会提供一个更简单的方式,后面再说。

function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log(‘The link was clicked.’);
}

return (

Click me

);
}
Vue
原始html: 用v-html


条件渲染:

// v-if 会根据Seen的值真的去移除dom节点

现在你看到我了

// 而v-show只会去改变css的值

现在你看到我了

而对于比较复杂的逻辑,vue也可以hold住。
A
B
C
Not A/B/C
html属性:需要用v-bind来指定

绑定事件:

<a @click=“doSomething”>…
另外,vue会提供一些事件修饰符,来简化调用event.preventDefault(),event.stopPropagation()的需求。

stop
prevent
capture
self
once
passive

4、内部状态(属性)
React
在React,组件内部自己维护的状态叫State,不能直接去改内部状态state,而是通过setState。

class Test extends React.Component() {
constructor(props) {
// super一定要写,继承React.Component
super(props);
// state在里面定义
this.state = { name : ‘daisy’ };
}
changeName () => {
this.setState({ name: ‘Lily’ })
}
render() {
return (


{this.state.name}

)
}
}
Vue
在Vue, 组件内部自己维护的状态其实就是Data。如果要改的话,直接在方法里通过this或者是通过vue对象来改。

var vm = new Vue({
el: ‘#app’,
// 用于给 View 提供数据,相当于React的state
data: {
msg: ‘Hello Vue’
},
method: {
changeMsg: function() {
this.msg = ‘Hello daisy’
}
}
})

// 或者
vm.msg = ‘daisy’;
但是Vue除了在Data里定义的属性之外,还额外定义计算属性跟侦听属性。

为什么要多两种呢?
计算属性是为了应付逻辑比较复杂的情况。比如:

data = { message: ‘’};

{{ message.split('').reverse().join('') }}
在这里需要对message进行多一层的处理,但是直接写在模板里面,觉得不好维护,也不够优雅。

所以Vue就多搞了一个计算属性。

var vm = new Vue({
el: ‘#example’,
data: {
message: ‘Hello’
},
computed: {
reversedMessage: function () {
return this.message.split(’’).reverse().join(’’)
}
}
})

{ reversedMessage }
这个reversedMessage 属性将会监听message的改变,而自动重新计算。

为啥React不需要这个属性呢?

因为React有render函数,你可以在里面随便多定义一个变量。
每一次this.state.message改变的时候,都一定会调用render函数重新渲染,所以就相当于重新计算reversedMessage了。

render() {
const reversedMessage = this.state.message.split(’’).reverse().join(’’)
return (


{reversedMessage}

)
}
侦听属性感觉跟计算属性很像,但是他们又有不同。
侦听属性是为了可以监听到数据的改变,然后做一些异步的或者开销大的操作。

var watchExampleVM = new Vue({
el: ‘#watch-example’,
data: {
question: ‘aaa’,
},
watch: {
// 如果 question 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.getAnswer()
}
},
methods: {
getAnswer: function () {
// AJax 请求
}
}
})
同样的问题,为啥React不需要这个属性呢?
因为React里已经有方法可以做到了。

React 15的版本,可以通过componentWillReceiveProps 来实现

componentWillReceiveProps(nextProps) {
if (nextProps.id !== this.props.id) {
this.setState({externalData: null});
this._loadAsyncData(nextProps.id);
}
}
React 16的版本,可以通过getDerivedStateFromProps,componentDidUpdate来实现。

static getDerivedStateFromProps(nextProps, prevState) {
// Store prevId in state so we can compare when props change.
if (nextProps.id !== prevState.prevId) {
return {
externalData: null,
prevId: nextProps.id,
};
}
// No state update necessary
return null;
}
componentDidUpdate(prevProps, prevState) {
if (this.state.externalData === null) {
this._loadAsyncData(this.props.id);
}
}
5、Props
props 一般指的是父组件传给子组件的属性。

React
React 的props 如果是静态的就直接传,动态的就用变量{}来传,还可以传入方法。

class Test extends React.Component {
constructor(super) {
super(props);
this.state = { name : ‘daisy’}
}
onClick( ) => {
console.log(“onClick”);
}
render() {
return (
;
;
;
// 传入的方法其实在子组件里,在props也可以拿到。
// 使用的时候,直接this.props.handleClick()就可以了。
)
}
}
由于React写的久了,我默认传props的时候,字符串就是静态的,如果是变量,或者方法,就用{},结果vue完全不是的,他们全都是传字符串!

Vue
Vue的静态props跟动态props传的方法不一样。
传入的值title为一个常量(静态prop)时,不加v-bind


传入的值title为一个变量(动态prop)时,加v-bind


因为如果不用v-bind,vue就会认为这只是普通的字符串。
所以用了v-bind才可以转成变量,然后vue会去data里找这个值。

传入方法的话,一样要使用v-on,子组件要用emit方法来触发。

<Welcome v-on:handleClick=“onClick” } />;
// 子组件里要用 e m i t 方 法 来 触 发 它 < b u t t o n v − o n : c l i c k = " emit方法来触发它 <button v-on:click=" emit<buttonvon:click="emit(‘handleClick’)">
Enlarge text

大家也看到了,React跟Vue对于props的处理还是很不同的。对于一个从react切过来的人,实在需要点时间去适应vue的props。

6、双向绑定
React
使用受控组件,就是input的value直接就是state的值。
然后监听相应的change事件,用setState改变state的值。

class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ‘’};

this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);

}

// 这里通过setState去改变state的值
handleChange(event) {
this.setState({value: event.target.value});
}

handleSubmit(event) {
alert('提交的名字: ’ + this.state.value);
event.preventDefault();
}

render() {
return (




);
}
}
Vue
vue采用v-model的形式

Message is: {{ message }}

实际上v-model 是一个语法糖, 上面可以翻译成:

<input :value='message' @input="message = $event.targer.value">
input本身有个oninput事件,每当输入框发生变化,就会触发onput,将最新的value传给他。

v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:

text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。
v-model 不仅仅可以用在原生html元素上,还可以用在组件上。用在组件上的时候v-on用于监听事件,emit用来触发事件。

// 相当于是 // 这里用v-on监听事件,相当于传给了子组件value,还有input方法 {{price}}
Vue.component('currency-input', { template: `

var demo = new Vue({
el: ‘#demo’,
data: {
price: 100,
}
})
总结一下,React在双向绑定方面,其实还是用着state在帮忙,传给子组件的方法也是直接传props即可,子组件直接通过props来调用。

;
// 传入的方法其实在子组件里,在props也可以拿到。
// 使用的时候,直接this.props.handleClick()就可以了。
而Vue是利用了v-model,自动帮你做了这件事。而在传给子组件的时候,需要用$emit来配合。
同时,你一定要知道v-model 实际上是可以翻译成这样的语法糖。

<input :value=‘message’ @input=“message = $event.targer.value”>`
这样你才知道父组件在用v-model的时候,实际上传了value,跟input给子组件。

7、渲染child节点
React
React里可以通过this.props.children 获取。

class NotesList extends React.Component {
render() {
return (


  1. {
    .map(function (child) {
    return
  2. {child}

  3. // 渲染出来就是
    //
  4. hello

  5. //
  6. world

  7. })
    }

)
}
}

React.render(

hello
world
,
document.body
);
Vue
Vue引入了一个插槽的概念。
通过父组件中插入一个的标签来实现。

// 父组件 Message的html

hello,world

// 在调用的时候

hello
daisy

最后就会渲染出来

hello,world hello daisy
Vue还提供了指定区域的插槽功能,比如

// 父组件 Message的html

hello,world

// 在调用的时候,需要使用元素,用上面的
// v-slot 来指定名称


daisy


huang

这样最后渲染的结果为:
hello,world daisy huang
而React的话可以直接通过this.props.chilren[0] [1] 等拿到不同的元素,所以就没有提供这个了。

而且就我的实践经验来看,第二种用法感觉实际用的其实很少,掌握第一种就行了。一般要用都是直接塞进去一段内容。

当然插槽还有好多内容,详细可以查阅文档

8、生命周期
我觉得React、vue的生命周期都大同小异,主要就是创建 -> 更新 -> 销毁。具体一些名字不同而已。

React
react 15
react 16
Vue

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值