---
# System prepended metadata

title: 【VUE】Vue基本 & 專案起手式
tags: [VUE]

---

---
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)