--- tags: VUE --- 【VUE】Vue基本 & 專案起手式 === [Guide](https://cn.vuejs.org/v2/guide/) - Vue 的應用程式在生成後,需綁定一個html元素(一次只能綁一個元素) - 一個網頁可放多個Vue應用程式 - 以**資料狀態**操作**畫面** - 不可以是**巢狀**應用程式 ```html // 不可以是巢狀 <div id="app"> {{text}} <!-- app2這裡無效 --> <div id="app2"> {{text2}} </div> </div> ``` # Vue 語法 - {{ mustache }} ## 資料綁定 - #### v-model - v-model.trim="filterText" //去掉空白 ```html <input type="text" v-model="message"> <input type="text" class="form-control" v-model.trim="filterText" @keyup.enter="filterData"> ``` - v-text ```html <p v-text="message"></p> ``` - v-html - 可代入html標籤 - 注意XSS ```html <p v-html="message"></p> ``` ```javascript message: '<h1>哈囉</h1>' ``` - v-once - 只會綁定一次,後續修改都不變 ## computed v.s. methods - computed - 是在監控資料更動後,重新運算結果呈現於畫面上 - 一般來說不會修改資料,只會回傳用於畫面呈現的資料 - methods - 就是互動的函式,需要觸發才會運作 - 會用來修改資料內容 ##### 觸發條件:data中的值有更動才會觸發 - 定義方法, 結果可以**回傳**且**能用在畫面** - 在computed宣告任何屬性都是function - 可重覆使用 ```html <div> {{ text.split('').reverse().join('') }} </div> <!-- 用computed可以縮短且重覆使用 --> <div> {{ reverseText }} </div> ``` ```javascript computed: { reverseText: function () { return this.text.split('').reverse().join(''); } } ``` ## 元件化 - 重覆使用, data值不會互相影響 ```html <counter-component></counter-component> <counter-component></counter-component> ``` - Vue.component( '元件名稱', {} ) - 元件內容 - data: function(){} 需要是function - template: html樣版 ```javascript Vue.component('counter-component', { // data需要是一個function data() { return { counter: 0 } }, template: ` <div class="my-3">你已經點擊 <button class="btn btn-outline-secondary btn-sm" @click="counter += 1">{{ counter }}</button> 下。 </div> ` }); ``` 1. npm install vue-cli -g ```javascript npm install vue-cli -g // -g 全域工具, for整台電腦 // sudo npm install vue-cli -g // 權限問題 ``` 3. vue init webpack 專案名 4. cd 專案名 5. npm run dev //開始編譯 6. npm run build // 編譯靜態資源 # vue 專案起手式 1. 使用元件化切分複雜網頁 2. 使用vue-router製作多頁面 3. 使用vuex統一狀態更動 ### Vue元件化 - 將網頁依功能拆分 - 小至按鈕,大致頁面 - single file component ### 資料夾結構 - src - components - manage: 後台頁面 - member: 會員頁面 - page: about, blog... - navbar - newsbox... - static: 靜態檔案 - dist ### Vue 結構 1. template ``` npm install -D pug pug-loader pug-filters ``` ```html <template lang="pug"> ... </template> ``` 2. script 3. style ``` npm i -D sass sass-loader node-sass --save ``` ```html <style lang="sass"> </style> ``` > sass編譯問題解決 > Sass Loader has been initialized using an options object that does not match the API schema #### 解1: 降版 ``` npm uninstall --save-dev sass-loader npm install --save-dev sass-loader@7.1.0 ``` #### 解2 (未完全解決 ) [解2](https://cli.vuejs.org/guide/css.html#passing-options-to-pre-processor-loaders) ### Vue 元件化概念 - 新增/使用元件 - 傳遞屬性 props - 釋放事件 $emit - 元件重用控制: key ### Vue元件化- 新增/使用元件 1. 每個元件有自己的data/computed/methods 2. data需要回傳資料的函數(非物件) ![螢幕快照 2020-05-22 上午9.56.39.png](:storage/93e4a593-10fc-4ca6-bc9c-fec97f425f78/cb328713.png) ### Vue元件化-傳遞屬性 props - 使用v-bind:屬性 或 :屬性 傳值給元件 - [參考網站](https://vuejs.org/v2/guide/components-props.html) ```html <component v-bind:value='10' :post=post> </component> ``` ```javascript // 元件會接受到值,當作內部資料使用 { props: ['propname'] data: { ... } } // or { props: { title: String } } ``` ### Vue元件化 - 釋放事件$emit - 自訂事件 ```html <component @save="..."></component> ``` ```javascript this.$emit("save", somedata) ``` ### Vue元件化-元件重用控制: key - key若變了,重新產生這個物件 - key一樣時則重覆使用這個元件 #### example - 列表頁是否重新render文章 ### Vue Router 路由 - 根據網址決定呈現頁面(元件) - 靜態網址、動態網址 ## Vue Router 使用 - 新增路徑設定 - 連結router-link(:to) ```javascript import PagePost from './components/page/pagePost.vue' const router = new VueRouter({ routes: [ { path: '/post', component: pagePost } ] }) ``` ```vue <router-view></router-view> <router-link to="/post"></router-link> ``` ### Vue-router動態路徑 - 路由相關路徑 $route - 參數: params(網址) / meta (其他) ```javascript const router = new VueRouter({ routes: [ { path: '/post/:id', component: Post } ] }) ``` ### Vue-router事件掛載 - hook頁面轉移前方法 - beforeEach / afterEach, e.g. GA/紀錄 或是 條件判斷 ```javascript router.beforeEach((to, from, next) => { // ... }) router.afterEach((to, from) => { // ... }) ``` ### Vue-router模式 - hash mode: /#/post - history mode: /post ```javascript let router = new Router({ mode: 'history', routes: [ // ... ] }); ``` ### Vue-router 變化 - transition + fade ```vue <transition name="page" mode="out-in"> <router-view :key="$route.path"></router-view> </transition> ``` ```sass // page 對應 name .page-enter-active, .page-leave-active transition: .5s .page-enter, .page-leave-to opacity: 0 ``` # MVVM - Model view viewmodel 軟體架構模式 - model: 資料存取層(以資料為中心),操控的部分 - view: 畫面(layout, 外觀等),看到的部分 - viewModel: 連接器,基本上寫程式不會動到,靠它自動轉換view 和 model的資料狀態 ![螢幕快照 2020-06-03 上午9.33.49.png](:storage/93e4a593-10fc-4ca6-bc9c-fec97f425f78/1e2ed17d.png)