Vue js router-view , router-linkについて

過去記事の続きです。

 

kirikko-scondcube.hatenablog.com

kirikko-scondcube.hatenablog.com

 

 

今回最初に操作するのは

src/App.vue

 

App.vue

<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>

<style lang="scss">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}

#nav {
padding: 30px;

a {
font-weight: bold;
color: #2c3e50;

&.router-link-exact-active {
color: #42b983;
}
}
}
</style>

 

ここで注目するのが

<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>

 

この

<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>

<router-view/>
 の部分
 
この2つはrouter/index.js内でルーターモジュールを読み込んだことで使えるようになる。
*疑問点*
ルーターモジュールとは??

 

<router-view/>
について 
この部分にルートに合わせたコンポーネント が表示される。
そのため全てのページで使用するグローバルビューはこの部分の外側に記述する
 
 
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>

について

これはデフォルトの内容で

Homeとaboutのページを行き来するためにしようされている。

上記「to='/'」のように記述しパスを指定する。

 

ルートに名前をつけて指定することも可能

その場合は以下のように書き換える

<router-link to="{name: 'home'}">Home</router-link> |
<router-link to="{name: 'about'}">About</router-link>

この記述方法のメリットはパスが変わっても適用可能と言う点にある。 

基本はこちらが推奨される。

 

また、内のHome, Aboutの記述を帰ればリンクを変更できる

(文字列を変えたりimgにリンクを貼れたりする)

<router-link to="{name: 'home'}"><img width='100' src="https://images.unsplash.com/photo-1595970731082-f7267436b6f1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=60" alt=""></router-link> |
<router-link to="{name: 'about'}">アバウト</router-link>
 
結果

f:id:kirikko_Scondcube:20200801013055p:plain

このように変更することも可能
 

 

 

 

 

 

 

 

 

 

Vue js SPAとRouterについて

この記事は前回の記事の続きです。

 

 

kirikko-scondcube.hatenablog.com

 

SPAの特徴

SPAはページの描画は一度(初回アクセスが重くなることがある)。

軽快に動作するアプリケーションが作れる。

 

Vue Routerの機能

ページごとの画面の切り替えをする機能

 

確認するにはsrc/main.js

 

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
router,
//router:router,と同じ意味上は省略の記載方法
store,
render: h => h(App)
}).$mount('#app')

 

import App from './App.vue'で読み込んで
new Vueの中のrouter,で定義している。
これによってVueインスタンスの初期化時にrouterが渡される。
 
次にsrc/router/index.jsをみてみる
 
index.js
import Vue from 'vue'//vue本体の読み込み
import VueRouter from 'vue-router'//vue Routerのライブラリの読み込み
import Home from '../views/Home.vue'

Vue.use(VueRouter)//useメソッドにルーターを渡して有効にしている

const routes = [//ここでルートの操作をする処理を記載。各ページに関するルートとそのルートで表示するコンポーネントの設定を書く
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]

const router = new VueRouter({//ここより以下でルーティングの設定をしている
mode: 'history',//mode: 各画面のパスの設定「history」ではパスを「/」で区切る一般的なやり方を指定している(他にhash, abstractなどがある。)
base: process.env.BASE_URL,//base: アプリケーションのベースとなるパスを指定するもの
routes
})

export default router

 

routesの解説

const routes = [//ここでルートの操作をする処理を記載。各ページに関するルートとそのルートで表示するコンポーネントの設定を書く
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]

ルーツでは配列の中で各ページごとの記載をしている。

扱いたいページが増やしたい時はこの配列の中に新しいページの記述を増やしていく。

書くページの記述はオブジェクトで指定している。

{
path: '/',
name: 'Home',
component: Home
},

path: そのページを表示するパス

→'/'はホーム画面(デフォルトで最初に表示されるパス)

 

name: 名前付きルートのこと(ルーターリンクコンポーネントで使用)

→ルートにネームを指定しておくことで名前でリンクに飛べるようになる(詳細は以下記事ルーターリンクコンポーネントにて)

 

kirikko-scondcube.hatenablog.com

 

 

component:実際に表示するコンポーネントを記述

コンポーネントの読み込み方法は2つ

 

①同一ファイル内にimportされたファイルを指定する方法

 

今回の例ではHomeコンポーネントは事前にインポートされている。

component: Homeとなっていることがわかる↓

import Vue from 'vue'//vue本体の読み込み
import VueRouter from 'vue-router'//vue Routerのライブラリの読み込み
import Home from '../views/Home.vue'

