#1 Vue.jsをインストールして動作確認
vue.jsについて
ページの内容がすぐに変わることや、マイクロインタラクション(動き)の実装ができ、ユーザーの動きに合わせたストレスのないサイトの制作が実現できるため、UI、UX*1に対して人気のフレームワークです。
vue-cliをインストールする
開発環境OS | MacOS Catalina 10.15.7 |
vue-cli | 4.5.9 |
vue | 2.6.12 |
npm | 6.14.8 |
node | 14.15.0 |
webpack | 4.44.2 |
HomebrewとNodebrew(node.js)はインストール済みであることが前提ですすめます。
まだの方はこちら
$ brew update
まずはHomebrewをアップデートします。
$ npm i -g @vue/cli
ノードパッケージモジュールでvueをグローバルにインストールします。i = install -g = global の略です。vueは各プロジェクトフォルダ(ローカル)ではなくグローバル(/Users/ユーザー名/node_modules)内にインストールします。
$ vue -V
インストールされたvueのバージョンを確認してみましょう。@vue/cli 4.5.9
このような表示が出ればOKです。
vue.jsのアップデートやその他コマンド
作業を進めていく中で必要なアップデートやモジュールの再インストール方法です。
##アップデート
$ npm update -g @vue/cli
#モジュールアップデート
$ npm i -g npm-check-updates
#モジュール削除と再インストール
$ rm -rf node_modules package-lock.json && npm i
↓これを1行にしたもの
$ rm -r node_modules
$ rm package-lock.json
$ npm i
開発用フォルダに移動し、vueプロジェクトを作成する
$ cd ~/job/stg/vue/
例ではjob/stgフルダ内にvueフォルダを作りました。vueのプロジェクトはここに入れていきます。
$ vue create project-name
vueコマンドでvueプロジェクトを作成します。project-nameは適当な名前をつけましょう。
ここでは01-vueとします。
Vue3が2020年9月にリリースされましたが、まだ日本語のマニュアルがありません。学習するために今回はVue2を選択しましょう。 カーソルキーで下矢印を押して、エンターキーで決定します。
・
・
・
65 packages are looking for funding
run `npm fund` for details
⚓ Running completion hooks...
📄 Generating README.md...
🎉 Successfully created project 01-vue.
👉 Get started with the following commands:
$ cd 01-vue
$ npm run serve
インストールが完了すると、一番下2行に次のコマンドが表示されます。
$ cd 01-vue
まず作成したプロジェクトフォルダに移動します。
$ npm run serve
エンターを押すとサーバーが起動しはじめます。
$ npm run serve -- --port 8081 とオプションを付けてポートを変更することもできます
INFO Starting development server...
98% after emitting CopyPlugin
DONE Compiled successfully in 2622ms
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.10.239:8080/
Note that the development build is not optimized.
To create a production build, run npm run build.
このコマンドで、webサーバが起動しブラウザに表示されます。※MAMPなどは不要です。表示にあるようにhttp://localhost:8080/にアクセスしてみましょう。

フォルダの内容を確認
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── node_modules
├── public
│ ├── favicon.ico
│ └── index.html
└── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ └── HelloWorld.vue
└── main.js
インストール直後のディレクトリ/ファイル構成です。package.json
// package.jsonの一部
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.11"
},
ライブラリの管理をするためのファイル。インストールしたものが追記される。
node_modules

