日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

react 与 Vue的一些比较

發布時間:2024/4/14 vue 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react 与 Vue的一些比较 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文地址

組件開發

特性對比

眾所周知,Vue和React都有那么一個特性,那就是可以讓我們進行組件化開發,這樣可以讓代碼得到更好的重用以及解耦,在架構定位中這個應該叫縱向分層吧。但是,兩個框架開發組件的寫法都有所不同(這個不同是基于我的開發習慣),下面先看一下不同的地方。

首先是React,個人習慣于es6的寫法(從來沒用過es5的createClass的寫法):

import React, { Component } from 'react'; import propTypes from 'prop-types';export default class Demo extends Component {state = {text: 'hello world'};static propTypes = {title: PropTypes.String}static defaultProps = {title: 'React Demo'}setText = e => {this.setState({text: '點擊了按鈕'})}componentWillReveiveProps(nextProps) {console.log(`標題從 ${this.props.title} 變為了 ${nextProps.title}`)}render() {const { title } = this.props;const { text } = this.state;return <div><h1>{title}</h1><span>{text}<span><button onClick={this.setText}>按鈕<button></div>} }

下面是常見vue的寫法:

<template><div><h1>{{title}}</h1><span>{{text}}<span><button @click="setText">按鈕</button></div> </template><script> export default {props: {title: {type: String,default: 'Vue Demo'}},watch: {title(newTitle, oldTitle) {console.log(`標題從 ${oldTile} 變為了 ${newTitle}`)}},data() {return {text: 'hello world'}},methods: {setText(e) {this.text = '點擊了按鈕';}} } </script>

這里的視圖渲染我們先忽略,下一節在詳細對比。

prop對比:

Vue的prop必須在props字段里聲明。React的prop不強制聲明,聲明時也可以使用prop-types對其聲明約束。
Vue的prop聲明過后掛在在組件的this下,需要的時候在this中獲取。React的prop存在組件的props字段中,使用的時候直接在this.props中獲取。
組件狀態對比,Vue為data,React為state:

Vue的狀態data需要在組件的data字段中以函數的方式聲明并返回一個對象。React的狀態state可以直接掛載在組件的state字段下,在使用之前初始化即可。
Vue的狀態data聲明后掛在在this下面,需要的是時候在this中獲取。React的狀態state存在組件的state字段中,使用的時候直接在this.state中獲取。
Vue的狀態更新可以直接對其進行賦值,視圖可以直接得到同步。React的狀態更新必須使用setState,否則視圖不會更新。
然后是組件方法對比:

Vue的方法需要在methods字段下聲明。React的方法用方法的方式聲明在組件下即可。
Vue與React使用方法的方式相同,因為都是掛載在組件中,直接在this中獲取即可。
計算屬性computed對比:

Vue有計算屬性在computed字段中聲明。React中無計算屬性特性,需要其他庫如mobx輔助完成。
Vue的計算屬性聲明后掛載在this下,需要的時候在this中獲取。
監聽數據對比:

Vue中可以在watch字段中對prop、data、computed進行對比,然后做相應的操作。在React所有變化需要在聲明周期componentWillReveiveProps中手動將state和prop進行對比。
對比完后發現,其實Vue給我的個人感覺就是自己在寫配置,只不過配置是以函數的形式在寫,然后Vue幫你把這些配置好的東西掛載到組件下面。而且prop、data、computed、方法所有都是掛載組件下,其實單單從js語法上很難以理解,比如說我在computed中,想獲取data的text數據,使用的是this.text來獲取,如果拋開vue,單單用js語法來看,其實this大多情況是指向computed對象的,所以個人覺得這樣的語法是反面向對象的。

這個時候在反過來看React的class寫法,本來就是屬于面向對象的寫法,狀態state歸狀態,屬性prop歸屬性,方法歸方法,想獲取什么內容,通過this直接獲取,更接近于JavaScript編程,相對來說比較好理解。

組件改造

針對Vue的反面向對象,我們可以更改其寫法,通過語法糖的形式,將其我們自己的寫法編譯成Vue需要的寫法。

vue-class-component
vue-class-component 是Vue英文官網推薦的一個包,可以以class的模式寫vue組件,它帶來了很多便利:

methods,鉤子都可以直接寫作class的方法
computed屬性可以直接通過get來獲得
初始化data可以聲明為class的屬性
其他的都可以放到Component裝飾器里
vue-property-decorator
vue-property-decorator 這個包完全依賴于vue-class-component,提供了多個裝飾器,輔助完成prop、watch、model等屬性的聲明。

