---
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需要回傳資料的函數(非物件)

### 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的資料狀態
