LoginSignup
79
79

More than 3 years have passed since last update.

react.js(next.js)とvue.js(nuxt.js)の違いをソースで確認してみましょう

Last updated at Posted at 2020-10-22

概要

最近人気のフロントエンドの言語であるreact.js, vue.js, augular.jsがあります
angular.jsは下落傾向で、react.jsvue.jsはほぼ同じように人気があります

この記事では、react.jsvue.jsに対する違いと
next.jsnuxt.jsに対する違いをソースで確認してみましょう

next.jsとnuxt.jsって何?

next.jsreact.jsSSR(ServerSideRender)フレームワークです
nuxt.jsvue.jsSSR(ServerSideRender)フレームワークです

react.jsvue.jsは、基本的にCSR(Client Side Render)です

CSR(Client Side Render)の場合、検索エンジンに露出できない短所があり、
最初のスクリプトロード時間が長いという短所があります

react.jsvue.jsのどちらもBtoBの場合、特別な問題はありませんが、
BtoCの場合、検索エンジンの露出が重要な要素となっているため、
結局はwebpackをカスタマイズするかnext.jsnuxt.jsに変えることになります。

プロジェクト作成の違い


yarn global add create-next-app
create-next-app next-tutorial
yarn dev

next.jsの場合、create-next-appモジュールを利用してプロジェクトを作成します

yarn global add create-nuxt-app
create-nuxt-app nuxt-tutorial
yarn dev

nuxt.jsの場合、create-nuxt-appモジュールを利用してプロジェクトを作成します

component基本

next.jsnuxt.jsはページディレクトリを利用してrouteします
基本的なコンポーネントソースの違いを確認してみましょう

next.js (react.js)

/pages/index.js

import { useEffect } from "react"

const Home = () => {
  useEffect(() => {
    console.log('mounted')
    return () => {
      console.log('unmounted')
    };
  }, []);

  return (
    <div>
      hello next.js
    </div>
  )
}

export default Home

nuxt.js (vue.js)

/pages/index.vue

<template>
  <div>
    hello nuxt.js
  </div>
</template>

<script>
export default {
  mounted() {
    console.log('mounted')
  },
  unmounted() {
    console.log('unmounted')
  }
}
</script>

react.jsの場合、JSXを使用してレンダリングします
vue.jsの場合、htmlを使用してレンダリングします
ライフサイクルは文法は少し違いますが、構造はほとんど似ています

react.jsの場合、JSXを学ぶ必要があるためパブリッシャーが作業が難しいため、
日本ではvue.jsが人気が高いと言われています

component state

next.js (react.js)

/pages/index.js

import { useState, useEffect } from "react"

const Home = () => {
  const [count, setCount] = useState(0)

  return (
    <div>
      count : {count}
    </div>
  )
}

export default Home

nuxt.js (vue.js)

/pages/index.vue

<template>
  <div>
    count : {{count}}
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    }
  }
}
</script>

react.jsの場合、react hooksであるuseStateを利用してstateを作成します
vue.jsの場合、データ関数を利用してstateを作成します

react.jsの場合、{}を利用して変数をレンダリングします
vue.jsの場合、{{ }}を利用して変数をレンダリングします

counter

next.js (react.js)

/pages/index.js

import { useState, useEffect } from "react"

const Home = () => {
  const [count, setCount] = useState(0)

  const increaseCount = () => {
    setCount(count + 1)
  }

  const decreaseCount = () => {
    setCount(count - 1)
  }

  return (
    <>
      <div>
        count : {count}
      </div>
      <button onClick={increaseCount}>+</button>
      <button onClick={decreaseCount}>-</button>
    </>
  )
}

export default Home

nuxt.js (vue.js)

/pages/index.vue

<template>
  <div>
    <div>
      count : {{count}}
    </div>
    <button @click="increaseCount()">+</button>
    <button @click="decreaseCount()">-</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increaseCount() {
      this.count +=  1
    },
    decreaseCount() {
      this.count -= 1
    }
  }
}
</script>

react.jsの場合、setStateを使用してstateをアップデートします
vue.jsの場合、thisを使用してstateをアップデートします

react.jsの場合、コンポーネント内部にイベント関数を作成します
vue.jsの場合、methods内部にイベント関数を作成します

react.jsの場合、onClickプロパティを利用してバインディングします
vue.jsの場合、@clickプロパティを利用してバインディングします

childコンポーネントにsteteとイベント関数を伝達

next.js (react.js)

/components/sample.js

const Sample = (props) => {
  return (
    <>
      <div>
        count : {props.count}
      </div>
      <button onClick={props.increaseCount}>+</button>
      <button onClick={props.decreaseCount}>-</button>
    </>
  )
}

export default Sample

/pages/index.js

import { useState, useEffect } from "react"
import Sample from "../components/Sample"

const Home = () => {
  const [count, setCount] = useState(0)

  const increaseCount = () => {
    setCount(count + 1)
  }

  const decreaseCount = () => {
    setCount(count - 1)
  }

  return (
    <>
      <Sample 
        count={count}
        increaseCount={increaseCount}
        decreaseCount={decreaseCount}
      />
    </>
  )
}

export default Home

nuxt.js (vue.js)

/components/sample.vue

<template>
  <div>
    <div>
      count : {{count}}
    </div>
    <button @click="$emit('increase-count')">+</button>
    <button @click="$emit('decrease-count')">-</button>
  </div>
</template>

<script>
export default {
  props: ['count'],
  emits: ['increase-count', 'decrease-count']
}
</script>

/pages/index.vue

<template>
  <div>
    <Sample 
      :count="count"
      @increase-count="increaseCount()"
      @decrease-count="decreaseCount()"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increaseCount() {
      this.count +=  1
    },
    decreaseCount() {
      this.count -= 1
    }
  }
}
</script>

react.jsの場合、propsを利用してchildコンポーネントにstateやイベント関数を伝達します
vue.jsの場合、各属性を利用してchildコンポーネントにstateやイベント関数を伝達します

react.jsの場合、すぐにバインディングして使用できます
vue.jsの場合、$emitを利用してバインディングすると使用できます

SSR function

next.js (react.js)

/pages/index.js

const Home = ({data}) => {
  return (
    <>
      {data}
    </>
  )
}

Home.getInitialProps = () => {
  return { data: 'SSR' }
}

export default Home

nuxt.js (vue.js)

/pages/index.vue

<template>
  <div>
    {{data}}
  </div>
</template>

<script>
export default {
  asyncData() {
    return { data: 'SSR' }
  },
}
</script>

SSRフレームワークの場合、htmlが構成される前にデータをfetchできる関数を提供します

next.jsの場合、getInitialPropsを使用します
nuxt.jsの場合asyncDataを使います

state 管理

vue.jsの場合、vuexを主に使います
vuex.png

react.jsの場合、主にreduxを使用します
redux-logo-landscape.png

まとめ

最も人気のある言語を簡単に2つ比較してみました
ご覧のとおり vue.jsreact.jsもメカニズムは似ています
またnext.jsnuxt.jsもメカニズムが似ています
したがって、一つを勉強すれば他の言語も簡単にできます

皆さんはvue.jsreact.js、どちらが好きですか?

79
79
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
79
79