djangoとvuejsをcdn以外の方法で共存させる
npmにvueを入れて構築する方法を試みる。djangoはdjango rest frameworkを使う。
今回気になる事項は、
- どうやってdjangoとvueをcdn以外の方法で共存させる環境を構築するのか
- どういう仕組でdjangoとvueが連携する仕組みになっているのか
- vueを使うにあたり単一ファイルコンポーネント、VueルーターやVuexをどう使っていくかのサンプルがほしい
この辺をまとめられたら良いと思う。
参考資料
いつもお世話になっているNaritoさんのブログ
1 vuecliを入れる
naritoさんのブログを参考にしてvuecliを使って構築する方法を試みる。
vueとvuecliは別々に分けられているらしく、ドキュメントが独立しているようだ。
$ 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をどうやって使うのか
必要な要素
- router/index.js内でVueにRouterを追加する(Vue.use(Router);)
- router/index.js内のRouter初期化のパラメータとしてroutesを追加する。このroutesがurl解決の役割を担う。
- 他のコンポーネントにrouter-link to="hoge"を書いてリンクできるようにセットする。
- 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を起動させ、データを取り出す仕組みとなっている。