800以上のライブラリが最初にインストールされています。追加されたモジュールもここに入ります。 必要に応じてモジュールを追加していきます。
public
ファビコンなど公開用の静的なファイルをおいておきます。src
vueアプリケーションのコードをおいておく場所です。main.js、App.vue
main.js = main.jsはページが表示されて最初に実行されるjsファイルです。いろんな初期設定を記載しておきます。App.vue = ページを表示させるためのファイルです。
src/assets
jsや画像、scssファイルをおいておく場所です。asset = 資産src/components
vueのコンポーネントファイルをおく場所です。ライブラリのインストール
サイトを作るために最低限必要な、ルーティングに関するライブラリとSCSSを扱えるようにするためのライブラリをインストールしておきます。
$ npm i -D ライブラリ名
インストールコマンドです。iはinstallの略。逆はuninstallです。
-Dはpackage.jsonのdevDependencies:に記載され、省くとdependencies:にライブラリが記載されます。
開発・制作のみで使うものはdevDependencies:に記載します。
vue-router
$ npm i vue-router
package.jsonの"dependencies": {} 内に"vue-router": "^3.*.*"が追記されていることが確認できます。
srcディレクトリにrouterディレクトを作成し、その中にindex.jsを作成して、以下の内容を記述します。
router/index.jsを作成します
import Vue from 'vue'
import VueRouter from 'vue-router'
import News from '@/components/News.vue'
import About from '@/components/About.vue'
Vue.use(VueRouter)
const routes = [
{ path: '/news', component: News },
{ path: '/about', component: About }
]
const router = new VueRouter({
mode: 'history',
routes
})
export default router
import VueRouter from 'vue-router'
vue-routerを読み込みます
import News from '@/components/News.vue'
import About from '@/components/About.vue'
テスト用でNews.vueとAbout.vueを使うので読み込む設定をします。@はsrcディレクトリのエイリアスになります。
Vue.use(VueRouter)
useコマンドでvue-routerを使えるようにします。
const routes = [
{ path: '/news', component: News }, //どのURLで、どのコンポーネントを読み込むか
{ path: '/about', component: About }
]
const router = new VueRouter({
mode: 'history', //ヒストリーモードに変更(URLに'#'がつかない)
routes // `routes: routes` の短縮表記
})
export default router
ルーティングの設定ルーティングの設定は以下のように書くこともできます。
export default new VueRouter({
routes: [
{
path: '/news',
component: News
},
{
path: '/about',
component: About
}
]
})
src/main.jsに2ヶ所追記します
import Vue from 'vue'
import App from './App.vue'
import router from './router' //←追加
Vue.config.productionTip = false
new Vue({
router, //←追加
render: h => h(App),
}).$mount('#app')
router/index.jsをインポートさせて、設定します。
テスト用にcomponentsフォルダに2つのコンポーネントファイル作成
router/index.jsにも指定した、テスト用ファイルのNews.vueとAbout.vueをcomponentsディレクトリ内に作成します。ファイル名が大文字で始まることに注意してください。
// News.vue
<template>
<div class="News">これはNewsの内容</div>
</template>
// About.vue
<template>
<div class="about">これはAboutの内容</div>
</template>
テスト用にApp.vueに追記・編集
// App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<!-- ここから追記 -->
<header>
<ul class="nav">
<li><router-link to="/">Home</router-link></li>
<li><router-link to="/news">News</router-link></li>
<li><router-link to="/about">About</router-link></li>
</ul>
</header>
<router-view/>
<!-- ここまで追記 -->
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
App.vueはページの大枠を構成するファイルです。この範囲の中でデータを描画させます。vueのコンポーネントファイルは
<div id="app">内で<router-link to="/">というvue独自のタグを使ってリンクさせています。 テスト用で作ったコンポーネントを読み込んで、クリックしたときに、表示やURLがどのように変わるかみてみましょう。
ターミナルで$ npm run serveして、ブラウザで確認します。
<script>タグ内で、HelloWorld.vueはimportされていますが、 About.vueや、News.vueはimport指示がされてません。ではどうして表示されたのでしょうか?
About.vueや、News.vueはrouter/index.js側で読み込まれており、ルーター機能により、<template>タグ内の <router-view/>タグの箇所に描画されるという仕組みになっています。
ここまでのファイル構成
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── node_modules
├── public
│ ├── favicon.ico
│ └── index.html
└── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ ├── About.vue
│ ├── HelloWorld.vue
│ └── News.vue
├── main.js
└── router
└── index.js

liリンクをクリックするとコンテンツ内容が変わり、URLも変わります。

生成されたHTMLはこのようになります。
#2 静的なページをvue.jsを使って構築する
過去に作ったデータをvue.js化してみよう
基礎1 #7 レスポンシブコーディングでサイト制作① で作成したレスポンシブデザインをscss化したデータを使って、 同じものをvue.jsで作ってみましょう。先程、#1で作ったvueプロジェクト01-vueを編集していきます。

