要求實現下面的小Demo,能夠經過計算屬性獲得全名,但這樣沒法顯示計算屬性的優越性,因此我還用了插值語法與methods方法實現,但願對你的理解有幫助。 javascript
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>姓名案例_插值語法實現</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準備好一個容器-->
<div id="root">
姓:<input type="text" v-model="firstName"> <br /><br />
名:<input type="text" v-model="lastName"> <br /><br />
全名:<span>{{firstName.slice(0,3)}}-{{lastName}}</span>
<!-- 要求截取前三位,還能夠在{{}}添加更多需求,可是十分不推薦,應該儘可能簡潔 -->
<!-- 全名:<span>{{firstName+ '-' +lastName}}</span> -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在啓動時生成生產提示。
new Vue({
el: '#root',
data: {
firstName: '張',
lastName: '三'
}
})
</script>
</html>
複製代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>姓名案例_methods實現</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準備好一個容器-->
<div id="root">
姓:<input type="text" v-model="firstName"> <br /><br />
名:<input type="text" v-model="lastName"> <br /><br />
全名:<span>{{fullName()}}</span>
</div>
</body>
<!-- data中的數據發生改變,vue模板會從新解析,對data從新讀取,若是有在模板裏面調方法,方法也會從新被調用 -->
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在啓動時生成生產提示。
new Vue({
el: '#root',
data: {
firstName: '張',
lastName: '三'
},
methods: {
fullName() {
console.log('@---fullName')
return this.firstName + '-' + this.lastName
}
},
})
</script>
</html>
複製代碼
計算屬性:
1.定義: 要用的屬性不存在,要經過已有屬性(Vue實例中的屬性)計算得來。
2.原理: 底層藉助了Object.defineproperty方法提供的getter和setter。
3.get函數何時執行?
(1).初次讀取時會執行一次。
(2).當依賴的數據發生改變時會被再次調用。
4.優點: 與methods實現相比,內部有緩存機制(複用),效率更高,調試方便。
5.備註:
1.計算屬性最終會出如今vm上,直接讀取使用便可。不能寫fullName.get(),沒有這種寫法。
2.若是計算屬性要被修改,那必須寫set函數去響應修改,且set中要引發計算時依賴的數據發生改變。css
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>姓名案例_計算屬性實現</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準備好一個容器-->
<div id="root">
姓:<input type="text" v-model="firstName"> <br /><br />
名:<input type="text" v-model="lastName"> <br /><br />
測試:<input type="text" v-model="x"> <br /><br />
全名:<span>{{fullName}}</span> <br /><br />
全名:<span>{{fullName}}</span> <br /><br />
全名:<span>{{fullName}}</span> <br /><br />
全名:<span>{{fullName}}</span>
<!-- 多個fullName初始只會調用一次get(),由於緩存了 ,用methods方法調用沒有緩存-->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在啓動時生成生產提示。
const vm = new Vue({
el: '#root',
data: {
firstName: '張',
lastName: '三',
x: '你好'
},
computed: {
fullName: {
//get有什麼做用?當有人讀取fullName時,get就會被調用,且返回值就做爲fullName的值
//get何時調用?1.初次讀取fullName時。2.所依賴的數據發生變化時。
get() {
console.log('get被調用了')
console.log(this) //此處的this是vm
return this.firstName + '-' + this.lastName
},
//set何時調用? 當fullName被修改時。
set(value) {
console.log('set', value)
const arr = value.split('-')
// 用-作分隔符將其變爲數組
this.firstName = arr[0]
this.lastName = arr[1]
//能夠用vm.fullName = '李四'更改fullname的值
}
//在多數狀況下只考慮讀取不考慮修改,能夠把set部分刪掉,簡寫
// fullName(){
// console.log('get被調用了')
// return this.firstName + '-' + this.lastName
//}
//注意上方模板{{}}中依然放fullName,不帶括號。
}
}
})
</script>
</html>
複製代碼
監視屬性watch:
1.當被監視的屬性變化時, 回調函數自動調用, 進行相關操做
2.監視的屬性必須存在,才能進行監視!!
3.監視的兩種寫法:
(1).new Vue時傳入watch配置
(2).經過vm.$watch監視html
深度監視:
(1).Vue中的watch默認不監測對象內部值的改變(一層)。
(2).配置deep:true能夠監測對象內部值改變(多層)。
備註:
(1).Vue自身能夠監測對象內部值的改變,但Vue提供的watch默認不能夠!
(2).使用watch時根據數據的具體結構,決定是否採用深度監視。vue
<!DOCTYPE html>
<html> <head> <meta charset="UTF-8" /> <title>天氣案例_監視屬性</title> <!-- 引入Vue --> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準備好一個容器--> <div id="root"> <h2>今每天氣很{{info}} {{x}}</h2> <!-- 綁定事件的時候:@xxx="yyy" yyy能夠寫一些簡單的語句 好比下面兩句功能相同,可是要記住模板裏面找數據從vm內找,有些語句放入報錯 --> <button @click="isHot = !isHot;x++">切換天氣</button> <button @click="changeWeather">切換天氣</button> <hr /> 深度監視按鈕: <h3>a的值是:{{numbers.a}}</h3> <button @click="numbers.a++">點我讓a+1</button> <h3>b的值是:{{numbers.b}}</h3> <button @click="numbers.b++">點我讓b+1</button> {{numbers.c.d.e}} </div> </body> <script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在啓動時生成生產提示。 const vm = new Vue({ el: '#root', data: { isHot: true, x: 0, numbers: { a: 1, b: 1, c: { d: { e: 100 } } } }, computed: { info() { return this.isHot ? '炎熱' : '涼爽' } }, methods: { changeWeather() { this.isHot = !this.isHot this.x++ } }, // 方法一 /* watch:{ isHot:{ immediate:true, //初始化時讓handler調用一下 //handler何時調用?當isHot發生改變時。 handler(newValue,oldValue){ console.log('isHot被修改了',newValue,oldValue) } } } //簡寫:不用immediate:true,deep: true等屬性時能夠簡寫 // isHot(newValue, oldValue) { // console.log('isHot被修改了', newValue, oldValue, this) // } */ //深度監視: //監視多級結構中某個屬性的變化,注意帶引號 /* 'numbers.a':{ handler(){ console.log('a被改變了') } } 但若是多級結構中屬性太多的話太過繁瑣 */ //監視多級結構中全部屬性的變化 numbers: { deep: true,//deep開啓深度監視,不開啓的話只監視numbers變化,不能看到numbers內的數據變化 handler() { console.log('numbers改變了') } } }) // 方法二 vm.$watch('isHot', {//注意帶引號 immediate: true, //初始化時讓handler調用一下 //handler何時調用?當isHot發生改變時。 handler(newValue, oldValue) { console.log('isHot被修改了', newValue, oldValue) } }) //簡寫 // vm.$watch('isHot', function (newValue, oldValue) { // console.log('isHot被修改了', newValue, oldValue, this) // }) </script> </html>
複製代碼
經過watch實現的姓名案例與上方計算屬性實現的姓名案例比較:java
computed和watch之間的區別:ajax
兩個重要的小原則:數組
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>姓名案例_watch實現</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準備好一個容器-->
<div id="root">
姓:<input type="text" v-model="firstName"> <br /><br />
名:<input type="text" v-model="lastName"> <br /><br />
全名:<span>{{fullName}}</span> <br /><br />
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在啓動時生成生產提示。
const vm = new Vue({
el: '#root',
data: {
firstName: '張',
lastName: '三',
fullName: '張-三'
},
watch: {
//簡寫
firstName(newValue) {
setTimeout(() => {
console.log(this)
this.fullName = newValue + '-' + this.lastName
}, 1000);
},
lastName(newValue) {
this.fullName = this.firstName + '-' + newValue
}
}
})
</script>
</html>
複製代碼
綁定樣式:緩存
寫法:class="xxx" xxx能夠是字符串、對象、數組。
字符串寫法適用於:類名不肯定,要動態獲取。
對象寫法適用於:要綁定多個樣式,個數不肯定,名字也不肯定。
數組寫法適用於:要綁定多個樣式,個數肯定,名字也肯定,但不肯定用不用。
複製代碼
:style="{fontSize: xxx}"其中xxx是動態值。
:style="[a,b]"其中a、b是樣式對象。
複製代碼
<!DOCTYPE html>
<html> <head> <meta charset="UTF-8" /> <title>綁定樣式</title> <style> .basic { width: 400px; height: 100px; border: 1px solid black; } .happy { border: 4px solid red; ; background-color: rgba(255, 255, 0, 0.644); background: linear-gradient(30deg, yellow, pink, orange, yellow); } .sad { border: 4px dashed rgb(2, 197, 2); background-color: gray; } .normal { background-color: skyblue; } .atguigu1 { background-color: yellowgreen; } .atguigu2 { font-size: 30px; text-shadow: 2px 2px 10px red; } .atguigu3 { border-radius: 20px; } </style> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準備好一個容器--> <div id="root"> <!-- 綁定class樣式--字符串寫法,適用於:樣式的類名不肯定,須要動態指定 --> <div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br /><br /> <!-- 綁定class樣式--數組寫法,適用於:要綁定的樣式個數不肯定、名字也不肯定 --> <div class="basic" :class="classArr">{{name}}</div> <br /><br /> <!-- 綁定class樣式--對象寫法,適用於:要綁定的樣式個數肯定、名字也肯定,但要動態決定用不用 --> <div class="basic" :class="classObj">{{name}}</div> <br /><br /> <!-- 綁定style樣式--對象寫法 --> <div class="basic" :style="styleObj">{{name}}</div> <br /><br /> <!-- 綁定style樣式--數組寫法 --> <div class="basic" :style="styleArr">{{name}}</div> </div> </body> <script type="text/javascript"> Vue.config.productionTip = false const vm = new Vue({ el: '#root', data: { name: '我要進大廠', mood: 'normal', classArr: ['atguigu1', 'atguigu2', 'atguigu3'], classObj: { atguigu1: true, atguigu2: false, }, styleObj: { fontSize: '40px', color: 'red', }, styleObj2: { backgroundColor: 'orange' }, styleArr: [ { fontSize: '40px', color: 'blue', }, { backgroundColor: 'gray' } ] }, methods: { changeMood() { //隨機切換心情 const arr = ['happy', 'sad', 'normal'] const index = Math.floor(Math.random() * 3) //Math.random() 返回 0 ~ 1 之間的隨機數,包含 0 不包含 1。 //Math.floor(x) 對 x 進行下舍入,即向下取整。 this.mood = arr[index] } }, }) </script> </html>
複製代碼
條件渲染:\markdown
寫法:
(1).v-if="表達式"
(2).v-else-if="表達式"
(3).v-else="表達式"
適用於:切換頻率較低的場景。
特色:不展現的DOM元素直接被移除。
複製代碼
注意:v-if能夠和:v-else-if、v-else一塊兒使用,但要求結構不能被「打斷」。\app
寫法:v-show="表達式"
適用於:切換頻率較高的場景。
特色:不展現的DOM元素未被移除,僅僅是使用樣式隱藏掉
複製代碼
3.備註:使用v-if的時,元素可能沒法獲取到,而使用v-show必定能夠獲取到。
<!DOCTYPE html>
<html> <head> <meta charset="UTF-8" /> <title>條件渲染</title> <script type="text/javascript" src="../js/vue.js"></script> </head> <body> <!-- 準備好一個容器--> <div id="root"> <h2>當前的n值是:{{n}}</h2> <button @click="n++">點我n+1</button> <!-- 使用v-show作條件渲染 元素隱藏--> <!-- <h2 v-show="false">歡迎來到{{name}}</h2> <h2 v-show="true">歡迎來到{{name}}</h2> --> <!-- <h2 v-show="1 === 1">歡迎來到{{name}}</h2> --> <!-- 使用v-if作條件渲染 元素直接被移除--> <!-- <h2 v-if="false">歡迎來到{{name}}</h2> --> <!-- <h2 v-if="1 === 1">歡迎來到{{name}}</h2> --> <!-- <h2 v-show="n === 1">你好</h2> <h2 v-show="n===2">百度</h2> <h2 v-show="n===3">北京</h2> --> <h2 v-if="n===1">你好</h2> <h2 v-if="n===1">百度</h2> <h2 v-if="n===3">北京</h2> <!-- v-else和v-else-if --> <div v-if="n === 1">Angular</div> <div v-else-if="n === 1">React</div> <div v-else-if="n === 3">Vue</div> <div v-else>哈哈</div> <!-- v-if與template的配合使用,template不能與v-show一塊兒使用 --> <!-- <template v-if="n === 1"> <h2>你好</h2> <h2>百度</h2> <h2>北京</h2> </template> --> </div> </body> <script type="text/javascript"> Vue.config.productionTip = false const vm = new Vue({ el: '#root', data: { name: '百度', n: 0 } }) </script> </html>
複製代碼
收集表單數據:
若:<input type="text"/>,則v-model收集的是value值,用戶輸入的就是value值。
若:<input type="radio"/>,則v-model收集的是value值,且要給標籤配置value值。
若:<input type="checkbox"/>
1.沒有配置input的value屬性,那麼收集的就是checked(勾選 or 未勾選,是布爾值)
2.配置input的value屬性:
(1)v-model的初始值是非數組,那麼收集的就是checked(勾選 or 未勾選,是布爾值)
(2)v-model的初始值是數組,那麼收集的的就是value組成的數組
備註:v-model的三個修飾符:
lazy:失去焦點再收集數據
number:輸入字符串轉爲有效的數字
trim:輸入首尾空格過濾
複製代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>收集表單數據</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 準備好一個容器-->
<div id="root">
<form @submit.prevent="demo">
帳號:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
密碼:<input type="password" v-model="userInfo.password"> <br/><br/>
年齡:<input type="number" v-model.number="userInfo.age"> <br/><br/>
性別:
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
愛好:
學習<input type="checkbox" v-model="userInfo.hobby" value="study">
打遊戲<input type="checkbox" v-model="userInfo.hobby" value="game">
吃飯<input type="checkbox" v-model="userInfo.hobby" value="eat">
<br/><br/>
所屬校區
<select v-model="userInfo.city">
<option value="">請選擇校區</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武漢</option>
</select>
<br/><br/>
其餘信息:
<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
<input type="checkbox" v-model="userInfo.agree">閱讀並接受<a href="http://www.atguigu.com">《用戶協議》</a>
<button>提交</button>
</form>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
userInfo:{
account:'',
password:'',
age:18,
sex:'female',
hobby:[],
city:'beijing',
other:'',
agree:''
}
},
methods: {
demo(){
console.log(JSON.stringify(this.userInfo))
}
}
})
</script>
</html>
複製代碼
過濾器:
定義:對要顯示的數據進行特定格式化後再顯示(適用於一些簡單邏輯的處理)。
語法:
1.註冊過濾器:Vue.filter(name,callback) 或 new Vue{filters:{}}
2.使用過濾器:{{ xxx | 過濾器名}} 或 v-bind:屬性 = "xxx | 過濾器名"
備註:
1.過濾器也能夠接收額外參數、多個過濾器也能夠串聯
2.並無改變本來的數據, 是產生新的對應的數據
3.不是必須的屬性,徹底能夠用methods和computed實現下面代碼中的過濾功能
4.當全局過濾器和局部過濾器重名時,會採用局部過濾器。
複製代碼
<!DOCTYPE html>
<html> <head> <meta charset="UTF-8" /> <title>過濾器</title> <script type="text/javascript" src="../js/vue.js"></script> <!-- <script type="text/javascript" src="../js/dayjs.min.js"></script> --> <script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.6/dayjs.min.js"></script> </head> <body> <!-- 準備好一個容器--> <div id="root"> <h2>顯示格式化後的時間</h2> <!-- 計算屬性實現 --> <h3>計算屬性實現:{{fmtTime}}</h3> <!-- methods實現 --> <h3>methods實現:{{getFmtTime()}}</h3> <!-- 過濾器實現 --> <h3>過濾器實現:{{time | timeFormater}}</h3> <!-- 過濾器實現(傳參) --> <h3>過濾器實現(傳參):{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3> <h3 :x="msg | mySlice">尚硅谷</h3> </div> <div id="root2"> <h2>{{msg | mySlice}}</h2> </div> </body> <script type="text/javascript"> Vue.config.productionTip = false //全局過濾器,必須在new Vue({})以前 Vue.filter('mySlice', function (value) { return value.slice(0, 4) }) new Vue({ el: '#root', data: { time: 1621561377603, //時間戳 msg: '你好,尚硅谷' }, computed: { fmtTime() { return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss') } }, methods: { getFmtTime() { return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss') } }, // filters: { // timeFormater(value) { // return dayjs(value).format('YYYY年MM月DD日 HH:mm:ss') // } // } //局部過濾器 filters: { //若是不傳參數,則使用默認參數'YYYY年MM月DD日 HH:mm:ss',若是傳參數,則使用 //傳入的參數'YYYY_MM_DD' timeFormater(value, str = 'YYYY年MM月DD日 HH:mm:ss') { // console.log('@',value) return dayjs(value).format(str) } } }) new Vue({ el: '#root2', data: { msg: 'hello,atguigu!' } }) </script> </html>
複製代碼