編譯準備

由于使用的是裝飾器語法糖,我們需要在我們webpack的babel編譯器中對齊進行支持。

首先是class語法支持,針對babel6及更低的版本,需要配置babel的plugin中添加class語法支持插件babel-plugin-transform-class-properties,針對babel7,需要使用插件@babel/plugin-proposal-class-properties對class進行語法轉換。

然后是裝飾器語法支持,針對babel6及更低的版本,需要配置babel的plugin中添加裝飾器語法支持插件babel-plugin-transform-decorators-legacy,針對babel7,需要使用插件@babel/plugin-proposal-decorators對裝飾器進行語法轉換。

針對bable6,配置.babelrc如下

{"presets": ["env", "stage-1"],"plugins": ["transform-runtime","syntax-dynamic-import","transform-class-properties", // 新增class語法支持"transform-decorators-legacy" // 新增裝飾器語法支持] }

對于bable7,官方推薦直接使用@vue/apppreset,該預設包含了@babel/plugin-proposal-class-properties和@babel/plugin-proposal-decorators兩個插件,另外還包含了動態分割加載chunks支持@babel/plugin-syntax-dynamic-import,同時也包含了@babel/envpreset,.babelrc配置如下:

{"presets": [["@vue/app", {"loose": true,"decoratorsLegacy": true}]] }

重寫組件

編譯插件準備好之后,我們對上面的Vue組件進行改寫,代碼如下

<template><div><h1>{{title}}</h1><span>{{text}}<span><button @click="setText">按鈕</button></div> </template><script> import { Vue, Component, Watch, Prop } from 'vue-property-decorator';@Component export default class Demo extends Vue {text = 'hello world';@Prop({type: String, default: 'Vue Demo'}) title;@Watch('title')titleChange(newTitle, oldTitle) {console.log(`標題從 ${oldTile} 變為了 ${newTitle}`)}setText(e) {this.text = '點擊了按鈕';} } </script>

到此為止,我們的組件改寫完畢,相對先前的“寫配置”的寫法,看起來相對來說要好理解一些吧。

注意:Vue的class的寫法的methods還是沒辦法使用箭頭函數進行的,詳細原因這里就不展開,大概就是因為Vue內部掛載函數的方式的原因。

視圖開發

特性對比

針對視圖的開發,Vue推崇html、js、css分離的寫法,React推崇all-in-js,所有都在js中進行寫法。

當然各有各的好處,如Vue將其進行分離,代碼易讀性較好,但是在html中無法完美的展示JavaScript的編程能力,而對于React的jsx寫法,因為有JavaScript的編程語法支持,讓我們更靈活的完成視圖開發。

對于這類不靈活的情況,Vue也對jsx進行了支持,只需要在babel中添加插件babel-plugin-transform-vue-jsx、babel-plugin-syntax-jsx、babel-helper-vue-jsx-merge-props(babel6,對于babel7,官方推薦的@vue/app預設中已包含了jsx的轉化插件),我們就可以像React一樣,在組件中聲明render函數并返回jsx對象,如下我們對上一節的組件進行改造:

組件改造

<script> import { Vue, Component, Watch, Prop } from 'vue-property-decorator';@Component export default class Demo extends Vue {title = 'hello world';@Prop({type: String, default: 'Vue Demo'}) title;@Watch('title')titleChange(newTitle, oldTitle) {console.log(`標題從 ${oldTile} 變為了 ${newTitle}`)}setText(e) {this.text = '點擊了按鈕';}render() {const { title, text } = this;return <div><h1>{title}</h1><span>{text}<span><button onClick={this.setText}>按鈕<button></div>} } </script>

Vue的jsx使用注意點
寫到這里,也基本上發現其寫法已經與React的class寫法雷同了。那么Vue的jsx和React的jsx有什么不同呢。

在React的jsx語法需要React支持,也就是說,在你使用jsx的模塊中,必須引進React。

而Vue的jsx語法需要Vue的createElement支持,也就是說在你的jsx語法的作用域當中,必須存在變量h,變量h為createElement的別名,這是Vue生態系統中的一個通用慣例,在render中h變量由編譯器自動注入到作用域中,自動注入詳情見plugin-transform-vue-jsx,如果沒有變量h,需要從組件中獲取并聲明,代碼如下:

const h = this.$createElement;
這里借助官方的一個例子,基本包含了所有Vue的jsx常用語法,如下:

// ... render (h) {return (<div// normal attributes or component props.id="foo"// DOM properties are prefixed with `domProps`domPropsInnerHTML="bar"// event listeners are prefixed with `on` or `nativeOn`onClick={this.clickHandler}nativeOnClick={this.nativeClickHandler}// other special top-level propertiesclass={{ foo: true, bar: false }}style={{ color: 'red', fontSize: '14px' }}key="key"ref="ref"// assign the `ref` is used on elements/components with v-forrefInForslot="slot"></div>) }

但是,Vue的jsx語法無法支持Vue的內建指令,唯一的例外是v-show,該指令可以使用v-show={value}的語法。大多數指令都可以用編程方式實現,比如v-if就是一個三元表達式,v-for就是一個array.map()等。

如果是自定義指令,可以使用v-name={value}語法,但是該語法不支持指令的參數arguments和修飾器modifier。有以下兩個解決方法:

將所有內容以一個對象傳入,如:v-name={{ value, modifier: true }}
使用原生的vnode指令數據格式,如:
const directives = [
{ name: 'my-dir', value: 123, modifiers: { abc: true } }
]

return <div {...{ directives }}/>
那么,我們什么時候使用jsx,什么時候template呢?很明顯,面對那么復雜多變的視圖渲染,我們使用jsx語法更能得心應手,面對簡單的視圖,我們使用template能開發得更快。

狀態管理

特性對比

針對狀態管理,Vue的Vuex和React的Redux很雷同,都是Flow數據流。

對于React來說,state需要通過mapStateToProps將state傳入到組件的props中,action需要通過mapDispatchToProps將action注入到組件的props中,然后在組件的props中獲取并執行。

而在Vue中,store在組件的$store中,可以直接this.$store.dispatch(actionType)來分發action,屬性也可以通過mapState,或者mapGetter把state或者getter掛載到組件的computed下,更粗暴的可以直接this.$store.state或者this.$store.getter獲取,非常方便。

組件改造
我們為了更貼切于es6的class寫法,更好的配合vue-class-component,我們需要通過其他的方式將store的數據注入到組件中。

vuex-class
vuex-class,這個包的出現,就是為了更好的講Vuex與class方式的Vue組件連接起來。

如下,我們聲明一個store

import Vuex from 'vuex';const store = new Vuex.Store({modules: {foo: {namespaced: true,state: {text: 'hello world',},actions: {setTextAction: ({commit}, newText) => {commit('setText', newText);}},mutations: {setText: (state, newText) => {state.text = newText;} }}} })

針對這個store,我們改寫我們上一章節的組件

<template><div><h1>{{title}}</h1><span>{{text}}<span><button @click="setText">按鈕</button></div> </template><script> import { Vue, Component, Watch, Prop } from 'vue-property-decorator'; import { namespace } from 'vuex-class';const fooModule = namespace('foo');@Component export default class Demo extends Vue {@fooModule.State('text') text;@fooModule.Action('setTextAction') setTextAction;@Prop({type: String, default: 'Vue Demo'}) title;@Watch('title')titleChange(newTitle, oldTitle) {console.log(`標題從 ${oldTile} 變為了 ${newTitle}`)}setText(e) {this.setTextAction('點擊了按鈕');} } </script>

這里可以發現,store聲明了一個foo模塊,然后在使用的時候從store中取出了foo模塊,然后使用裝飾器的形式將state和action注入到組件中,我們就可以省去dispatch的代碼,讓語法糖幫我們dispatch。這樣的代碼,看起來更貼切與面向對象。。。好吧,我承認這個代碼越寫越像Java了。

然而,之前的我并不是使用Redux開發React的,而是Mobx,所以這種 dispatch -> action -> matation -> state 的形式對我來說也不是很爽,我還是更喜歡把狀態管理也以class的形式去編寫,這個時候我又找了另外一個包vuex-module-decorators來改寫我的store.module。

下面我們改寫上面的store:

import Vuex from 'vuex'; import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators';@Module class foo extends VuexModule {text = 'hello world'@MutationsetText(text) {this.text = text;}@Action({ commit: 'setText' })setTextAction(text) {return text;} }const store = new Vuex.Store({modules: {foo: foo }) export default store;

這樣,我們的項目準備基本上完畢了,把Vue組件和Vuex狀態管理以class的形式來編寫。大概是我覺得es5的寫法顯得不太優雅吧,沒有es6的寫法那么高端。

結束
class語法和裝飾器decorators語法都是ES6的提案,都帶給了前端不一樣的編程體驗,大概也是前端的一個比較大的革命吧,我們應該擁抱這樣的革命變化。

總結

以上是生活随笔為你收集整理的react 与 Vue的一些比较的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。