# Vue JS 2 Tutorial part 2
###### tags: `Javascript, Vue.js`
# The Vue CLI
* 創造一個可以使用webpack的開發環境
* 使用ES6
* 編譯並且讓檔案容量縮小成一個JS檔
* 使用single file template給網頁的不同app使用
* 在渲染到畫面上前,編譯所有的內容在本地端而不是在瀏覽器上
* 使用在即時更新的伺服器上
使用方式:
1. [安裝node.js](https://nodejs.org/en/)
2. 確認是否安裝成功輸入 node -v 出版本就是成功摟
3. `npm install -g vue-cli`
4. `vue create <project-name>`
接下來會出現一些問題需要回答:
這邊作者選擇Maunally select features

可以視專案需求做選擇

下一步選擇vue.js的版本

下一步選擇 In dedicated config files

下一步會詢問是否儲存設定建議選擇N 畢竟每次專案設定不同看需求而定
接下來我們進入資料夾 cd vue-crash-2021會發現需要的資料都已經載入

下一步使用
```
npm run serve
```

就可以成功叫出來瞜!

# Vue Files & The Root Component
針對剛剛產生出來的vue-cli檔案做一些解析
## Vue Files
### assets
* 放置圖片Logo的區域
* 需要使用到的img都可以放置在這區
### main.js
控制所有的components的檔案
```javascript=
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
```
從最基礎的檔案中可以看出它引入了:
1. Vue(就是整個框架內容)
1. App
App就是指這個部分的檔案,也就是The Root Component

並創造一個新的Vue實體:
抓取id=app這個元素並且把App.vue的內容渲染到元素上面位於index.html內

html內部抓取的div

## The Root Component
也就是剛剛提到的App的部分
可以發現這樣的vue檔案其實就是vue components的延伸,但是拆分到不一樣的檔案
* script
這邊處理把內容輸出到main.js裡面
* style
處理畫面
### 特別注意
template內部只能用一個div包裹住全部的html如果有兩個會報錯

```htmlembedded=
<template>
<div id="app">
<img src="./assets/logo.png">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
<ul>
<li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
</ul>
<h2>Ecosystem</h2>
<ul>
<li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
<li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
<li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
```
## 範例
使用App.vue的內容來渲染index.html內部的id=app的tag
App.vue
```javascript=
<template>
<div>
<h1>{{title}}</h1>
<p>{{greeting()}}</p>
</div>
</template>
<script>
export default {
data () {
return {
title:'yout first vue file'
}
},methods:{
greeting() {
return 'heeeeeeee cowboy!'
}
},
}
</script>
<style></style>
```
印出內容:

# Nesting Components
* 創造components以及import它們、nest它們到其他的components

## Nesting Globally
主要把import寫在main.js內部,並且所有的components都可以使用
1. import 資料夾名稱 from 資料夾位置
1. 並且components建立在這裡`Vue.component('ninjas', Ninjas);`
```javascript=
import Vue from 'vue'
import App from './App.vue'
import Ninjas from './Ninjas.vue'
Vue.component('ninjas', Ninjas);
new Vue({
el: '#app',
render: h => h(App)
})
```
在App.vue檔案內則要使用ninjas tag來使用這個components
App.vue
```javascript=
<template>
<div>
<h1>{{title}}</h1>
<ninjas></ninjas>
</div>
</template>
<script>
export default {
data () {
return {
title:'New title for nesting components'
}
}
}
</script>
<style></style>
```
印出結果:
把Ninja.vue這個components的內容成功渲染到頁面上

## Nesting locally
不會操作在main.js上面,而是在想要渲染的components上面操作
1. 把import的部分寫在App.vue內
1. 把components的內容寫在App.vue內部script內
```javascript=
<template>
<div>
<h1>{{title}}</h1>
<ninjas></ninjas>
</div>
</template>
<script>
import Ninjas from './Ninjas.vue'
export default {
components:{
'ninjas': Ninjas
},
data () {
return {
title:'New title for nesting components'
}
}
}
</script>
<style></style>
```
# Component CSS (scoped)
在style tag加上 scoped讓其CSS只會影響到檔案本身
* 有socped的CSS會針對每個components的CSS新增一個屬性
* 避免複寫其他的components的CSS效果

印出結果:
在App.vue寫的是h1 color:purple
在Ninjas.vue寫的是 h1 color:blue

# Nesting Components Examples
## 成品:

## 成品功能:
1. 點擊人物名稱會顯示使用技能
## HTML
畫面呈顯處index.html
### html程式碼:
```htmlembedded=
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vuejs-playist</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
</body>
</html>
```
## vue-app
* 引入其他components的地點
* 使用components屬性添進進去templates內
```javascript=
<template>
<div>
<app-header>
</app-header>
<app-content></app-content>
<app-footer>
</app-footer>
</div>
</template>
<script>
import Header from'./components/Header.vue'
import Footer from'./components/Footer.vue'
import Content from'./components/Content.vue'
export default{
components:{
'app-header':Header,
'app-footer':Footer,
'app-content':Content,
},
data() {
return {
}
}
}
</script>
<style></style>
```
## Header.vue
```javascript=
<template>
<header>
<h1>{{title}}</h1>
</header>
</template>
<script>
export default{
data() {
return {
title:'nesting example'
}
}
}
</script>
<style scoped>
header{
background:lightgreen;
padding:10px;
}
h1{
color:#222;
text-align:center;
}
</style>
```
## Footer.vue
```javascript=
<template>
<footer>
<p>{{copyright}}</p>
</footer>
</template>
<script>
export default{
data() {
return {
copyright:"Copyright 2021 Vue"
}
}
}
</script>
<style scoped>
footer{
background:#222;
padding:6px;
}
p{
color:lightgreen;
text-align:center;
}
</style>
```
## Content.vue
使用:
* v-for 依序印出物件
* v-on:click 讓其內容可以被toggle
* v-show 當v-show為true時speciality會出現,不是則否
```javascript=
<template>
<div id="ninjas">
<ul>
<li v-for="ninja in ninjas" v-on:click="ninja.show = !ninja.show">
<h2>{{ninja.name}}</h2>
<h3 v-show="ninja.show">{{ninja.speciality}}</h3>
</li>
</ul></div>
</template>
<script>
export default{
data() {
return {
ninjas:[
{name:'Ryu',speciality:'Vue Components', show:false},
{name:'Crystal',speciality:'HTML Wizardry', show:false},
{name:'Hitoshi',speciality:'Click Events', show:false},
{name:'Tango',speciality:'Conditionals', show:false},
{name:'Kami',speciality:'Webpack', show:false},
{name:'Yoshi',speciality:'Data Diggin', show:false},
]
}
}
}
</script>
<style scoped>
#ninjas{
Width:100%;
max-width:1200px;
margin:40px auto;
padding:0 20px;
box-sizing:border-box;
}
ul{
display:flex;
flex-wrap:wrap;
list-style-type:none;
padding:0;
}
li{
flex-grow:1;
flex-basis:300px;
text-align:center;
padding:30px;
border:1px solid #222;
margin:10px
}
</style>
```
# Props
* 從Root component 傳送資料給nesting components
* 使用情境是當需要不同的components需要相同的資訊時可以使用Props

## 範例
把上面實作的範例做改寫:
1. 把ninjas的資料都搬回Root
1. 在Content.vue寫接收 `props:['ninjas']`
1. 在App.vue 寫 輸出prop `<app-content v-bind:ninjas="ninjas"></app-content>`
* App.vue
```javascript=
<template>
<div>
<app-header>
</app-header>
<app-content v-bind:ninjas="ninjas"></app-content>
<app-footer>
</app-footer>
</div>
</template>
<script>
import Header from'./components/Header.vue'
import Footer from'./components/Footer.vue'
import Content from'./components/Content.vue'
export default{
components:{
'app-header':Header,
'app-footer':Footer,
'app-content':Content,
},
data() {
return {
ninjas:[
{name:'Ryu',speciality:'Vue Components', show:false},
{name:'Crystal',speciality:'HTML Wizardry', show:false},
{name:'Hitoshi',speciality:'Click Events', show:false},
{name:'Tango',speciality:'Conditionals', show:false},
{name:'Kami',speciality:'Webpack', show:false},
{name:'Yoshi',speciality:'Data Diggin', show:false},
]
}
}
}
</script>
<style></style>
```
* Content.vue
1. 可以從template內部發現不需要修改,prop像是components的方式一樣使用
1. 使用在scirpt 內部的methods的部分也是一樣可以直接調用
```javascript=
methods:{
test:function(){
this.ninjas
}
}
```
```javascript=
<template>
<div id="ninjas">
<ul>
<li v-for="ninja in ninjas" v-on:click="ninja.show = !ninja.show">
<h2>{{ninja.name}}</h2>
<h3 v-show="ninja.show">{{ninja.speciality}}</h3>
</li>
</ul></div>
</template>
<script>
export default{
props:['ninjas'],
data() {
return {
}
}
}
</script>
```
## Validation
* 當收到props時我們必須確認是我們需要的資料型別(String, Array...),這邊就可以使用Validation
* required則用來確認是否Root components成功傳送props過來
* 使用在接收props的檔案
```javascript=
export default {
props: {
ninjas: {
type: Array,
required: true
}
},
data(){
return{
}
}
}
```
# Primitive vs Reference Types
## Primitive
Number, String, Boolean,
如果修改了Primivtive的資料則只會影響當下檔案的內容而不會影響到Root component,這是因為 by Primitive的性質
## Reference
Object, Array
如果修改 Reference的資料Root跟使用的component都會一起改變,這是因為 by Reference的性質
## 範例說明兩者區別
### Reference 會全部一起改變
1. 在Content.vue設置一個method刪除Content的內容
1. 在App.vue多設置一對app-content讓內容呈現兩個
1. 按下刪除按鈕會發現兩邊都會一起刪除內容
Content.vue
```javascript=
methods: {
deleteContent:function(){
this.ninjas.pop()
}
}
```
App.vue
```javascript=
<template>
<div>
<app-header>
</app-header>
<app-content v-bind:ninjas="ninjas"></app-content>
<hr/>
<app-content v-bind:ninjas="ninjas"></app-content>
<app-footer>
</app-footer>
</div>
</template>
```
印出結果:
因為by Reference操作的是同一個物件,任何改動都是同步的

### Primitive 只會改變當前檔案
* 設置App.vue的內容 title:"Vue contnet" prop到header, footer內
* 改變App.vue的內容會讓header, footer內容跟著改變
重點來了:
1. 當我們在接受prop的檔案修改Primitive時,其他檔案不會像Reference一樣改變,而是保持原樣
1. 在Header.vue使用methods changeTitle 當點擊header時修改其title為Vue Wizards
2. header修改了,此時的footer保持原樣
```javascript=
<template>
<header>
<h1 v-on:click="changeTitle">{{title}}</h1></header>
</template>
```
```javascript=
methods: {
changeTitle:function(){
this.title ="Vue Wizards"
}
}
```
印出結果:
因為這邊props傳送的是Primitive,當修改本地檔案時,不會影響其他檔案內容

# Events (child to parent)
* props是把資料從Root 傳到其他 components
* Events則是把資料從其他 components傳回 Root

## 範例-使用Event回傳修改Root進而透過prop修改其他components
* 首先在Header.vue的部分做修改並送出資料:
1. 使用 v-on:click觸發changeTitle來修改title內容
1. function changeTitle的內容使用`this.$emit('changeTitle', "Vue Wizards")`來把資料回傳回去Root
```javascript=
<template>
<header>
<h1 v-on:click="changeTitle">{{title}}</h1></header>
</template>
```
```javascript=
methods: {
changeTitle:function(){
this.$emit('changeTitle', "Vue Wizards")
}
}
```
* 在App.vue做接收Event的動作:
1. 使用`v-on:changeTitle="updateTitle($event)"`接受Header.vue的資料
1. 並使用其內容"Vue Wizards"修改Title
1. methods的部分使用參數就是`$event`也就是"Vue Wizards"(名稱可以自訂)
```javascript=
<template>
<div>
<app-header v-bind:title="title" v-on:changeTitle="updateTitle($event)"></app-header>
<app-content v-bind:ninjas="ninjas"></app-content>
<app-footer v-bind:title="title"></app-footer>
</div>
</template>
```
```javascript=
methods: {
updateTitle:function(updatedTitle){
this.title = updatedTitle;
}
}
```
# The Event Bus
* 在Event的部分是我們操作過從其他components傳送資料回去Root再由Root改變其他components
* 而Event Bus做的事情則簡化這個過程:
1. 創造一個新的Vue實體
1. 並且import到想要操作的componets內
1. 這樣就可以彼此溝通而不需要傳回Root再傳出來
## 範例說明Events Bus
* 通常使用在想要改變 siblings或是任何其他的componets但不想經過Root來更動時
1. 在main.js創造其Vue實體並且輸出
`export const bus = new Vue();`
2. 在Header.vue(想要改變的檔案):
引入bus也就是Bus Event的實體
`import {bus} from '../main';`
這邊的methods處則不使用$emit把資料傳回Root
而是使用`this.title = 'Vue Wizards'`
直接修改Header.vue的title
並且使用引入的bus做$emit資料出去給想要修改內容的其他components,並設定名稱titlechanged以及內容"Vue Wizards"
```javascript=
methods: {
changeTitle:function(){
this.title = 'Vue Wizards';
bus.$emit('titleChanged',"Vue Wizards");
}
}
```
3. Footer.vue做接收
引入bus也就是Bus Event的實體
`import {bus} from '../main';`
使用life cycle hook: created 當實體被創建時會馬上觸發此函式
接收來自Header.vue的資料也就是titleChanged使用`$on()`
並使用callback函式處理修改title成Header.vue傳送來的資料也就是"Vue Wizards"
```javascript=
created(){
bus.$on('titleChanged',(data)=>{
this.title = data;
})
}
```
4. 通過Event Bus 的傳遞就不須經過Root而是透過Vue實體Bus來傳遞兩者的資料
5. 需要注意的點是
你可以在Header.vue檔案中發現
* 除了傳送資料的函式$emit之外,他還有使用`this.title = 'Vue Wizards';`修改當前自己目前的資料
* 這個部份如果沒有處理則只會改變Footer.vue的title
* 原因在於我們只有監聽Footer.vue的event而Header.vue的部分就必須這樣自己做修改
```javascript=
methods: {
changeTitle:function(){
// this.$emit('changeTitle', "Vue Wizards")
this.title = 'Vue Wizards';
bus.$emit('titleChanged',"Vue Wizards");
}
}
```
# Life-cycle Hooks
**beforeCreate**
Vue實體初始化後立刻呼叫此函式,不過此時Vue實體還未創建所以其中的設定都還未能使用(如data observation, event, watcher setup)
**created**
Vue實例創建完成後立刻呼叫此函式,已設置 data, computed properties, methods, watch/event callbacks,但尚未開始mounting階段,且 $el 還不能在此階段使用。
**beforeMount**
在mounting階段開始前被調用:render function首次被調用。
**mounted**
選項物件中的el被新創建的vm.$el替換,並掛載到到 vm 上,並調用mounted這個鉤子。
**beforeUpdate**
數據被更新時會調用,發生在 Virtual DOM re-render 和 patch 之前(連結:Day4: Virtual DOM),可以在此時更改狀態數據,並不會增加重新渲染的成本。
**updated**
由於數據更新導致 Virtual DOM re-render 和 patch 之後會調用updated這個鉤子。
不精確白話文為:由於updated被調用時,DOM 已經更新。所以在此時更新數據很可能會導致updated無限循環的被調用。
**beforeDestroy**
在 Vue Instance 被銷毀前被調用,因此 Vue Instance 在beforeDestroy中仍可運作。
不精確白話文為:Vue Instance 可以在此時做垂死前的掙扎。
**destroyed**
在 Vue Instance 被銷毀後被調用,此時 Vue Instance 所有東西會解除綁定,事件監聽也都會被移除,子實例也會被銷毀。
## 範例 - life cycle hook 出現的時機
```javascript=
<template>
<div id="ninjas">
<ul>
<li v-for="ninja in ninjas" v-on:click="ninja.show = !ninja.show">
<h2>{{ninja.name}}</h2>
<h3 v-show="ninja.show">{{ninja.speciality}}</h3>
</li>
</ul>
<button v-on:click="deleteContent">Delete Content</button>
</div>
</template>
<script>
export default {
props: {
ninjas: {
type: Array,
required: true
}
},
data(){
return{
}
},
methods: {
deleteContent:function(){
this.ninjas.pop()
}
},
// lifecycle hooks
beforeCreate(){
alert('beforeCreate');
},
created(){
alert('created');
},
beforeMount(){
alert('beforeMount');
},
mounted(){
alert('mounted');
},
beforeUpdate(){
alert('beforeUpdate');
},
updated(){
alert('updated');
}
}
</script>
<style scoped></style>
```
重整畫面第一個出現的就是beforeCreate,畢竟是在實體出現之前所以不會有畫面呈現

第二個出現的是created實體已經被創造了,但是還沒被mounted上去,故也沒有畫面

第三個出現的是beforeMounted,在mounted之前的可以做一些處理依舊沒有畫面

第四個出現的是mounted點擊OK之後畫面產生!

畫面產生

第五按下delete Content後會出現beforeUpdate按下OK後出現update

第六後會出現updated按下OK後即更新畫面

畫面更新

# Slots
* 在子元件上面開個洞, 由外層元件將內容置放在至子層元件指定的位置中
* 可以傳送HTML tag藉由slot
## 範例 slot的使用
1. 要使用slot必須先引入子層到App.vue
`import formHelper from'./components/formHelper.vue'`
2. 輸出components處輸出到formHelper位置
```javascript=
export default{
components:{
'form-helper':formHelper
}
```
3. template處放入創好的components - form-helper
4. 輸入內容
App.vue
```javascript=
<template>
<div>
<form-helper>
<h2>I am the slot title</h2>
<p>I am the paragraph text for the slot</p>
</form-helper>
</div>
</template>
<script>
import formHelper from'./components/formHelper.vue'
export default{
components:{
'form-helper':formHelper
},
data() {
return {
}
},
methods: {
}
}
</script>
<style></style>
```
1. 在formHelper.vue則在template使用slot tag來接收來自Root的資料
formHelper.vue
```javascript=
<template>
<div>
<h1> I am the form helper</h1>
<slot></slot>
</div>
</template>
<script>
export default{
components:{
},
data() {
return {
}
},
methods: {
}
}
</script>
<style scoped></style>
```
印出結果:
就可以使用這樣的方式傳遞HTML

## 範例二 使用name抓取Root的slot
* 這時候如果我想要h1, p 各別在不同位置該怎麼處理
* 藉由命名的方式子層的slot就知道該抓取哪個部分:
1. 在App.vue命名後,在子層 使用name去抓取
App.vue
```javascript=
<template>
<div>
<form-helper>
<h2 slot="title">I am the slot title</h2>
<p slot="text">I am the paragraph text for the slot</p>
</form-helper>
</div>
</template>
```
formHelper.vue
```javascript=
<template>
<div>
<slot name="title"></slot>
<h1> I am the form helper</h1>
<slot name="text"></slot>
</div>
</template>
```
印出結果:
就可以分開呈現內容

### 修飾子層的內容
* 要處理子層的style則必須在子層的style處理
formHelper.vue
```javascript=
<style scoped>
h1{
color:red;
}
</style>
```
處出結果:

### 動態顯示文字則在Root處理
* 動態文字要修改的話主要處理在Root內
App.vue
```javascript=
<template>
<div>
<form-helper>
<h2 slot="title">{{title}}</h2>
<p slot="text">I am the paragraph text for the slot</p>
</form-helper>
</div>
</template>
<script>
import formHelper from'./components/formHelper.vue'
export default{
components:{
'form-helper':formHelper
},
data() {
return {
title:'I am a dynamic slot title'
}
},
methods: {
}
}
</script>
<style></style>
```
印出結果:

## 範例三 slot真正的用法
上面的偏向展示slot怎麼用,接下來會使用真實的範例說明如何使用slot:
製作一個網站,需要數個不同的form表單,並且他們的結構要相似但是內容必須要可以修改這時候就可以使用slots這個概念
在Root這邊處理內容:
1. 使用form-helper tag包住要傳送到子層的內容
1. 使用slot="form-相關插槽"的方式抓取子層的架構並且填上內容
```javascript=
<form-helper>
<div slot="form-header">
<h3>This is the title of the form</h3>
<p>information about the form</p>
</div>
<div slot="form-fields">
<input type="text" placeholder="name" required>

<input type="password"placeholder="password" required>
</div>
<div slot="form-controls">
<button v-on:click="handleSubmit">Submit</button>
</div>
</form-helper>
```
App.vue
```javascript=
<template>
<div>
<form-helper>
<div slot="form-header">
<h3>This is the title of the form</h3>
<p>information about the form</p>
</div>
<div slot="form-fields">
<input type="text" placeholder="name" required>
<input type="password"placeholder="password" required>
</div>
<div slot="form-controls">
<button v-on:click="handleSubmit">Submit</button>
</div>
</form-helper>
</div>
</template>
<script>
import formHelper from'./components/formHelper.vue'
export default{
components:{
'form-helper':formHelper
},
data() {
return {
title:'I am a dynamic slot title'
}
},
methods: {
}
}
</script>
<style></style>
```
子層的formHelper這邊可以處理好form的架構,使用slot name的方式接受來自Root的資料
* form-header
* form-fields
* form-controls
* useful-links
formHelper.vue
```javascript=
<template>
<div>
<h1>Please fill out our form...</h1>
<form >
<div id="form-header">
<slot name="form-header"></slot>
</div>
<div id="form-fields">
<slot name="form-fields"></slot>
</div>
<div id="form-controls">
<slot name="form-controls"></slot>
</div>
<div id="uesful-links">
<ul>
<li><a href="#">link1</a></li>
<li><a href="#">link2</a></li>
<li><a href="#">link3</a></li>
<li><a href="#">link4</a></li>
</ul>
</div>
</form>
</div>
</template>
<script>
export default{
components:{
},
data() {
return {
}
},
methods: {
}
}
</script>
<style scoped>~這邊我就省略~</style>
```
印出結果:
下次想要打造form表格就是直接在App.vue內 使用template form-helper並且抓取想要修改的slot修改好內容後就可以在做出另一個form表個瞜

# Dynamic components
在上一篇課程中我們製作了格式固定但是內容可以更改的表格,這次我們針對這個表格想要動態的切換表格內容(新增了兩個表格檔案),比方 點擊按鈕切換表格一變成二
App.vue
1. 首先在引入檔案進App.vue
2. 註冊components
3. 使用component template 並且使用 is 抓取要使用的component
4. 使用v-bind讓 is的部分做動態並在data處理component
5. 針對按鈕使用click事件 動態顯示當點哪個按鈕呈現哪個內容
6. 最後為了保存表格input內的資料輸入不會因為切換表格被刪除使用 keep-alive template
```html=
<template>
<div>
<keep-alive>
<component v-bind:is='component'></component>
</keep-alive>
<button v-on:click="component = 'form-one'">Show form one</button>
<button v-on:click="component = 'form-two'">Show form two</button>
</div>
</template>
```
```javascript=
<script>
// Imports
import formOne from './components/formOne.vue';
import formTwo from './components/formTwo.vue';
export default {
components: {
'form-one': formOne, // 註冊component
'form-two': formTwo
},
data () {
return {
component: 'form-one' // v-bind 處理的動態部分
}
},
methods: {
handleSubmit: function(){
alert('thanks for submitting');
}
}
}
</script>
```
在下兩個頁面中切換並且儲存input輸入的內容不會因為切換頁面而不見
Form One

Form Two

[formOne, formTwo 程式碼](https://github.com/iamshaunjp/vuejs-playlist/tree/lesson-28/src/components)