[SSR] Nuxt.jsの起動


🤔 Nuxt ?
NuxtはVueです.jsを使用してWebのフレームワークをすばやく作成
=>フレームのフレーム!
❗️ 👍 Webアプリケーションの作成に必要なリポジトリ(View X、ルータ、Axiosなど)を事前に設定します.
単一ページアプリケーション、サーバ側レンダリング、静的Webサイトの簡単な作成
サーバ側レンダリング(Server Side Rendering)
サーバからWebコンテンツを作成し、クライアント(ブラウザ)に送信し、画面に描画します.
❗️ 👍 SPAの作成には、通常クライアントレンダリングが使用されます.
初期運転速度が遅く、検索エンジン最適化(SEO)が困難.
これに対して補充することができます!
また、リンクを共有する場合、OGタグは様々なオープングラフ情報を表すことはできません.
単一ページアプリケーション
空のHTMLをサーバからブラウザに捨て、hashChangeEventなどのURLを変更します.
内部でJS操作でDOMの形状を描く
📚 リファレンス
Nuxt.js公式ドキュメントサイト
板橋隊長ブログ-Nuxt部分
」Nuxtのメリット
  • 検索エンジン最適化
  • 初期項目設置コストを低減し、生産性を向上させる
  • ライブラリのインストールとプロファイル(たとえば
  • ルータとストア)X
  • が必要です.
  • ファイルのルーティングに基づく.自動生成プロファイル
  • ページのロード速度とユーザー体験の向上
  • ブラウザは、サーバ
  • に作業を割り当てる.
    デフォルトは
  • コードジャンプ
  • です.
    個人的に思う最大のメリットは、とても便利で簡単…!
    既存のvueに詳しい人は感嘆して面白い製品を開発します!

    バトルNuxtの特徴
  • サーバ側レンダリング
  • 標準化フォルダ構造(レイアウト、ストレージ、ミドルウェア、プラグインなど)
  • 非同期データ要求属性
  • ES 6/ES 6+変換
  • その他の設定、
  • Webパッケージを含む
    」フォルダ構造/ルーティング

    mainがページフォルダにある場合.vueファイルを作成する場合
    構築後、routerファイルは自動的に/mainパスを生成し、そのコンポーネントを表示します.
    なんてことだ.

    以上のように🗂 pagesフォルダにファイルを作成した場合、router.jsに自動的に追加されます.
    urlに入ると、コンポーネントが表示されます.
    url構造により、フォルダ、インデックス、{id}などのvueファイルを使用してルーティングを設定できます.
    それに比べて、
    📃 default.vue
    <Nuxt /> 
    <!-- Nuxt 태그 => <router-view></ router-view> --->
    <NuxtLink to="main"></NuxtLink>
    <nuxt-link class="logo" to="/">공통 헤더</nuxt-link>
    <!-- NuxtLink 태그 => <router-link to="main"></ router-view> --->
    🗂 layouts > 🗂 pages > 🗂 components
  • エラーページ(error.vue)ファイルがレイアウトフォルダに存在する
  • 」」データコール方式-asyncData
    Postはサーバ側レンダリングフレームなので.
    ビューの単一ページアプリケーションとREST APIには、異なる方法でアクセスする必要があります.
    既存のCSRは、createdなどから構成部品を作成する際にデータを取得することで格納される.
    これにより、ロードバーが画面を表示/リフレッシュするときに画面が点滅します.(まず空のデータで始まるので)
    vueプロパティで、asyncDataを使用してページが表示される前にデータを設定します.(ページに入る前に呼び出す)
    注意事項
  • 🗂 pagesフォルダ内の構成部品にのみ有効なデータ
  • asyncDataでは参照構成部品(構成部品の作成前に呼び出すため)
  • は許可されていません.
    asyncDataメソッドは最初のパラメータとしてcontextを受信する
    const {
        app,
        store,
        route,
        params,
        query,
        env,
        isDev,
        isHMR,
        redirect,
        error,
       $config
      } = context
    asyncDataの戻り値はdataとマージされるため、今後this.데이터이름にアクセスできます.
    export default {
    
      async asyncData({ params }) { // context 객체에서 params 사용가능
        try {
          const { data } = await fetchProducts(params.id)
          const items = data || []
          return { items } // this.items에 저장됨
        } catch (e) {
          // 에러 페이지로 이동가능
          error({ statusCode: 503, message: 'API 요청이 실패했습니다 다시 시도해 주세요' })
        }
      },
      
      computed: {
        proceedItems() { // this.items로 접근하여 가공하여 사용가능
          return this.items.map((item) => ({
            ...item,
            imageUrl: `${item.imageUrl}?random=${Math.random()}`,
          }))
        },
      },
      
    }
    
    snid▼データを呼び出す方法-fetch
    asyncDataとは異なる🗂 componentsフォルダのコンポーネントでも使用できます
    このアプローチは可能です
    thisはアクセスできますが、fetchプロパティのため、2つの場合で異なる場合があります.

  • このURLに直接接続すると呼び出し時にページが表示されます


  • ブラウザでURLアドレスを変更してページを移動する場合-構成部品を作成し、呼び出しを実行します.

  • バトルバトル用vuex-store
    自動生成🗂 storeフォルダはvuexと同じ役割を果たし、indexです.jsファイルがrootStateになる
    本来new Vue()でオブジェクトを作成する際にuse vuexなどを設定するのですが、これも自動プリセットで便利!
    索引の場合jsを作成し、別の名前のJavaScriptファイルを作成すると、ビューXのモジュールになります.
    🗂 store > 📃 index.js
    import { fetchCartItems } from '~/api'
    
    export const Types = {
      getters: {
        PROCEED_CARTS: 'proceedCarts',
      },
      mutations: {
        ADD_ITEM_TO_CART: 'addItemToCart',
        SET_CARTS: 'setCarts',
      },
      actions: {
        FETCH_CARTS: 'fetchCarts',
      },
    }
    
    export const state = () => ({
      carts: [],
    })
    
    export const getters = {
      [Types.getters.PROCEED_CARTS](state) {
        return state.carts.map((item) => ({
          ...item,
          imageUrl: `${item.imageUrl}?random=${Math.random()}`,
        }))
      },
    }
    
    export const mutations = {
      [Types.mutations.ADD_ITEM_TO_CART](state, item = {}) {
        state.carts = [...state.carts, item]
      },
      [Types.mutations.SET_CARTS](state, carts) {
        state.carts = [...carts] || []
      },
    }
    
    export const actions = {
      async [Types.actions.FETCH_CARTS](context) {
        const { data } = await fetchCartItems() || {}
        const items = data || []
        context.commit(Types.mutations.SET_CARTS, items)
      },
    }
    
    📃 cart.vue
    import { mapGetters, mapMutations } from 'vuex'
    import { createCartItem } from '~/api'
    export default {
      async asyncData({ store }) {
        // store에서 fetch수행
        await store.dispatch('fetchCarts')
      },
    
      computed: {
        // store에서 가공한 mapGetters 사용 가능
        ...mapGetters(['proceedCarts']),
        // 컴포넌트에서 가공하여 사용
        carts() {
          return this.$store.state.carts
        },
      },
    
      methods: {
    	// ...mapMutations(['addItemToCart']), - mapMutations로도 사용 가능
        async addToCart() {
          await createCartItem(this.product)
          // store commit
          this.$store.commit('addItemToCart', this.product)
          // this.addItemToCart(this.product)
          this.$router.push('/cart')
        },
      },
    }
    ⭐️ ❗️ NuxtServerInit
    Store>ActionsのnuxtServerInit関数はPostの汎用モードで使用可能
    ストレージ領域のデータから開始
    =>サーバ側プレゼンテーション時に実行されるため、サーバからのみアクセス可能なデータをショップで事前に設定したり、処理したりする場合に便利です.たとえば、
    actions: {
      // 두 번째 파라미터 nuxtContext는 asyncData 메서드의 context 파라미터와 동일
      nuxtServerInit(storeContext, nuxtContext) {
        storeContext.commit('뮤테이션 함수명');
        if (process.server) {
          const { req, res, beforeNuxtRender } = nuxtContext;
        }
      }
    }
    🗂 store > 📃 index.js
    export const actions = {
      async nuxtServerInit(storeContext, nuxtContext) {
        const { data } = await fetchCartItems() || {}
        onst items = data || []
        storeContext.commit(Types.mutations.SET_CARTS, data)
      },
    
      // async [Types.actions.FETCH_CARTS](context) {
      //   const { data } = await fetchCartItems() || {}
      //   const items = data || []
      //   context.commit(Types.mutations.SET_CARTS, items)
      // },
    }
    
    📃 cart.vue
    export default { // nuxtServerInit으로 변경
      // async asyncData({ store }) {
      //   await store.dispatch('fetchCarts')
      // },
    }
    」Nuxtライフサイクル


    」配置方法
    SSR(Server Side Rendering)
    Nodeから配備するサーバへ.jsサーバを実行する方法で導入
    🗂 .nxtフォルダ
    // nuxt.config.js
    export default {
      target: 'server'
    }
     
    $ npm run build
    $ npm run start
    SSG(Static Site Generation)
    サーバがページURL要求を受け取るたびに描画してブラウザに送信するSSRモードとは異なります.
    Webサービスを構成するすべてのページを事前に描画する必要があるため、ワークベンチサーバに配備する形式.
    🗂 distフォルダ
    // nuxt.config.js
    export default {
      target: 'static'
    }
     
    $ npm run generate
    各ページのメタラベルの設定
    export default {
      
      async asyncData({ params }) {
        const response = await fetchProductById(params.id)
        return { product: response.data }
      },
    	
      head() {
        return {
          title: `상품 상세 페이지 - ${this.product.name}`,
          meta: [
            {
              hid: 'description', // 다른 곳과 동일하게 설정해야 덮어써짐
              name: 'description',
              content: `이 페이지는 ${this.product.name} 상품입니다`,
            },
          ],
        }
      },
      /*
    	head: {
          title: '페이지 타이틀',
          meta: [
            {
              hid: 'description', // 다른 곳과 동일하게 설정해야 덮어써짐
              name: 'description',
              content: '페이지 설명 내용',
            },
          ],
      	}, 
      */
    }
    戦OGラベル
    SNS上で特定ページのリンクを共有する場合
    メタタグを使用すると、ページの情報をよりよく表示できます.
    Open Graphプロトコル式ドキュメント
    KakaoOGタグキャッシュクリアサイト
    export default {
      head() {
        return {
          title: `상품 상세 페이지 - ${this.product.name}`,
          meta: [
            {
              hid: 'og:title', // og:을 붙여준다
              property: 'og:title',
              content: `상품 상세 페이지 - ${this.product.name}`,
            },
            {
              hid: 'og:description',
              property: 'og:description',
              content: `이 페이지는 ${this.product.name} 상품입니다`,
            },
            {
              hid: 'og:image',
              property: 'og:image',
              content: this.product.imageUrl,
            },
          ],
        }
      },
      /*
      head: {
        title: '상품 상세 페이지',
        meta: [
          {
            hid: 'og:title', // og:을 붙여준다
            property: 'og:title',
            content: '상품 상세 페이지'
          },
          {
            hid: 'og:description',
            property: 'og:description',
            content: '상품의 상세 정보를 확인해보세요'
          },
          {
            hid: 'og:image',
            property: 'og:image',
            content: 'http://placeimg.com/640/480/fashion'
          },
        ]
      }
      */
    }