本篇主要是透過線上課程:HiSKIO
、官方文件及網路上搜尋資源所學習的。
列表渲染 Lists render
v-for 把陣列轉為一組元素
舉例說明:v-for="item in todo"
,前面參數item代表各個元素,後面todo代表整個陣列是陣列。
如果是從 1 開始到實際已知的數值可以不用宣告陣列。
也可以用 v-for 取 index 值:v-for="(month, index) in months"
。
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
| <div id="app"> <ol> <li v-for="item in todo">{{item}}</li> </ol> <select>
<option v-for="(month, index) in months" :value="index+1">{{month}}</option> </select> </div> <script> new Vue({ el: "#app", data: { todo: ["學會JavaScript", "學會Vue", "投履歷", "找到工作"],
months: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] } }); </script>
|
v-for 把物件轉為一組元素
基本上用法與陣列轉換相同,但有些情況 v-for 在物件中不保證會按照宣告的順序呈現,ex.用數字宣告。
如果要按照順序,就使用陣列宣告。
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
| <div id="app">
<div v-for="item in friend">{{item.prop}} - {{item.value}}</div> </div>
<script> new Vue({ el: "#app", data: {
friend: [ { prop: "name", value: "Joe" }, { prop: "id", value: "Superman" }, { prop: 32, value: "訂婚" }, { prop: 28, value: "創辦公司" } ] } }); </script>
|
修改陣列或物件的注意事項
透過修改陣列與物件,結果會直接反應在 html 元素上,但也有一些狀況是不會直接反應在元素上。
1 2 3 4 5 6 7
| <div id="app"> <ul> <li v-for="(num, key) in nums">{{key}}: {{num}}</li> </ul> <button @click="action">Yo</button> </div>
|
陣列修改:
能夠直接反應:
陣列的push
, pop
, unshift
, shift
, splice
, sort
, reverse
,新增移除,由小到大排序,反轉等等都可以直接反應在元素上。filter
會過濾後產生新陣列,也能夠直接反應。
不能夠直接反應:
用指定 index 的方式來操作,陣列會被改變,但 vue 沒辦法偵聽到這個變更,要即時反應在元素上可以用splice
來操作。
指定陣列的長度來修改也沒辦法直接反應在元素上,但可以透過splice
或slice
來操作即可。
slice是區間取值 slice(index1, index2) from index1 to index2
,算頭不算尾
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
| new Vue({ el: "#app", data: { nums: [1, 2, 3, 4, 5, 6, 7, 8]
}, methods: { action() {
this.nums = this.nums.slice(1, 3); } } });
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| new Vue({ el: "#app", data: { nums: { x: 10, y: 20 } }, methods: { action() { this.nums.x = 111;
this.$set(this.nums, "z", 30); // Vue.set Vue.set(this.nums, "z", 30); } } });
|
列表的過濾與排序
- reverse 反轉
- filter 過濾偶數
- sort 排序
要注意到 sort 會直接修改原本的陣列,可以先用 slice 來取陣列後 sorting。
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
| <div id="app"> <ul> <li v-for="num in nums">{{num}}</li> </ul> <button @click="reverse">Reverse</button> <button @click="all">All</button> <button @click="even">Even</button> <button @click="sort">Sort</button> </div>
<script> const orgNums = [5, 8, 1, 4, 3, 2, 9, 7, 6]; new Vue({ el: "#app", data: { nums: orgNums }, methods: { reverse() { this.nums.reverse(); }, even() { this.nums = orgNums.filter(num => num % 2 === 0); }, all() { this.nums = orgNums; }, sort() { this.nums = orgNums.slice().sort(); } } }); </script>
|
v-for 渲染 template
一個元素不只要 render 出自己本身以外,可以用 template 模板(不是實際存在的元素)來渲染。
ex. 每個 h1 後要接上 hr 的標籤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div id="app"> <template v-for="header in headers"> <h1>{{header}}</h1> <hr /> </template> </div>
<script> new Vue({ el: "#app", data: { headers: ["About", "Products", "Contact"] } }); </script>
|
實作-json 資料渲染課程列表
從 data.json(用陣列包住)中用 ajax 方式獲取資料來渲染成列表。
data.json 格式範例
1 2 3 4 5 6
| { "img": "https://cdn.hiskio.com/courses/145/cover/1510133824V8glV.png", "url": "https://hiskio.com/course/145", "title": "精通 VueJS 之 前端開發完全指南 預購中", "teacher": "諾浩設計講堂" },
|
用 v-for 迴圈帶出背景圖片、標題搭配 a 連結、課程老師。
要用背景圖來渲染,所以用上 v-bind 動態綁定屬性,a 連結的 href 也是動態綁定。
ajax 在 mounted 階段就去初始化,用原生的fetch
來串接,之後再用then
搭配箭頭函式,把值 return 到原本 vue 實例中 data 的空陣列裡面。
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
| <div id="app"> <div v-for="lesson in lessons" class="lesson"> <div class="image" :style="imgStyle(lesson.img)"></div> <a :href="lesson.url"> <h1>{{lesson.title}}</h1> </a> <span class="teacher">{{lesson.teacher}}</span> </div> </div>
<script> new Vue({ el: "#app", data: { lessons: [] }, mounted() { fetch("./data.json") .then(res => res.json()) .then(lessons => (this.lessons = lessons)); }, methods: { imgStyle(img) { return { backgroundImage: `url(${img})` }; } } }); </script>
|
剩下的就是 css 的渲染設定
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
| html, body { font-family: Arial, Microsoft JhengHei; } h1 { font-size: 18px; } a { color: #369; text-decoration: none; } .teacher { font-size: 12px; } .lesson { display: inline-block; width: 240px; border-radius: 8px; margin: 12px; padding: 8px; position: relative; height: 100px; padding-top: 150px; overflow: hidden; box-shadow: 4px 4px 20px rgba(0, 0, 0, 0.3); } .image { width: 100%; height: 150px; background-size: cover; background-position: center center; top: 0; left: 0; position: absolute; }
|
JSON 資料補充
json 中,物件的 key 需要用雙引號,物件中最後一個 key 或是 value 後不能有逗號,不能有函式(但可以宣告成字串,之後用 js 取出來用)。
JSON.stringify()
括號中可以含三個參數,第一個是內容,第二個是 replacer,第三個是數字。
第二個 replacer,內容輸出後只會有第二個參數傳入陣列的內容會留下。
第三個數字,為了可讀性,斷行,縮排的次數。
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
|
const dataJSON = { "name": "point", "x": 2, "y": 4 };
let data; try { data = JSON.parse(dataJSON); } catch (err) { data = {}; }
const dataJSON = JSON.stringify(data, ["x", "y"], 2);
const dataJSON = JSON.stringify(data, null, 2);
|