Vue學習筆記(二)

點擊跳轉:Vue學習筆記(一)

點擊跳轉:Vue學習筆記(三)

Vue核心(續)

2.9 計算屬性(computed)

要求實現下面的小Demo,能夠經過計算屬性獲得全名,但這樣沒法顯示計算屬性的優越性,因此我還用了插值語法與methods方法實現,但願對你的理解有幫助。 image.pngjavascript

姓名案例_插值語法實現

<!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>
複製代碼

姓名案例_methods實現

<!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>
複製代碼

2.10監視屬性(偵聽器watch)

天氣案例-監視屬性

監視屬性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實現

經過watch實現的姓名案例與上方計算屬性實現的姓名案例比較:java

computed和watch之間的區別ajax

  1. computed能完成的功能,watch均可以完成。
  2. watch能完成的功能,computed不必定能完成,例如:watch能夠進行異步操做。

兩個重要的小原則數組

  1. 所被Vue管理的函數,最好寫成普通函數,這樣this的指向纔是vm 或 組件實例對象。
  2. 全部不被Vue所管理的函數(定時器的回調函數、ajax的回調函數等、Promise的回調函數),最好寫成箭頭函數,這樣this的指向纔是vm 或 組件實例對象。
<!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>
複製代碼

2.11綁定樣式

綁定樣式:緩存

1. class樣式

寫法:class="xxx" xxx能夠是字符串、對象、數組。
	字符串寫法適用於:類名不肯定,要動態獲取。
	對象寫法適用於:要綁定多個樣式,個數不肯定,名字也不肯定。
	數組寫法適用於:要綁定多個樣式,個數肯定,名字也肯定,但不肯定用不用。
複製代碼

2. style樣式

: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>
複製代碼

2.12條件渲染

條件渲染:\markdown

1.v-if

寫法:
(1).v-if="表達式" 
(2).v-else-if="表達式"
(3).v-else="表達式"
適用於:切換頻率較低的場景。
特色:不展現的DOM元素直接被移除。
複製代碼

注意:v-if能夠和:v-else-if、v-else一塊兒使用,但要求結構不能被「打斷」。\app

2.v-show

寫法: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>
複製代碼

2.13 收集表單數據-v-model詳解

收集表單數據:
	若:<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>
複製代碼

2.14過濾器(filter)

過濾器:
	定義:對要顯示的數據進行特定格式化後再顯示(適用於一些簡單邏輯的處理)。
	語法:
		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>
複製代碼
相關文章
相關標籤/搜索