---
title: Vue 學習
tags: vue
---
> [中文文檔](https://v3.cn.vuejs.org/guide/introduction.html)
> [CSS 函式庫 Bootstrap](https://bootstrap5.hexschool.com/)
> [chrome 擴充](https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg)

### VSCode 相關套件
- [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)
- [Vue 官方提供的 Vue 整合插件](https://marketplace.visualstudio.com/items?itemName=octref.vetur)
- [Vue 3 Snippets](https://marketplace.visualstudio.com/items?itemName=hollowtree.vue-snippets)
---
### 運作概念
**MVVM** 全名為 Model-View-ViewModel
* M 代表 Model(存放資料)
* V 代表 View(畫面顯示)
* VM 稱作 ViewModel(資料與畫面互動)

### createApp
```javascript
<div id="app">
{{counter}}
{{text}}
</div>
<script>
Vue.createApp({
data() {
return {
counter: 5,
text: '這是一段話',
}
}
}).mount('#app')
</script>
```

### 起手式
:::info
可輸入 `div.app` or `div#app`
:::
```javascript
<div id="app">
{{ counter }}
<button type="button" v-on:click="clickMe"> 按我 </button>
</div>
<script>
const app = {
// 資料 -> 函式
data(){
return{
counter: 0
}
},
// 生命週期 -> 函式
created() {
this.counter = 10
console.log(this);
},
// 方法 -> 物件
methods: {
clickMe() {
console.log(1);
this.counter = this.counter + 1
}
},
}
Vue.createApp(app).mount('#app')
</script>
```

### 雙向綁定
```javascript
<div id="app">
<form>
{{ temp }}
<div class="mb-3">
<label for="productName" class="form-label">產品名稱</label>
<input type="text" id="productName" class="form-control" v-model="temp.name">
</div>
<div class="mb-3">
<!-- html 屬性 -->
<img v-bind:src="temp.imageUrl" class="img-fluid" alt="">
<label for="productImage"
class="form-label">產品圖片</label>
<input type="text" id="productImage"class="form-control" v-model="temp.imageUrl">
</div>
<button type="button" class="btn btn-secondary" v-on:click="confirmEdit">更新</button>
</form>
</div>
<script>
const App = {
data() {
return {
temp: {
name: '',
imageUrl: 'https://images.unsplash.com/photo-1602526430780-782d6b1783fa?ixid=MXwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80'
}
}
},
methods: {
confirmEdit(){
console.log(this.temp)
}
},
};
Vue.createApp(App).mount('#app');
</script>
```
### 資料操作

```javascript
<div id="app">
<form>
<div class="mb-3">
<label for="productName" class="form-label">產品名稱</label>
<input type="text" id="productName" class="form-control" v-model="temp.name">
</div>
<div class="mb-3">
<img :src="temp.imageUrl" class="img-fluid d-block" alt="" width="300">
<label for="productImage" class="form-label">產品圖片</label>
<input type="text" id="productImage" class="form-control" v-model="temp.imageUrl">
</div>
<button type="button" class="btn btn-secondary" v-on:click="confirmEdit">更新</button>
</form>
</div>
<script>
const products = [{
id: '1',
imageUrl: 'https://images.unsplash.com/photo-1516906571665-49af58989c4e?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=300&q=80',
name: 'MacBook Pro',
onStock: false,
},{
id: '2',
imageUrl: 'https://images.unsplash.com/photo-1512499617640-c74ae3a79d37?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80',
name: 'iPhone',
onStock: false,
}];
const App = {
data() {
return {
products: [],
temp: {
name: '卡斯伯',
imageUrl: 'https://images.unsplash.com/photo-1602526430780-782d6b1783fa?ixid=MXwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80'
}
}
},
methods: {
confirmEdit() {
this.temp.id = new Date().getTime();//unix timestamp
this.temp.onStock = false;
console.log(this.temp);
this.products.push(this.temp); // 把 temp 加到 products
this.temp = {};
}
},
created() {
this.products = products;
},
};
Vue.createApp(App).mount('#app');
</script>
```
### 多筆資料渲染

```javascript
<tr v-for="item in products" :key="item.id" v-bind:class="{'table-success': item.onStock}">
<td> {{ item.name }} </td>
<td>
<img v-bind:src="item.imageUrl" alt="">
</td>
<td>
<input type="checkbox" v-model='item.onStock'>
<!-- {{ item.onStock }} -->
</td>
<td>
<button type="button" class="btn btn-outline-primary"> 編輯 </button>
</td>
</tr>
```
### 指令

#### `v-for`
```javascript
<ul>
<li v-for="(item, key) in products"> {{key+1}} . {{item.name}}/{{item.price}}元</li>
</ul>
```
```javascript
products: [
{
name: '蛋餅',
price: 30,
vegan: false
},
{
name: '飯糰',
price: 35,
vegan: false
},
{
name: '小籠包',
price: 60,
vegan: false
},
{
name: '蘿蔔糕',
price: 30,
vegan: true
},
],
```

```javascript
<ul>
<li v-for="(item, key) in productsObj"> {{key}} . {{item.name}}/{{item.price}}</li>
</ul>
```
```javascript
productsObj: {
chineseOmelette: {
name: '蛋餅',
price: 30,
vegan: false
},
riceBall: {
name: '飯糰',
price: 35,
vegan: false
},
soupDumpling: {
name: '小籠包',
price: 60,
vegan: false
},
radishCake: {
name: '蘿蔔糕',
price: 30,
vegan: true
}
},
```
