# Vue.js 1207 只做部分宣染效能較好 codepen>setting>js>搜尋vue>選取需要版本>save&close ## v-model html ``` <div id ="app"> <input type="text" v-model="message"> <span> {{message}} </span> </div> ``` js ``` new Vue({ el: '#app', //選擇ID data: { message: '內容' } }) ``` * `v-model="message"`與`{{message}}`可以讓html引入Vue.js的data內容 virtual DOM 虛擬DOM ================================= ## v_for 製造迴圈效果 html ``` <div id="app"> <ul> <li v-for="f in friends">{{ f }}</li> </ul> </div> ``` js ``` new Vue({ el: '#app', data: { message: '', friends: ['aa', 'bb', 'cc'] } }) ``` * `v-for="f in friends`可以有迴圈效果,依序輸出friends的內容,f為自定義的變數(類似Ruby的each do效果 `friend.each do |f|`) 查 變數shalld ================================= ## v-if html ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> </head> <body> <div id="app"> <span v-if="isAdult">18禁</span> </div> <script src="script.js"></script> </body> </html> ``` js ``` new Vue({ el: '#app', data: { message: '', friends: ['aa', 'bb', 'cc', 'dd'], isAdult: true } }) ``` * `v-if="isAdult"`時顯示18禁 ================================= ## v-else html ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> </head> <body> <div id="app"> <button @click="isAdult = !isAdult">按我</button> <span v-if="isAdult">18禁</span> <span v-else>皆可</span> </div> <script src="script.js"></script> </body> </html> ``` js ``` new Vue({ el: '#app', data: { message: '', friends: ['aa', 'bb', 'cc', 'dd'], isAdult: true } }) ``` * `@click="isAdult = !isAdult"` 點擊時isAdult變成否定 * v-else與v-if搭配,v-else會找最近的v-if搭配,而v-if可以單獨使用 ================================= ## v-show html ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> </head> <body> <div id="app"> <button @click="isAdult = !isAdult">按我</button> <span v-show="isAdult">18禁show</span> <span v-if="isAdult">18禁if</span> </div> <script src="script.js"></script> </body> </html> ``` js ``` new Vue({ el: '#app', data: { message: '', friends: ['aa', 'bb', 'cc', 'dd'], isAdult: true } }) ``` * v-show只是改變css狀態(display: none;),v-if則是會真正消除元素(檢視原始碼可看到狀態改變)較吃效能,原則上需要頻繁切換用v-show ================================== ## v-bind ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> </head> <body> <div id="app"> <a v-bind:href="url">連結</a> </div> <script src="script.js"></script> </body> </html> ``` js ``` new Vue({ el: '#app', data: { message: '', friends: ['aa', 'bb', 'cc', 'dd'], isAdult: true, url: 'www.yahoo.com' } }) ``` * herf這種內建的屬性不能用href={{url}}或href="url"寫法不會直接翻譯,要用v-bind * `v-bind:href="url"`中的v-bind可以省略,變成`:href="url"` ============================== ## v-on html ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> </head> <body> <div id="app"> <a v-bind:href="url">連結</a> <button v-on:click="clickme">按我</button> </div> <script src="script.js"></script> </body> </html> ``` js ``` new Vue({ el: '#app', data: { message: '', url: 'www.yahoo.com' }, methods: { clickme: function (e) { console.log('clicked') } } }) ``` * el與methods都是固定用法不可改字 * `v-on:click="clickme"`中的v-on也可以省略,變成`@click="clickme"` ================================ html ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> </head> <body> <div id="app"> 年紀: <input type="text" @input="ageChange"> <span v-if="isAdult"> 18禁</span> <span v-else>未成年</span> </div> <script src="script.js"></script> </body> </html> ``` js ``` new Vue({ el: '#app', data: { message: '', isAdult: false, url: 'https://www.yahoo.com.tw' }, methods: { clickme: function (e) { console.log('clicked!') }, ageChange: function (e) { let age = Number(e.target.value) if (age >= 18) { //delegation 代理 this.isAdult = true } else { this.isAdult = false } } } }) ``` * `@input="ageChange"` 當輸入事件發生執行ageChange方法 * `let age = Number(e.target.value)`Number是做數字轉換 * `this.isAdult`因為vue.js改變了this的行為,與js中不同,一般function有自己的this,沒辦法穿越function找到isAdult而變成undefind ## 另外一種寫法v-model ``` html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> </head> <body> <div id="app"> 年紀: <input type="text" v-model="age"> <span v-if="age >= 18"> 18禁</span> <span v-else>未成年</span> </div> <script src="script.js"></script> </body> </html> ``` js ``` new Vue({ el: '#app', data: { message: '', isAdult: false, age: '', url: 'https://www.yahoo.com.tw' }, methods: { clickme: function (e) { console.log('clicked!') } } } }) ``` ## computed html ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script> </head> <body> <div id="app"> 年紀: <input type="text" v-model="age"> <span v-if="isAdult"> 18禁</span> <span v-else>未成年</span> </div> <script src="script.js"></script> </body> </html> ``` js ``` new Vue({ el: '#app', data: { message: '', age: '', url: 'https://www.yahoo.com.tw' }, computed: { isAdult() { return this.age >= 18 } } }) ``` * computed內的資料性質較接近data內的屬性,但是可以放計算式(data內的只是單純變數只能透過外部動作(input,click等)改變) * methods的則像動詞,是放發生某件事(input,click等)時要執行的某個動作 * js中的function要寫return否則會出現undefind ================================ ##BMI計算器 html ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> @import url(https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300); body { background-color: #F1F1F1; } .clearfix { clear: both; } .calculator { max-width: 600px; margin-left: auto; margin-right: auto; margin-top: 20px; padding: 30px; background-color: #CDDE47; border-radius: 20px; box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2); } .calculator h1 { font-weight: 200; font-size: 3em; margin-top: 0; margin-bottom: 0; } .calculator h2 { font-weight: 200; } .fields { width: 50%; float: left; } .result { width: 50%; float: left; } #resultText { font-family: 'Open Sans Condensed'; text-align: center; font-weight: 100; font-size: 100px; } input[type="number"] { font-family: 'Open Sans Condensed'; font-size: 1.5em; margin-top: 10px; margin-left: 5px; margin-right: 10px; padding: 10px; border: 2px dashed gray; } input[type="submit"] { margin-top: 30px; width: 100%; padding: 20px; border-radius: 8px; box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); font-size: 2em; font-weight: 200; } </style> <script src='main.js'></script> </head> <body> <section class="calculator"> <section class="fields"> <h1>BMI 計算機</h1> <h2>想要健康嗎?趕快動起來!</h2> <div> <label for="bodyHeight">身高</label> <input type="number" id="bodyHeight" min="0">公分 </div> <div> <label for="bodyWeight">體重</label> <input type="number" id="bodyWeight" min="0">公斤 </div> <input type="submit" value="計算" class="bmi_btn"> </section> <section class="result"> <h2>計算結果:</h2> <p id="resultText">0</p> </section> <div class="clearfix"></div> </section> </body> </html> ``` js ``` // 原生js window.addEventListener('DOMContentLoaded', function () { document.querySelector(".bmi_btn").addEventListener("click", function () { const height = document.querySelector("#bodyHeight").value / 100 const weight = document.querySelector("#bodyWeight").value const bmi = weight / (height * height) const result = document.querySelector("#resultText") resultText.innerHTML = Math.round(bmi * 100) / 100 }) }) // jQuery寫法 // $(".bmi_btn").click(function){ // const height = $("#bodyHeight").val() / 100 // const weight = $("#bodyWeight").val() // const bmi = weight / (height * height) // const result = $("#resultText") // result.text(Math.round(bmi * 100) / 100) // } ``` vue js jq計算bmi 原生js jq寫自動計算bmi ================================ `$rails webpacker:install:vue`在rails專案中引入vue 在JavaScript資料夾下增加APP.vue示範檔是個元件檔 ================================ 查data message computed的差別 1620 mounted 生命週期有掛仔就會啟動 vue官網影片元件引用