Vue.use(VueRouter)//useメソッドにルーターを渡して有効にしている

const routes = [//ここでルートの操作をする処理を記載。各ページに関するルートとそのルートで表示するコンポーネントの設定を書く
{
path: '/',
name: 'Home',
component: Home
},

 

コードを見ると上で

import Home from '../views/Home.vue'
を定義しているのがわかる。
これをcomponent:Homeで指定している。

 

メリット

小規模プロジェクトであれば管理しやすい。

 

デメリット

大規模開発で多数のコンポーネントの読み込みが必要な場合、importするファイルが多くなり、最初の読み込みに時間がかかる

 

②必要な物を取ってくる方法(関数でコンポーネントを取ってくる方法)

この方法だと最初にimportをする必要がなくなるため、軽快に使用可能(しかし記述がわかりづらい)

 

今回の例だとaboutのインポートで使われている

{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}

component部分の記述がHomeと違うことがわかる↓

component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
 

ここの記述では関数の戻り値でコンポーネントの場所を返すことができるため、そのページが読み込まれたタイミングで初めてインポートされるため複数コンポーネントの読み込みが一度に起こらず軽快な操作を実現できる。

*コメント部分「* webpackChunkName: "about" */」にも意味があるがそこは割愛。

udemyのセクション40でも解説がある。

 

基本的に軽い記述であれば①を使えば良さそう

 

 

 

 

 

Vue CLI のcreateしたファイルについて

Vue CLIでcreateしたファイルの主なフォルダの役割について

 

f:id:kirikko_Scondcube:20200731213644p:plain

インストールしたファイルの階層

 

メモ

画面で表示される。ファイルはpublicフォルダに入れる。

大事なのはpublic/index.html

内の<div id='app'><div>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

 

このapp要素にvueインスタンスをマウントすることでアプリケーションが動作する。

 

次にインスタンスの生成部分

src/main.js

 

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

ここで#appとなっているところがポイント

render: h => h(App)

そしてこれでsrc/App.vueを指定している

 

App.vue

<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>

<style lang="scss">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}

#nav {
padding: 30px;

a {
font-weight: bold;
color: #2c3e50;

&.router-link-exact-active {
color: #42b983;
}
}
}
</style>

このように1つのファイルで1つのコンポーネントが設定されている。

これが単一ファイルコンポーネント

→1つのファイルにテンプレートjavascript, css を書く。

 

コンポーネントは作成したファイルの中のsrc/components/の中に作っていく。

*例外あり→例外①参照*

基本的な作りはtemplate, script, styleの3点記入

ちなみにtemplateの記載があれば動作はするscript , styleは任意

vue create をした際に設定するとvcliにはscssが入る。

langにscssを設定するとstyleタグをscss形式で記入ができる。

.vueを作る時の基本構造は以下

<template>
</template>

<script>
</script>

<style scoped lang="scss">//langにscssと記述するとscssの形式でスタイルを記載できる。
 
</style>

 

*例外①

コンポーネントでもファイル表示のコンポーネント

src/views/の中に○○.vueという名前で記述をする。

ここにはHome.vueというファイルがある。これが初期ではホームコンポーネント となっている。

*ホームコンポーネント とはnpm run serveでサーバーを立ち上げた際に一番最初に表示される画面のこと。

Home.vue

<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
name: 'Home',
components: {
HelloWorld
}
}
</script>

 

元ファイルを元に自分の作りたいファイルを追加していく方法について

まず

src/componets内にAddresses.vueファイルを作成。

 

Addresses.vue

<template>
<div>
<h1>マイアドレス帳</h1>
</div>
</template>

<script>

</script>

<style scoped lang="scss">//langにscssと記述するとscssの形式でスタイルを記載できる。

</style>

 

シンプルにh1タグの記述のみにしています。

 

次にホームコンポーネントの設定を変更

初期ではHome.vueからsrc/component/HelloWorld.vueが設定されている

 

Home.vue

<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
name: 'Home',
components: {
HelloWorld
}
}
</script>

これを修正し、src/components/Addresses.vueを読み込むようにすると、、

<template>
<div class="home">
<!-- <img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/> -->
<Addresses/>
</div>
</template>

<script>
// @ is an alias to /src @/components以下でファイルを指定すると参照できるようになるよと書いてある。
// import HelloWorld from '@/components/HelloWorld.vue'
import Addresses from '@/components/Addresses.vue'//作成したアドレスコンポーネントを読み込み


