# 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官網影片元件引用