完成形のデザインと、ファイル構成の関係はこのようになります。
最初に部品としてのコンポーネント(部品)を読み込む、土台としてのHome.vueを作ります。 これがURLに対応する1ページ単位となります。https://hoge.com/news/にはNews.vue。https://hoge.com/about/にはAbout.vueというイメージです。
このファイルはcomponentsディレクトリではなくviewsディレクトリに配置します。
srcディレクトリ内にviewsディレクトリを作成します。
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── node_modules
├── public
│ ├── favicon.ico
│ └── index.html
└── src
├── App.vue
├── assets
│ ├── images
│ │ ├── 画像
│ └── scss
│ ├── _variables.scss
│ └── main.scss
├── components
│ ├── Footer.vue
│ ├── Header.vue
│ ├── Main.vue
│ ├── MainMenu.vue
│ ├── MainVision.vue
│ └── Nav.vue
├── main.js
├── router
│ └── index.js
└── views
└── Home.vue
完成したときのファイル配置
Home.vueの作成
// Home.vue
<template>
<div class="home">
<Header/>
<Nav/>
<Main/>
<Footer/>
</div>
</template>
<script>
import Header from '@/components/Header.vue'
import Nav from '@/components/Nav.vue'
import Main from '@/components/Main.vue'
import Footer from '@/components/Footer.vue'
export default {
name: 'Home',
components: {
Header,
Nav,
Main,
Footer,
}
}
</script>
<style lang="scss" scoped>
.home {
background: #fff;
}
</style>
template
描画するコンポーネント(部品)をタグの形式で配置させます。必ずdivなどのセレクタで囲います。script
描画するvueファイルをインポートし、export defaultでこのtemplate内で使えるようにコンポーネントを登録
style
lang="scss"で、scss形式を記述できます。scopedは、このコンポーネント内(ローカル)でしか適応させたくない場合に指定します。 その場合、必ず.homeなどのclassかidで指定します。
コンポーネント(部品)ファイルの作成
以前作った基礎1 #7 レスポンシブコーディングでサイト制作① のhtmlやscssファイルを必要なセクションごとに切り出していきます。1枚のhtmlやscssファイルを、 headerやfooterやボタンなど特定の場所ごとに切り分けていくイメージです。<template>タグの内容にはhtml部分を、<style>タグの内容はscssファイルから、それぞれ必要なセレクタを切り出してコピーしていきます。
これらのファイルはcomponentsディレクトリに入れていきます。
以前は1枚のhtmlやscssファイルにheaderからfooterまですべてのセレクタを記述していましたが、 vueではコンポーネント(部品)ごとに該当するセレクタを記述していきます。
該当するscssを変更したいときには、scssファイルではなく、コンポーネントファイルに記述してあるstyleを編集できるので管理が容易になります。
//Header.vue
<template>
<header>
<div class="header__contents">
<div class="header__contents--text text-right">
Professional Skills in<br>the Engineering Curriculum.
</div>
<div class="header__contents--logo">
<p class="header__contents--logo-mark"><img src="../assets/images/logo.png" alt="CBC logo"></p>
<p><img src="../assets/images/logo-bagde.png" alt="CRI BOOT CAMP"></p>
</div>
<div class="header__contents--text">
プロフェッショナルになるための<br>“挫折しない”トレーニングメソッド
</div>
</div>
<div class="header__image">
<img src="../assets/images/badge.png">
</div>
</header>
</template>
<script>
export default {
name: 'Header'
}
</script>
<style lang="scss" scoped>
header {
border-top:20px solid $mainColor;
/* widthをpx指定している部分がレスポンシブ化のポイントになります */
.header__contents{
width:1200px;
margin:43px auto 88px;
display:flex;
justify-content:center;
@include mq('max','md'){
display:block;
margin-top:240px;
position:relative;
}
@include mq('max','lg'){
width:100%;
}
&--text{
align-self:flex-end;
margin:0 30px;
width:25%;
border-top:1px solid $mainColor;
border-bottom:1px solid $mainColor;
@include mq('max','md'){
margin:0 auto;
width:90%;
}
}
.text-right{
text-align:right;
@include mq('max','md'){
text-align:left;
border-bottom:none;
}
}
&--logo{
text-align:center;
@include mq('max','md'){
position: absolute;
top:-228px;
left: 0;
right: 0;
margin: auto;
}
&-mark{
margin-bottom:20px;
}
}
}
.header__image{
position:relative;
height:600px;
background:$mainColor url('../assets/images/bg_header.jpg')no-repeat right center / cover;
@include mq('max','md'){
position:relative;
height:40vh;
background:$mainColor url('../assets/images/bg_header.jpg')no-repeat right center / cover;
}
img{
position:absolute;
top:-60px;
right:5vw;
}
}
}
</style>
//Footer.vue
<template>
<footer>
<div class="footer">
<div class="footer__image"></div>
<h2>Location & Contact</h2>
<div class="footer__column">
<div class="footer__column--form">
<form action="send.php" method="POST">
<p>ご予約やお問い合わせはこちらのフォームを<br>ご利用ください。個人情報保護方針について</p>
お名前<br>
<input type="text" name="inputName">
メールアドレス<br>
<input type="text" name="inputMail">
問い合わせ内容<br>
<textarea name="toiawase"></textarea>
<input type="submit" value="送信">
</form>
</div>
<div class="footer__column--map">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d810.4161765212042!2d139.66673032925627!3d35.660631688388975!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x6018f4ab6ef28945%3A0xed98990ae6e1597b!2z5qCq5byP5Lya56S-44Kv44Oq44Ko44Kk44OG44Kj44OW44Oq44K944O844K544Kk44Oz44K544OG44Kj44OB44Ol44O844OI!5e0!3m2!1sja!2sjp!4v1571382479874!5m2!1sja!2sjp" frameborder="0" style="border:0;" allowfullscreen=""></iframe>
<div>
〒000-0000 東京都世田谷区 0-0-0<br>
TEL. 03-0000-0000<br>
OPENING HOURS: 12:00 PM – 11:00 PM
</div>
</div>
</div>
</div>
<div class="footer__copy">© 20XX Created by CBC</div>
</footer>
</template>
<script>
export default {
name: 'Footer'
}
</script>
<style lang="scss" scoped>
footer {
text-align:center;
.footer {
color:#fff;
padding:60px 0 70px;
background-color:$mainColor;
h2{
font-size:50px;
margin:30px auto 80px;
@include mq('max','md'){
font-size:2em;
}
}
&__image{
width:100%;
height:600px;
background:$mainColor url('../assets/images/bg_footer.jpg')no-repeat center center / cover;
@include mq('max','md'){
height:40vh;
}
}
&__column{
width:1200px;
display:flex;
margin:40px auto 100px;
@include mq('max','md'){
display:block;
}
@include mq('max','lg'){
width:100%;
}
&--form{
flex:1;
width:60%;
@include mq('max','md'){
flex:1;
width:100%;
}
form{
width:60%;
margin:10px auto 0;
display:flex;
flex-direction:column;
text-align:left;
@include mq('max','md'){
width:80%;
}
p{
font-size:0.9em;
margin-bottom:15px;
}
input[type="text"]{
margin: 0 0 20px 0;
padding:5px 10px;
font-size:1.2em;
border-radius:5px;
border:none;
background-color:#fff; //リセット用のress.cssが効いて背景色になるので、白色を指定
}
textarea{
margin: 0 0 20px 0;
padding:10px;
height:8em;
font-size:1.3em;
border-radius:5px;
border:none;
background-color:#fff; //リセット用のress.cssが効いて背景色になるので、白色を指定
}
}
}
&--map {
flex:1;
text-align:left;
width:500px;
height:450px;
@include mq('max','lg'){
margin:0 auto;
width:97%;
}
iframe{
width:500px;
height:450px;
@include mq('max','md'){
width:90%;
margin:50px auto 0;
text-align:center;
}
@include mq('max','lg'){
width:40vw;
height:450px;
}
}
}
}
&__copy{
font-size:0.8em;
padding:20px 0;
color:#aaa;
}
}
}
</style>
//Nav.vue
<template>
<nav>
<ul>
<li><a href="">home</a></li>
<li><a href="">beginner</a></li>
<li><a href="">basic</a></li>
<li><a href="">advanced</a></li>
<li><a href="">design</a></li>
<li><a href="">performance</a></li>
<li><a href="">kids</a></li>
</ul>
</nav>
</template>
<script>
export default {
name: 'Nav'
}
</script>
<style lang="scss" scoped>
nav {
background-color:$mainColor;
ul{
width:1200px;
margin:0 auto;
display:flex;
justify-content: space-around;
@include mq('max','md'){
flex-wrap:wrap;
}
@include mq('max','lg'){
width:100%;
}
li{
width:120px;
height:60px;
@include mq('max','md'){
margin:6px 0;
}
a{
display:flex;
justify-content: center;
align-items: center;
height:100%;
color:#fff;
@include mq('max','md'){
border:1px solid #fff;
}
}
}
}
}
</style>
//Main.vue
<template>
<main>
<MainMenu/>
<MainVision/>
</main>
</template>
<script>
import MainMenu from '@/components/MainMenu.vue'
import MainVision from '@/components/MainVision.vue'
export default {
name: 'Menu',
components: {
MainMenu,
MainVision
}
}
</script>
//MainMenu.vue
<template>
<section class="menu">
<div class="menu__content">
<div class="menu__content--text">
<img src="../assets/images/title_cording.png" alt="cording">
<h1>Title</h1>
<p>ここはコンテンツの説明を入力していきます。魅力的な文章を追加して、ユーザーにコンテンツの内容を理科してもらいましょう。</p>
<div class="btn"><a href="">MENU</a></div>
</div>
<div class="menu__content--image img-cording"></div>
</div>
<div class="menu__content">
<div class="menu__content--image img-design"></div>
<div class="menu__content--text">
<img src="../assets/images/title_design.png" alt="design">
<h1>Title</h1>
<p>ここはコンテンツの説明を入力していきます。魅力的な文章を追加して、ユーザーにコンテンツの内容を理科してもらいましょう。</p>
<div class="btn"><a href="">MENU</a></div>
</div>
</div>
</section>
</template>
<script>
export default {
name: 'MainMenu'
}
</script>
<style lang="scss" scoped>
.menu {
width:1200px;
margin:0 auto;
@include mq('max','md'){
margin:30px auto 0;
}
@include mq('max','lg'){
width:100%;
}
&__content{
display:flex;
text-align:center;
@include mq('max','md'){
display:block;
position:relative;
}
&--text{
flex:1;
@include mq('max','md'){
position: absolute;
top:30px;
left: 0;
right: 0;
margin: auto;
z-index:99;
}
img{
margin-top:80px;
text-align:center;
}
h1{
margin:20px 0 50px;
font-size:1.3em;
}
p{
width:65%;
margin:0 auto 20px;
}
}
&--image{
flex:1;
height:600px;
@include mq('max','md'){
position: relative;
margin-bottom:2px;
&::before{
height:600px;
background-color: rgba(0,0,0,0.6);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: ' ';
}
}
}
.img-cording{
background:url('../assets/images/menu_cording.jpg')no-repeat center center / cover;
}
.img-design{
background:url('../assets/images/menu_design.jpg')no-repeat center center / cover;
}
}
}
</style>
//MainVision.vue
<template>
<section class="vision">
<div class="vision__image">
<h1>ブラウザやテキストエディタ等ツールのインストールや、<br>html・CSSとはなにかを学び、<br>簡単なサイトを作りながらコーダーを目指します。</h1>
<p><img src="../assets/images/be-pro.png" alt="Be Professional"></p>
</div>
<div class="vision__columun">
<div class="vision__columun--item">
<p class="vision__columun--item-img"><img src="../assets/images/contents_cording.png" alt="cording image"></p>
<p>
ここはコンテンツの説明を入力していきます。魅力的な文章を追加して、ユーザーにコンテンツの内容を理科してもらいましょう。
ここはコンテンツの説明を入力していきます。魅力的な文章を追加して、ユーザーにコンテンツの内容を理科してもらいましょう。
</p>
</div>
<div class="vision__columun--item">
<p class="vision__columun--item-img"><img src="../assets/images/contents_design.png" alt="design image"></p>
<p>
ここはコンテンツの説明を入力していきます。魅力的な文章を追加して、ユーザーにコンテンツの内容を理科してもらいましょう。
ここはコンテンツの説明を入力していきます。魅力的な文章を追加して、ユーザーにコンテンツの内容を理科してもらいましょう。
</p>
</div>
<div class="vision__columun--item">
<p class="vision__columun--item-img"><img src="../assets/images/contents_analytics.png" alt="analytics image"></p>
<p>
ここはコンテンツの説明を入力していきます。魅力的な文章を追加して、ユーザーにコンテンツの内容を理科してもらいましょう。
ここはコンテンツの説明を入力していきます。魅力的な文章を追加して、ユーザーにコンテンツの内容を理科してもらいましょう。
</p>
</div>
</div>
</section>
</template>
<script>
export default {
name: 'MainVision'
}
</script>
<style lang="scss" scoped>
.vision {
position: relative;
@include mq('max','md'){
margin-top:50px;
}
&__image{
border-top: 60px solid $mainColor;
height:600px;
background:$mainColor url('../assets/images/bg_contents.jpg')no-repeat center center / cover;
display:flex;
justify-content: center;
align-items: center;
flex-direction:column;
@include mq('max','md'){
font:bold 1.6em/1.9em sans-serif;
}
/*背景画像に黒いカバーをかける方法*/
&::before{
height:600px;
background-color: rgba(0,0,0,0.6);
position: absolute;
top: 60px;
right: 0;
bottom: 0;
left: 0;
content: ' ';
}
h1{
font:bold 31px/2.3em sans-serif;
text-align:center;
color:#fff;
z-index:99;
}
p{
margin-top:75px;
z-index:99;
}
}
&__columun{
width:1200px;
margin:80px auto 150px;
display:flex;
justify-content: space-between;
@include mq('max','md'){
width:90%;
margin:10px auto;
display:block;
}
@include mq('max','lg'){
width:97%;
}
&--item{
width:30%;
text-align:left;
@include mq('max','md'){
width:90%;
margin-top:40px;
text-align:left;
}
&-img{
margin:0 0 50px;
text-align:center;
@include mq('max','md'){
margin:0 0 10px;
text-align:center;
}
img{
height:200px;
}
}
}
}
}
</style>
※自分で過去に作成していたファイルを切り出す場合、画像のリンクパスが変更になります。templateとstyleの../images/を../assets/images/に変更しましょう。
scssファイルの作成
scssファイルはassetsディレクトリにsassディレクトを作成しその中に入れていきます。具体的なセレクタではない共通セレクタ(bodyやaタグなど)はmain.scssに記述します。
/* main.scss */
body {
font:normal 16px/1.8em Arial,Helvetica,sans-serif;;
color: $mainColor;
}
a {
text-decoration: none;
}
.btn a,
input[type="submit"]{
display:inline-block;
margin:0 auto;
padding:10px 0;
width:130px;
cursor:pointer;
font-size:1.3em;
color:#58847F;
text-align:center;
border: 10px solid #58847F;
background-color:transparent;
}
また以前作成した、変数をまとめた_variables.scssはそのままassets/scssディレクトリに入れておきましょう。※変数をまとめたstyleなどの、別のファイルに読み込ませることを目的としたscssファイル名にアンダーバーをつけてわかりやすようにします。
リセット系css
$ npm i ress
いままでreset.cssを作って読み込んでいましたが、それもコマンドラインツールでress.scssをインストールしましょう。
後ほどimport設定します。
scssファイルのインポート
変数をまとめた共通のscssを、各コンポーネントに毎回importするのは大変なので、importなしで使えるようにします。
@import "./_variables.scss"; /* ← 全ファイルにこれを書くのは保守性が悪い... */
body {
color: $Color;
他のscssファイル、例えばmain.scssなどで_variables.scssで使おうとするとこのようにimportさせますが、
すべてのscssファイルでわざわざimportせずに使えるようにするには、ルートにvue.config.jsを作成し、
以下のように記述します。srcディレクトリと同じ場所に配置します。
// vue.config.js
module.exports = {
css: {
loaderOptions: {
scss: {
additionalData: `@import "@/assets/scss/_variables.scss";`
}
}
}
};
※module.exports = { }でwebpackローダーの拡張設定をしています。※sass-loader v9.0以上は、prependDataは、additionalDataに変更されました。
scssファイルのコンパイル
このままではsassをコンパイル(css形式に変換)できません。Webpackを使ってコンパイルさせるライブラリをインストールします。
$ npm i -D sass-loader node-sass
sass-loaderとnode-sassをインストールします。2020年11月では以下のバージョンです。
"node-sass": "^5.0.0",
"sass-loader": "^10.0.5",
"sass-loader": "^10.0.5",
imagesフォルダをコピー
以前作成したサイトのimagesフォルダを、src/assets/ディレクトリの中にコピーします。main.jsの編集
main.jsはページが表示されて最初に実行されるjsファイルです。
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import 'ress'; // npm経由でインストールしたress.cssをインポート
import '@/assets/scss/main.scss' // コンポーネントに取り込んでいないscssファイル
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App),
}).$mount('#app')
styleファイルを読み込むための記述をします。
ルーティングの設定(router/index.js)
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/views/Home.vue'
Vue.use(VueRouter)
const routes = [
{ path: '/', component: Home }
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
4行目でHome.vueをインポートします。
const routes = [
{ path: '/', component: Home }
]
path:'' でURLを指定します。path: '/news' といった感じになります。また、viewsの中に作ったvueコンポーネントファイルを指定します。
const routes = [
{ path: '/', component: Home },
{ path: '/news', component: News },
{ path: '/about', component: About }
]
複数指定するとこのようになります。
base: process.env.BASE_URL,
ルーティングに関わる設定です。App.vueの編集
App.vueを編集します。
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<template>内の<router-view/>のヶ所で、router/index.jsで記述したコンポーネント
(URLが'/'の場合、Home.vue)がルーティング機能により表示されます。
完成品の確認とサーバ公開
ブラウザで確認
$ npm run serve
http://localhost:8080/ブラウザを確認して、画面が表示されていればOKです。
エラーが出る場合はエラー内容を確認しながら、以下の内容を確認してみましょう。
- ・imagesフォルダ含め、ファイルが全て揃っているか
- ・sass-loaderがnpm経由でインストールされているか
- ・存在しないコンポーネントを読み込んではいないか
- ・ファイルのパスが間違っていないか
- ・ターミナルを再起動してコマンド入力してみる
webサーバーで公開するためビルドする
ローカルの開発環境での表示が確認できたところで、レンタルサーバやAWSなどの公開サーバにアップロードしてみましょう。Ctr+cでサーバを停止し、ビルドコマンドを実行します。
$ npm run build
Building for production...という表示のあと、
ルートディレクトリにdistフォルダが作成されたはずです。distはdistribution(配布する)の略です。
├── css
│ ├── app.db43c444.css
│ └── chunk-vendors.501fb1dc.css
├── favicon.ico
├── img
│ └── 画像
├── index.html
└── js
├── app.8019827c.js
├── app.8019827c.js.map //ソースマップ
├── chunk-vendors.fc849a72.js
└── chunk-vendors.fc849a72.js.map //ソースマップ
このような内容になっています。詳しい説明は省きますが、このフォルダの中身をサーバーのルートディレクトリに入れて、ブラウザで確認すると同じ表示になっていることが確認できます。
公開用ディレクトリが違う場合などのオプションはvue.config.jsに記述します。
//vue.config.js
const path = require('path')
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/test/' : '/',
productionSourceMap: process.env.NODE_ENV === 'production' ? false : true,
devServer: {
port: 8082,
https: false
},
css: {
loaderOptions: {
scss: {
additionalData: `@import "@/assets/scss/_variables.scss";`
}
}
}
}
■publicPathでディレクトリを指定します。
publicPath: './',
①ルートの場合
publicPath: '/test/',
②testディレクトリだった場合
publicPath: process.env.NODE_ENV === 'production'
? '/test/'
: '/',
③Webpackで公開用(グローバル)か開発用(ローカル)かのモードを判断させてディレクトリを変える場合productionは公開用のことです。
/test/とした場合は、サーバのルートにtestディレクトリを作成し、distフォルダの中身をすべてアップロードします。 その後https://xxxx.com/test/にアクセスします。
■そのほか
const path = require('path')
パス情報の取得
productionSourceMap: process.env.NODE_ENV === 'production' ? false : true,
公開用にソースマップが不要な場合
devServer: {
port: 8082,
https: false
},
開発用のポートを変えたい場合は、ここで指定できます。
下のようにオプションでポートを指定することもできます。
$ npm run serve -- --port 8082