export default {
name: 'Home',
components: {
// HelloWorld,
Addresses
}
}
</script>

このようになる(元あった不要なHelloWorld.vueへの表示のための記述はコメントあうとしてあります)

ポイント

テンプレート

<Addresses/>

 

スクリプト

import Addresses from '@/components/Addresses.vue'//作成したアドレスコンポーネントを読み込み

 

スタイル

components: {
// HelloWorld,
Addresses
}

 

の部分

こうするとnpm run serveでの初期画面が

 

f:id:kirikko_Scondcube:20200731223019p:plain

デフォルトから上記のように変更される。

 

初期ファイルの変更は以上。

つづく。

Vue js component 親コンポーネント から子コンポーネント へデータの渡し方(props , slot)

参考動画

https://www.youtube.com/watch?v=uNR_WKLFh48&list=PLkQpCfbvj0lwds9oPsRRrFp1ZxTGyueqv&index=14

 

メモ

propsはdataを扱うのと似た感じで使える

slotを使うとタグの間に文字が入れられて視認性が良い

 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>コンポーネントから子コンポーネント の練習</h1>
<div id="app">
<h2>propsの使い方</h2>
<paragragh message='hello'></paragragh>
<paragragh message='world'></paragragh>
<br>
<h2>slotの使い方</h2>
<paragragh2>hogehogehoge</paragragh2>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('paragragh',{
props:['message'],
'template':`<p>{{message}}</p>`
})
Vue.component('paragragh2',{
'template':`<p><slot></slot></p>`
})


new Vue({
el:'#app',
data:{}
})

 
</script>
</body>
</html>

 

結果

f:id:kirikko_Scondcube:20200731184255p:plain

 

 

Vue js componentのグローバルな書き方とローカルな書き方

グローバルは過去記事の記載方法

 

kirikko-scondcube.hatenablog.com

kirikko-scondcube.hatenablog.com

kirikko-scondcube.hatenablog.com

 

 

簡単に言うと

Vue.component(第一引数, 第二引数)

で宣言し、使用するもの

 

しかしこの場合常にコンポーネントの読み込みがされて重くなる。

そこでローカルの使い方を覚える。

 

ローカルでの記述は以下

コード全体

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Vueの練習</h1>
<div id="app">
<h2>{{message}}</h2>
<list></list>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
const titleCom = {
data(){
return{
text:'コンポーネント入れ子構造練習',
}
},
template:`<h3>{{text}}</h3>`
}

Vue.component('list',{//第一引数がコンポーネント名(この名前で呼び出す)
components:{
'titleCom': titleCom
},
data(){//第二引数にコンポーネントの内容を記述する
return {
items:[
{id:1, name:'taro' },
{id:2, name:'ziro' },
{id:3, name:'sabu' },
{id:4, name:'yon' },
{id:5, name:'goro' },
]
}
},
template:`
<div>
<titleCom></titleCom>
<ul>
<li v-for='item in items' :key='item.id'>
{{item.name}}
</li>
</ul>
</div>
`
})


new Vue({
el:'#app',
data:{
message:'コンポーネントの練習'
}
})

 
</script>
</body>
</html>

 

コンポーネント部分

const titleCom = {
data(){
return{
text:'コンポーネント入れ子構造練習',
}
},
template:`<h3>{{text}}</h3>`
}

Vue.component('list',{//第一引数がコンポーネント名(この名前で呼び出す)
components:{
'titleCom': titleCom
},
data(){//第二引数にコンポーネントの内容を記述する
return {
items:[
{id:1, name:'taro' },
{id:2, name:'ziro' },
{id:3, name:'sabu' },
{id:4, name:'yon' },
{id:5, name:'goro' },
]
}
},
template:`
<div>
<titleCom></titleCom>
<ul>
<li v-for='item in items' :key='item.id'>
{{item.name}}
</li>
</ul>
</div>
`
})

 

この例ではコンポーネントtitleComをローカルで宣言

ローカルで宣言は定数constに内容を格納。

 

 

 

【注意点】

・使用する際はグローバルのようにhtml部分にタグの形で入れても表示されない。

→ローカル登録の場合は、登録先コンポーネントないのテンプレートからしか呼び出すことができない

template:`
<div>
<titleCom></titleCom>
<ul>
<li v-for='item in items' :key='item.id'>
{{item.name}}
</li>
</ul>
</div>
`

 

・ローカルのコンポーネントを使用する際、読み込み先で

