Vue JS 2 Tutorial part 2 The Vue CLI 創造一個可以使用webpack的開發環境 使用ES6 編譯並且讓檔案容量縮小成一個JS檔 使用single file template給網頁的不同app使用 在渲染到畫面上前,編譯所有的內容在本地端而不是在瀏覽器上 使用在即時更新的伺服器上 使用方式:
安裝node.js 確認是否安裝成功輸入 node -v 出版本就是成功摟 npm install -g vue-cli
vue create <project-name>
接下來會出現一些問題需要回答:
這邊作者選擇Maunally select features
可以視專案需求做選擇
下一步選擇vue.js的版本
下一步選擇 In dedicated config files
下一步會詢問是否儲存設定建議選擇N 畢竟每次專案設定不同看需求而定
接下來我們進入資料夾 cd vue-crash-2021會發現需要的資料都已經載入
下一步使用
就可以成功叫出來瞜!
Vue Files & The Root Component 針對剛剛產生出來的vue-cli檔案做一些解析
Vue Files assets 放置圖片Logo的區域 需要使用到的img都可以放置在這區 main.js 控制所有的components的檔案
1 2 3 4 5 6 7 import Vue from 'vue' import App from './App.vue' new Vue({ el: '#app' , render: h => h(App) })
從最基礎的檔案中可以看出它引入了:
Vue(就是整個框架內容) App App就是指這個部分的檔案,也就是The Root Component
並創造一個新的Vue實體:
抓取id=app這個元素並且把App.vue的內容渲染到元素上面位於index.html內
html內部抓取的div
The Root Component 也就是剛剛提到的App的部分
可以發現這樣的vue檔案其實就是vue components的延伸,但是拆分到不一樣的檔案
特別注意 template內部只能用一個div包裹住全部的html如果有兩個會報錯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 <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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <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都可以使用
import 資料夾名稱 from 資料夾位置 並且components建立在這裡Vue.component('ninjas', Ninjas);
1 2 3 4 5 6 7 8 9 10 11 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <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上面操作
把import的部分寫在App.vue內 把components的內容寫在App.vue內部script內 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <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 成品:
成品功能: 點擊人物名稱會顯示使用技能 HTML 畫面呈顯處index.html
html程式碼: 1 2 3 4 5 6 7 8 9 10 11 <!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內 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <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>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <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>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <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會出現,不是則否 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <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
範例 把上面實作的範例做改寫:
把ninjas的資料都搬回Root 在Content.vue寫接收 props:['ninjas']
在App.vue 寫 輸出prop <app-content v-bind:ninjas="ninjas"></app-content>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <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>
可以從template內部發現不需要修改,prop像是components的方式一樣使用 使用在scirpt 內部的methods的部分也是一樣可以直接調用1 2 3 4 5 methods:{ test:function ( ) { this .ninjas } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <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的檔案 1 2 3 4 5 6 7 8 9 10 11 12 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 會全部一起改變 在Content.vue設置一個method刪除Content的內容 在App.vue多設置一對app-content讓內容呈現兩個 按下刪除按鈕會發現兩邊都會一起刪除內容 Content.vue
1 2 3 4 5 methods: { deleteContent:function ( ) { this .ninjas.pop() } }
App.vue
1 2 3 4 5 6 7 8 9 10 11 <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內容跟著改變 重點來了:
當我們在接受prop的檔案修改Primitive時,其他檔案不會像Reference一樣改變,而是保持原樣 在Header.vue使用methods changeTitle 當點擊header時修改其title為Vue Wizards header修改了,此時的footer保持原樣 1 2 3 4 <template> <header> <h1 v-on:click="changeTitle" >{{title}}</h1></ header> </template>
1 2 3 4 5 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的部分做修改並送出資料: 使用 v-on:click觸發changeTitle來修改title內容 function changeTitle的內容使用this.$emit('changeTitle', "Vue Wizards")
來把資料回傳回去Root 1 2 3 4 <template> <header> <h1 v-on:click="changeTitle" >{{title}}</h1></ header> </template>
1 2 3 4 5 methods: { changeTitle:function ( ) { this .$emit('changeTitle' , "Vue Wizards" ) } }
使用v-on:changeTitle="updateTitle($event)"
接受Header.vue的資料 並使用其內容”Vue Wizards”修改Title methods的部分使用參數就是$event
也就是”Vue Wizards”(名稱可以自訂) 1 2 3 4 5 6 7 <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>
1 2 3 4 5 methods: { updateTitle:function (updatedTitle ) { this .title = updatedTitle; } }
The Event Bus 創造一個新的Vue實體 並且import到想要操作的componets內 這樣就可以彼此溝通而不需要傳回Root再傳出來 範例說明Events Bus 通常使用在想要改變 siblings或是任何其他的componets但不想經過Root來更動時 在main.js創造其Vue實體並且輸出 export const bus = new Vue();
在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”
1 2 3 4 5 6 methods: { changeTitle:function ( ) { this .title = 'Vue Wizards' ; bus.$emit('titleChanged' ,"Vue Wizards" ); } }
Footer.vue做接收 引入bus也就是Bus Event的實體
import {bus} from '../main';
使用life cycle hook: created 當實體被創建時會馬上觸發此函式
接收來自Header.vue的資料也就是titleChanged使用$on()
並使用callback函式處理修改title成Header.vue傳送來的資料也就是”Vue Wizards”
1 2 3 4 5 created ( ) { bus.$on('titleChanged' ,(data )=> { this .title = data; }) }
通過Event Bus 的傳遞就不須經過Root而是透過Vue實體Bus來傳遞兩者的資料
需要注意的點是
你可以在Header.vue檔案中發現
除了傳送資料的函式$emit之外,他還有使用this.title = 'Vue Wizards';
修改當前自己目前的資料 這個部份如果沒有處理則只會改變Footer.vue的title 原因在於我們只有監聽Footer.vue的event而Header.vue的部分就必須這樣自己做修改 1 2 3 4 5 6 7 methods: { changeTitle:function ( ) { 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 出現的時機 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <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() } }, 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的使用 要使用slot必須先引入子層到App.vueimport formHelper from'./components/formHelper.vue'
輸出components處輸出到formHelper位置
1 2 3 4 export default { components:{ 'form-helper' :formHelper }
template處放入創好的components - form-helper 輸入內容 App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <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>
在formHelper.vue則在template使用slot tag來接收來自Root的資料 formHelper.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <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就知道該抓取哪個部分: 在App.vue命名後,在子層 使用name去抓取 App.vue
1 2 3 4 5 6 7 8 <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
1 2 3 4 5 6 7 <template> <div> <slot name="title" ></slot> <h1> I am the form helper</h1> <slot name="text" ></slot> </div> </template>
印出結果:
就可以分開呈現內容
修飾子層的內容 要處理子層的style則必須在子層的style處理 formHelper.vue
1 2 3 4 5 <style scoped> h1{ color:red; } </style>
處出結果:
動態顯示文字則在Root處理 App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <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這邊處理內容:
使用form-helper tag包住要傳送到子層的內容 使用slot=”form-相關插槽”的方式抓取子層的架構並且填上內容 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <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> ![](https: <input type="password" placeholder="password" required> </div> <div slot="form-controls" > <button v-on:click="handleSubmit" >Submit</button> </div> </form-helper>
App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <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
首先在引入檔案進App.vue 註冊components 使用component template 並且使用 is 抓取要使用的component 使用v-bind讓 is的部分做動態並在data處理component 針對按鈕使用click事件 動態顯示當點哪個按鈕呈現哪個內容 最後為了保存表格input內的資料輸入不會因為切換表格被刪除使用 keep-alive template 1 2 3 4 5 6 7 8 9 10 <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 >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script> import formOne from './components/formOne.vue' ;import formTwo from './components/formTwo.vue' ;export default { components: { 'form-one' : formOne, 'form-two' : formTwo }, data () { return { component: 'form-one' } }, methods: { handleSubmit: function ( ) { alert('thanks for submitting' ); } } } </script>
在下兩個頁面中切換並且儲存input輸入的內容不會因為切換頁面而不見
Form One
Form Two
formOne, formTwo 程式碼