diadia

興味があることをやってみる。自分のメモを残しておきます。

djangoとvuejsをcdn以外の方法で共存させる

npmにvueを入れて構築する方法を試みる。djangodjango rest frameworkを使う。

今回気になる事項は、

  1. どうやってdjangoとvueをcdn以外の方法で共存させる環境を構築するのか
  2. どういう仕組でdjangoとvueが連携する仕組みになっているのか
  3. vueを使うにあたり単一ファイルコンポーネント、VueルーターやVuexをどう使っていくかのサンプルがほしい

この辺をまとめられたら良いと思う。

参考資料

いつもお世話になっているNaritoさんのブログ

Narito Blog

インストール — Vue.js

1 vuecliを入れる

naritoさんのブログを参考にしてvuecliを使って構築する方法を試みる。

vueとvuecliは別々に分けられているらしく、ドキュメントが独立しているようだ。

Installation | Vue CLI

$ npm install -g @vue/cli

上記のコマンドでvue cliをインストールする。@vue/cliっていう表現で@が何を表すか気になったがこれは単純に@がついただけで意味はない。パッケージのネームとして@がつけられただけだという認識で良いと思う。

Warning regarding Previous Versions The package name changed from vue-cli to @vue/cli. If you have the previous vue-cli (1.x or 2.x) package installed globally, you need to uninstall it first with npm uninstall vue-cli -g or yarn global remove vue-cli.

2 vueプロジェクトを作成する

$ vue create frontend

プロジェクトを作成するとfrontendというディレクトリが生成される。このディレクトリにはnpmの設定関係のpackage.jsonやnode_modulesディレクトリ、vueのファイル関係を収めているsrcディレクトリが作られている。

プロジェクトを作ったときにはvuexとrouterをプロジェクトで使うように選択する。

3 App.vueを編集する

src以下にApp.vueがプロジェクトをvue作ると生成されている。これはどうやらsrc/main.jsが読み込まれ、このファイル内でApp.vueが読み込まれる。その流れでApp.vueが表示される流れになる。

App.vue

<template>
    <div id="app">
        <Header/>
        <router-view/>
        <Footer/>
    </div>
</template>

<script>
    import Header from "./components/Header"
    import Footer from "./components/Footer"

    export default {
        name: 'app',
        components: {Header, Footer}
    }
</script>

これで起動してみる。

npm run serve

4 単一ファイルコンポーネントを使う

cdnを使ったvueをdjangoで使う場合(MPAの場合)には、サーバーに各リクエストが送信され、返信されたファイルのscriptタグ内にVueを初期化するコードが埋め込まれている構造になっていた。 したがって、返信されるテンプレートには必ずVueの初期化が行われ、そのVue自身にmethodsやmountedを準備してやりvueを動かしていた。
今回のようなSPAの場合には、おそらくVueの初期化は一度限りでそのVueのライブラリを使ってページ遷移を実施する流れなのだと思われる。

5 vue routerをどうやって使うのか

必要な要素

  1. router/index.js内でVueにRouterを追加する(Vue.use(Router);)
  2. router/index.js内のRouter初期化のパラメータとしてroutesを追加する。このroutesがurl解決の役割を担う。
  3. 他のコンポーネントにrouter-link to="hoge"を書いてリンクできるようにセットする。
  4. router-viewタグに遷移先のページがレンダリングされるイメージなのでrouter-viewタグも忘れずにセットする。
routerに関して分かりやすい資料

https://b1tblog.com/2019/10/03/vue-router/

Vue Routerの書き方、使い方について解説 | ELOOP(イーループ) - 開発課題に取り組んで身につける実践型プログラミング学習サービス

routerに関するサンプルコード

GitHub - chiaki1990/vue_router_first_sample

疑問点

ランディングページでデータをデータベースから取得するにはどうするのか? それはvueの
ライフサイクルを利用すれば良い。

mountedに非同期通信の関数を設置しておき、mounted時に非同期通信が開始されるように構成しておけば良い。

(環境構築手順とは別に)vue cliについて少し分かったことをメモ

a. vueがどんな風に動いているか

最初にsrc/main.jsを読み込む流れになると思われる。そのファイルの中で、

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

createApp(App).use(store).use(router).mount('#app')

ここからApp.vueが読み込まれる。このApp.vueのファイルはtemplateタグを使っている。 templateタグ内では単一ファイルコンポーネントのタグを挿入したりしている。 そしてこの単一ファイルコンポーネントは同一ファイル内のscriptタグ内でimport して呼び出している。 このような流れで動いていると推測される。

<template>
    <div id="app">
        <Header/>
        <router-view/>
        <Footer/>
    </div>
</template>

<script>
    import Header from "./components/Header"
    import Footer from "./components/Footer"

    export default {
        name: 'app',
        components: {Header, Footer}
    }
</script>

<style>
</style>

b. vueとdjangoの組み合わせ方

主要なurlのルーティング機能はvueが担う。
vue routerが画面の内容を制御する。データベースからデータの取り出しはaxios等を使用して非同期処理でデータを取り出し、画面のデータとして反映する。
このデータの取り出しでdjangoのurls.pyを通じてdrfのapiviewを起動させ、データを取り出す仕組みとなっている。