components:{
'titleCom': titleCom
},

このように宣言する(コンポーネント名:コンポーネントオブジェクト)

コンポーネント名:自由に決めてOK

コンポーネントオブジェクト:constで定義した名前となっている。

 

グローバルからローカルへの書き換え方法

上記全体コードでは

titleComがローカル

listがグローバル

コンポーネント化されている。


Vue.component('list',{//第一引数がコンポーネント名(この名前で呼び出す)
components:{
'titleCom': titleCom
},
data(){//第二引数にコンポーネントの内容を記述する
return {
items:[
{id:1, name:'taro' },
{id:2, name:'ziro' },
{id:3, name:'sabu' },
{id:4, name:'yon' },
{id:5, name:'goro' },
]
}
},
template:`
<div>
<titleCom></titleCom>
<ul>
<li v-for='item in items' :key='item.id'>
{{item.name}}
</li>
</ul>
</div>
`
})


new Vue({
el:'#app',
data:{
message:'コンポーネントの練習'
}
})

 

このlistをローカル化すると以下になる

const List= {//第一引数がコンポーネント名(この名前で呼び出す)
components:{
'titleCom': titleCom
},
data(){//第二引数にコンポーネントの内容を記述する
return {
items:[
{id:1, name:'taro' },
{id:2, name:'ziro' },
{id:3, name:'sabu' },
{id:4, name:'yon' },
{id:5, name:'goro' },
]
}
},
template:`
<div>
<titleCom></titleCom>
<ul>
<li v-for='item in items' :key='item.id'>
{{item.name}}
</li>
</ul>
</div>
`
}


new Vue({
el:'#app',
conponents:{
'list':List
},
data:{
message:'コンポーネントの練習'
}
})

 

基本的にVue.component(第一引数,第二引数)を

const コンポーネント名(第一引数の名前にしちゃうとわかりやすい)= {第二引数の処理}

↑グローバルから変更した場合は外のとじかっこ「 )」を削除することを忘れない。

 

そして使用するVueの宣言にconponents:で宣言する。

 

 

 

 

 

Vue js componentについての注意点

コンポーネント

data:{

},

template,,,,,,,,,,,,

 

といったオブジェクトの記述は出来ない。

この場合は

 

data(){第一引数(コンポーネント名, 第二引数(コンポーネント内容)))

の記述をする

例)

Vue.component('title-com',{
data(){
return{
text:'コンポーネント入れ子構造練習',
}
},
template:`<h3>{{text}}</h3>`
})

 

Vue.component('list',{//第一引数がコンポーネント名(この名前で呼び出す)
data(){//第二引数にコンポーネントの内容を記述する
return {
items:[
{id:1, name:'taro' },
{id:2, name:'ziro' },
{id:3, name:'sabu' },
{id:4, name:'yon' },
{id:5, name:'goro' },
]
}
},
template:`
<div>
<title-com></title-com>
<ul>
<li v-for='item in items' :key='item.id'>
{{item.name}}
</li>
</ul>
</div>
`
})

など

 

コンポーネントのtemplate内では開始タグは同じ階層に1つしか置けない。

 

Vue js Component 入れ子構造について

2つのコンポーネントを作成→入れ子構造にして表示を実装

コンポーネントについての過去記事は以下

 

kirikko-scondcube.hatenablog.com

 

 

 

コード

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Vueの練習</h1>
<div id="app">
<h2>{{message}}</h2>
<list></list>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('title-com',{
data(){
return{
text:'コンポーネント入れ子構造練習',
}
},
template:`<h3>{{text}}</h3>`
})

Vue.component('list',{//第一引数がコンポーネント名(この名前で呼び出す)
data(){//第二引数にコンポーネントの内容を記述する
return {
items:[
{id:1, name:'taro' },
{id:2, name:'ziro' },
{id:3, name:'sabu' },
{id:4, name:'yon' },
{id:5, name:'goro' },
]
}
},
template:`
<div>
<title-com></title-com>
<ul>
<li v-for='item in items' :key='item.id'>
{{item.name}}
</li>
</ul>
</div>
`
})


new Vue({
el:'#app',
data:{
message:'コンポーネントの練習'
}
})
 
</script>
</body>
</html>

 

title-comのコンポーネントを作成→そのコンポーネント名をlistコンポーネントのtemplate内で記述

するとlistコンポーネント内でtitle-comコンポーネントが実行される。

 

表示結果

f:id:kirikko_Scondcube:20200730214837p:plain