天天看點

二、Vue常用操作

Vue常用操作

Vue常用操作: https://cn.vuejs.org/v2/api/

對Vue2的掌握,我們主要從

vue基礎指令、過濾器、監聽器、計算屬性、全局元件、父子元件、元件注冊、元件之間通信、自定義事件、插槽、路由、過渡動畫、vue生命周期

開始着手。

一、Vue指令

  • 内容渲染指令

      内容渲染指令用來輔助開發者渲染DOM元素的文本内容,常用的内容渲染指令有: v-text、{{}}、v-html、v-once、v-pre、v-clock。

      v-text:向頁面注入文本,相當于innerText。v-html:向頁面注入元素,相當于innerHTML。v-once:隻渲染元素群組件一次,v-pre:用于跳過這個元素和它子元素的編譯過程,标簽内怎麼編寫頁面就展示什麼。v-clock:在某些情況下(例如網絡延遲等),我們浏覽器可能會直接顯示出未編譯的插值運算符,也就是一閃而過看到{{}}這些雙括号的模闆,我們可以采用該指令。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
		
		<style>
			[v-clock] {
				display: none;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<!-- v-tetx相當于innerText,把username 對應的值渲染到第一個p标簽中 -->
			<p v-text="username">姓名</p>
			
			<!-- {{}}插值運算把gender對應的值渲染第二個p标簽中-->
			<p>性别:{{gender}}</p>
			
			<!-- v-html相當于innerHTML,把包含HTML标簽的字元串渲染到頁面上-->
			<p v-html="hobby">愛好</p>
			
			<hr />
			<!-- v-once元素群組件隻會被渲染一次 -->
			<p v-once>原始值:{{msg}}</p>
			<p>後面值:{{msg}}</p>
			<input type="text" v-model="msg" />
			
			<!-- v-pre跳過元素和子元素的編譯過程,原始展示 -->
			<p v-pre>{{msg}}}</p>
			
			<!-- 解決因為網絡延遲導緻的插值運算值還沒有及時渲染時情況 -->
			<p v-clock>{{msg}}</p>
		</div>
		
		<script>
			const vm = new Vue({
				el:'#app',
				data:{
					username:'張三',
					gender:'男',
					hobby:'<font color="red">王者榮耀</font>',
					msg:'這是一條測試消息'
				}
			});
		</script>
	</body>
</html>           

測試結果:

二、Vue常用操作

内容渲染指令使用

  • 屬性綁定指令

   v-bind動态地綁定一個或多個特性。給一個标簽動态綁定一個屬性、樣式、一些類,或者将一個對象綁定到一個标簽上。鑒于v-bind使用較多,官方推薦使用簡寫

:屬性。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
		<style>
			.active {
				background-color: orange;
			}
			.fontActive {
				font-size: 20px;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<!-- 綁定一個屬性 ,v-bind可以簡寫-->
			<img v-bind:src="imgSrc" height="100" width="100" />
			<img :src="imgSrc" height="100" width="100"/>
			<!-- 綁定一個樣式 -->
			<p :style='{color:fontColor}'>我愛Vue</p>
			<!-- 綁定一個類 -->
			<p v-for="(course,index) in courses" :class='index==acticeIndex?"active":""'>
				{{course}}
			</p>
			<p :class=['active',{'fontActive':bool}]>多個樣式</p>
			<!-- 綁定一個有屬性的對象-->
			<p v-bind="{id:1,name:'mytext'}">綁定有屬性的對象</p>
		</div>
		
		<script>
			const vm = new Vue({
				el:'#app',
				data:{
					//綁定屬性
					imgSrc:'img/1.jpeg',
					//綁定樣式
					fontColor:'red',
					bool:true,
					//綁定class
					courses:['html','css','javascript'],
					acticeIndex:2
				}
			});
		</script>
	</body>
</html>           

測試結果:

二、Vue常用操作

v-bind指令使用

補充:vue指令中可以使用JavaScript表達式: 在 vue 提供的模闆渲染文法中,除了支援綁定簡單的資料值之外,還支援 Javascript 表達式的運算,例如
二、Vue常用操作
  • 事件綁定指令

    vue 提供了 v-on 事件綁定指令,用來輔助程式員為 DOM 元素綁定事件監聽。v-on針對事件,動态綁定事件。表示形式有v-on:事件=“事件函數”或者簡寫@事件=“事件函數”,通過v-on綁定的事件處理函數,需要在methods節點中聲明。原生DOM對象有onclikc、oninput、onkeyup等原生時間,vue相應替換分别為:v-on:click、v-on:input、v-on:keyup。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
		<style>
			.active {
				background-color: orange;
			}
			.fontActive {
				font-size: 20px;
			}
		</style>
	</head>
	<body>
		<div id="app">
 			<h3>count的值為: {{count}}</h3>
 			
 			<!-- "v-on:事件"完整寫法 -->
 			<button v-on:click="addCount">+1</button>
 			
 			<!-- "v-on:事件"簡寫形式,把v-on:簡寫為 @符号 -->
 			<!-- 如果事件處理函數中的代碼足夠簡單,隻有一行代碼,則可以簡寫到行内 -->
 			<button @click="count+=1">+1</button>
		</div>
		
		<script>
			const vm = new Vue({
				el:'#app',
				data:{
					count:0
				},
				methods:{
					addCount(){
						this.count+=1;
					}
				}
			});
		</script>
	</body>
</html>           
二、Vue常用操作

  1.綁定事件并傳參

   在使用v-on指令綁定事件時,可以使用()進行傳參,示例如下:

二、Vue常用操作

綁定事件并傳參

   2.$event

    $event是vue提供的特殊變量,用來表示原生的事件參數對象event。$event可以解決事件參數對象event被覆寫的問題,示例如 下:

二、Vue常用操作

$event使用

   3.事件修飾符

   在事件處理函數中調用 event.preventDefault() 或 event.stopPropagation() 是非常常見的需求。是以,vue 提供了事件修飾符的概念,來輔助程式員更友善的對事件的觸發進行控制。常用的 5 個事件修飾符如下:

事件修飾符 說明
.prevent 阻止預設行為(例如:阻止a連結的跳轉、阻止表單的送出等)
.stop 阻止事件冒泡
.capture 以捕獲模式觸發目前的事件處理函數
.once 綁定的事件隻能觸發一次
.self 隻有在event.target 是目前元素自身時觸發事件處理函數
二、Vue常用操作

   4.按鍵修飾符

在監聽鍵盤事件時,我們經常需要判斷詳細的按鍵。此時,可以為鍵盤相關的事件添加按鍵修飾符,例如:

二、Vue常用操作
  • 雙向綁定指令

   vue 提供了 v-model 雙向資料綁定指令,用來輔助開發者在不操作 DOM 的前提下,快速擷取表單的資料。

二、Vue常用操作

為了友善對使用者輸入的内容進行處理,vue 為 v-model 指令提供了 3 個修飾符,分别是:

示例
.number 自動将使用者的輸入值轉為數值類型 <input v-model.number="age" />
.trim 自動過濾使用者輸入的首尾空白字元 <input v-model.trim="msg" />
.lazy 在“change”時而非“input”時更新 <input v-model.lazy="msg" />
  • 條件渲染指令

   條件渲染指令用來輔助開發者按需控制 DOM 的顯示與隐藏。條件渲染指令有如下兩個,分别是:v-if(v-else-if、v-else)、v-show。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			<div v-show="score<60">差</div>
			<div v-show="score>=60&&score<90">良</div>
			<div v-show="score>=90">優秀</div>
			
			<!-- v-if、v-else-if、v-else相當于if、else if、else,隻會展示符合條件的元素,其他元素均移除 -->
			<div v-if="score<60">差</div>
			<div v-else-if="score>=60&&score<90">良</div>
			<div v-else>優秀</div>
		</div>
		
		<script>
			const vm = new Vue({
				el:'#app',
				data:{
					score:80
				}
			});
		</script>
	</body>
</html>           

v-if和v-show差別

v-if 和 v-show 的差別:

實作原理不同:

⚫ v-if 指令會動态地建立或移除 DOM 元素,進而控制元素在頁面上的顯示與隐藏;

⚫ v-show 指令會動态為元素添加或移除 style="display: none;" 樣式,進而控制元素的顯示與隐藏;

性能消耗不同:

v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。是以:

⚫ 如果需要非常頻繁地切換,則使用 v-show 較好

⚫ 如果在運作時條件很少改變,則使用 v-if 較好

  • 清單渲染指令

   v-for基于資料源多次渲染元素或者模闆塊,也可以為數組索引指定别名(或者用于建立對象的鍵)。v-for 指令還支援一個可選的第二個參數,即目前項的索引。文法格式為 (item, index) in items。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			<!--周遊數組-->
			<p v-for="(score,index) in scores">{{index +':'+score}}</p>
			
			<!-- 周遊對象數組 -->
				<table border="1" align="center" width="300">
					<thead style="background-color: orange;">
						<tr align="center">
							<td>姓名</td>
							<td>年齡</td>
							<td>性别</td>
						</tr>
					</thead>
					<tbody>
						<tr v-for="p in persons" align="center">
							<td>{{p.name}}</td>
							<td>{{p.age}}</td>
							<td>{{p.sex}}</td>
						</tr>
					</tbody>
			</table>
			<!-- 對字元串進行周遊 -->
			<p v-for ="str in hobby">
				{{str}}
			</p> 
		</div>
		
		<script>
			const vm = new Vue({
				el: '#app',
				data: {
					scores: [100, 90, 80, 70],
					persons: [
						{ name: '張三', age: 23, sex: '男' },
						{ name: '李四', age: 24, sex: '女' },
						{ name: '王五', age: 25, sex: '男' },
						{ name: '趙六', age: 26, sex: '女' },
					],
					hobby:'籃球'
				}
			});
		</script>
	</body>
</html>           
二、Vue常用操作

v-for指令使用

使用 key 維護清單的狀态

當清單的資料變化時,預設情況下,vue 會盡可能的複用已存在的 DOM 元素,進而提升渲染的性能。但這種預設的性能優化政策,會導緻有狀态的清單無法被正确更新。

為了給 vue 一個提示,以便它能跟蹤每個節點的身份,進而在保證有狀态的清單被正确更新的前提下,提升渲染的性能。此時,需要為每項提供一個唯一的 key 屬性:

二、Vue常用操作
key 的注意事項

①key 的值隻能是字元串或數字類型

②key 的值必須具有唯一性(即:key 的值不能重複)

③建議把資料項 id 屬性的值作為 key 的值(因為 id 屬性的值具有唯一性)

④使用 index 的值當作 key 的值沒有任何意義(因為 index 的值不具有唯一性)

⑤建議使用 v-for 指令時一定要指定 key 的值(既提升性能、又防止清單狀态紊亂)

二、過濾器

   過濾器(Filters)是 vue 為開發者提供的功能,常用于文本的格式化。過濾器可以用在兩個地方:插值表達式和 v-bind 屬性綁定。在建立 vue 執行個體期間,可以在 filters 節點中定義過濾 器。

   過濾器分為:私有過濾器(在filters節點下定義的過濾器,隻能在目前vm執行個體所控制的el區域内使用)和全局過濾器(全局過濾器可以在多vue執行個體之間共享過濾器)。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			<!-- 私有過濾器使用 -->
			<p>{{sex | sexFormatter}}</p>
			
			<!-- 全局過濾器使用 -->
			<p>{{str | capitalize}}</p>
			
			<!-- 連續調用多個過濾器 -->
			<p>{{message | filterA | filterB}}</p>
			
			<!-- 過濾器傳參 -->
			<p>{{message | maxLength(5)}}</p>
		</div>
		<script>
			//全局過濾器 -獨立于每個vm執行個體之外,必須定義在vm執行個體之前
			//Vue.filter()方法接受兩個參數:
			//第一個參數,是全局過濾器的"名字"
			//第二個參數,是全局過濾器的"處理函數"
			Vue.filter('capitalize',function(value){
				return value.toUpperCase().split('').reverse().join('');
			});
			
			//全局過濾器 - 控制文本的最大長度
			Vue.filter('maxLength',function(str,len = 4){
				if(str.length<=len) return str;
				return str.slice(0,len)+'...';
			});
			
			const vm = new Vue({
				el:'#app',
				data:{
					sex:0,
					str: 'abc',
					message:'chensheng'
				},
				filters:{	//局部過濾器
					sexFormatter(sex){
						if(sex==0){
							return "男";
						}else{
							return "女";
						}
					},
					filterA(value){	//将首字母大寫
						return value.charAt(0).toUpperCase()+value.slice(1);
					},
					filterB(value){	//将字元串反轉
						return value.split('').reverse().join('');
					}
				}
			});
		</script>
	</body>
</html>           
二、Vue常用操作

過濾器使用

三、監聽器

   如果我們需要監聽某個值的變化,當這個值變化是,進行一些操作,可以使用監聽器。監聽器的屬性名稱是watch,和data平級。監聽器中的資料是方法,接收兩個參數,分别為改變後的值和改變前的值。如果想讓wath偵聽器立即被調用,則需要使用immediate選項。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			firstName:<input type="text" v-model="firstName" />
			lastName:<input type="text" v-model="lastName" />
			<h2>{{fullName}}</h2>
			person:<input type="text" v-model="person.username" />
		</div>
		
		<script>
			const vm = new Vue({
				el:'#app',
				data:{
					firstName:'',
					lastName:'',
					fullName:'',
					person:{username:'admin'}
				},
				watch:{
					firstName(newVal,oldVal){
						//在vue中,操作data、method必須使用this
						this.fullName = this.firstName + this.lastName;
					},
					lastName(newVal,oldVal){
						this.fullName = this.firstName + this.lastName;
					},
					person:{             //監聽對象内屬性變化,handler是固定寫法,當username值變化時,自動調用handler處理函數
						handler(newVal){
							console.info('如果監聽對象内屬性變化,則使用這種方式'+newVal.username);
						},
					    deep: true,		 //如果watch偵聽的是一個對象,如果對象中的屬性值發生了變化,則無法被監聽到,需要使用deep選項才能偵聽
						immediate:true   //表示頁面初次渲染好之後,就立即觸發目前的watch偵聽器
					},
					'person.username':{
						handler(newVal){
							console.info('如果隻想監聽對象單個屬性變化,則使用這種方式'+newVal)
						}
					}
				}
			});
		</script>
	</body>
</html>           
二、Vue常用操作

watch監聽器使用

四、計算屬性

計算屬性指的是通過一系列運算之後,最終得到一個屬性值。這個動态計算出來的屬性值可以被模闆結構或 methods 方法使用。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			<p @click='show()'>計算屬性: {{reverseMsg}}</p>
		</div>
		
		<script>
			const vm = new Vue({
				el:'#app',
				data:{
				   msg: 'hello world'
				},
				computed: {
					//計算屬性的getter
					reverseMsg: function() {
						//this指向vm執行個體
						return this.msg.split('').reverse().join('');
					}
				},
				methods:{
					show(){
						console.info(this.reverseMsg);  //在methods中調用屬性
					}
				}
			});
		</script>
	</body>
</html>           

計算屬性使用

計算屬性和 method差別?
  •    當頁面重新渲染(不是重新整理)的時候,計算屬性不會變化,直接讀取緩存使用,适合較大量的計算和改變頻率較低的屬性;而method就是當頁面重新渲染的時候(頁面元素的data變化,頁面就會重新渲染),都會重新調用method。
  •    計算屬性是一個屬性,而不是方法。雖然寫法是方法,但是我們使用的時候是直接視為一個屬性去操作的,使用方式和data一緻。
  •    計算屬性中使用到的data中的資料隻要發生了變化,計算屬性就會重新計算。如果兩次擷取計算屬性的時候,裡面使用到的屬性沒有發生變化,計算屬性會直接使用之前緩存的值。
注意點:
  •    計算屬性。在computed中,可以定義一些屬性,這些屬性叫做計算屬性,他本質上就是一個方法,但是,我們使用的時候是當做屬性來使用。計算屬性使用的過程中,一定不要加(),它就是一個屬性,和data裡的屬性用法一樣。
  •    隻要極速暗屬性中所用到的data中的屬性發生了變化,就會立即去重新計算屬性的值。
  •    計算屬性的結果會被緩存起來,友善下次調用,如果計算屬性中用到的data都沒有變化,就不會重新求值。
  •   在計算屬性中,無論如何都需要return一個值,用來代表這個屬性的值。
計算屬性和監聽器的差別:
  • Computed用法視為一個屬性,并且結果會被緩存。
  • Methods表示方法,表示一個具體的操作,主要用來寫業務邏輯
  • Watch是一個對象,key是需要監聽的表達式,value是對應的回調函數,主要用來監聽某些資料的變化,進而執行某些具體的業務邏輯。可以看做是計算屬性和methods的結合體。

五、全局元件

元件是可複用的Vue執行個體,且帶一個名字,可以複用。我們搭建的頁面其實是一個個元件組裝而成,可以分為局部元件和全局元件。

  • 局部元件:隻屬于目前Vue的執行個體,其他執行個體無法共享這個局部元件。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			<my-date></my-date>
		</div>
		
		<script>
			//1、建立元件構造器
			let partialTemplate = Vue.extend({
				template:`
							<div>
								<input type='date'/>
								<p>今天天氣好晴朗!</p>
							</div>
						`
			});
			const vm = new Vue({
				el: '#app',
				// 注冊局部元件,隻屬于目前的vue執行個體
				components:{
					'my-date':partialTemplate
				}
			});
		</script>
	</body>
</html>

局部元件簡潔寫法:
			const vm = new Vue({
				el: '#app',
				// 注冊局部元件,隻屬于目前的vue執行個體
				components:{
					'my-date':{
						template:`
							<div>
								<input type='date'/>
								<p>今天天氣好晴朗!</p>
							</div>
							`
					}
				}
			});           
二、Vue常用操作

vue注冊局部元件

  • 全局元件:屬于所有的Vue執行個體所有。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			<my-date></my-date>
		</div>
		
		<script>
			//1. 建立元件構造器
			let ProFile = Vue.extend({
				//1.1 模闆選項
				template:`
					<div>
						<input type="date"/>
						<p>今天天氣好晴朗!</p>
					</div>
				`
			});

			//2. 注冊全局元件,參數1自定義元件名稱,參數2元件
			Vue.component('my-date',ProFile);
			
			const vm = new Vue({
				el: '#app'
			});
		</script>
	</body>
</html>           

測試結果同上!

六、父子元件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			<parent></parent>
		</div>
		<script>
			// 1. 子元件構造器
			let Child1 = Vue.extend({
				template: `<img src="img/estar.ico" width="200">`
			});

			let Child2 = Vue.extend({
				template: `<p>孤獨的星星!</p>`
			});

			// 2. 父元件構造器
			Vue.component('parent', {
				components: { 			  //注冊子元件
					'my-child1': Child1,
					'my-child2': Child2
				},
				template: `               //組裝父元件
                  <div>
                      <my-child1></my-child1>
                      <my-child2></my-child2>
                  </div>
                `
			});

			new Vue({
				el: '#app'
			});
		</script>
	</body>
</html>           
二、Vue常用操作

父子元件

  • template标簽和script标簽注冊元件
一、使用template來注冊元件【常用】
                <body>
                    <div id="app">
                        <!-- 使用父元件 -->
                        <my-div></my-div>
                    </div>
                    <template id="parent">
                        <!-- 隻能有一個出口,最外層必須有标簽包裹 -->
                        <div>
                            <img src="img/estar.ico" width="200">
                            <p>孤獨的星星!</p>
                        </div>
                    </template>
                    <script>
                        //執行個體化元件
                        Vue.component('my-div', {
                            template: '#parent'
                        });

                        new Vue({
                            el: '#app'
                        });
                    </script>
                </body>
 	二、使用script來注冊元件,必須聲明類型type=”text/template” 【不推薦使用】
                <body>
                    <div id="app">
                        <!-- 使用父元件 -->
                        <my-div></my-div>
                    </div>
                    <script type="text/template" id="parent">
                        <!-- 隻能有一個出口,最外層必須有标簽包裹 -->
                        <div>
                            <img src="img/estar.ico" width="200">
                            <p>孤獨的星星!</p>
                        </div>
                    </script>
                    <script>
                        //執行個體化元件
                        Vue.component('my-div', {
                            template: '#parent'
                        });

                        new Vue({
                            el: '#app'
                        });
                    </script>
            	</body>           
  • 元件中data使用

下述在元件中直接調用data中的資料會報錯,如下所示:

二、Vue常用操作
 為什麼元件的 data 必須是一個方法?

  首先,如果不是一個方法,Vue直接會報錯。其次,原因在于Vue讓每一個元件對象都傳回一個新的對象,如果是同一個對象的,元件會在多次使用後互相影響。如果我們不寫成方法傳回對象的話,那麼就是所有元件公用一個data。

u  我們将data定義成函數,這樣每個按鈕點選後都會産生自己獨享的變量,而不是共享的變量。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>

	<body>
		<div id="app">
			<!-- 使用元件 -->
			<my-btn></my-btn>
			<my-btn></my-btn>
			<my-btn></my-btn>
		</div>
		<template id="btn_group">
			<button @click="counter++">按鈕點選次數{{counter}}</button>
		</template>
		<script>
			//執行個體化元件
			Vue.component('my-btn', {
				template: '#btn_group',
				data() {
					return { counter: 0 }
				}
			});

			new Vue({
				el: '#app'

			});
		</script>
	</body>
  </html>           

測試結果:(描述,我們點選不同的按鈕統計的counter都是自己的)

u  如果我們将counter定義到外面來

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>

	<body>
		<div id="app">
			<!-- 使用元件 -->
			<my-btn></my-btn>
			<my-btn></my-btn>
			<my-btn></my-btn>
		</div>
		<template id="btn_group">
			<button @click="counter++">按鈕點選次數{{counter}}</button>
		</template>

		<script>
			//元件将共享一個countDate
			let countDate = { counter: 0 };
			Vue.component('my-btn', {
				template: '#btn_group',
				data() {
					return countDate;
				}
			});

			new Vue({
				el: '#app'
			});
		</script>
	</body>
 </html>           

測試結果:(描述:我們點選其中一個按鈕其他按鈕點選次數也會随之改變,共享一個counter值)

二、Vue常用操作

七、元件通信

 父子元件之間的通信,父元件通過 prop 給子元件下發資料,子元件通過$emit觸發事件給父元件發送消息,即

prop 向下傳遞,事件向上傳遞。

二、Vue常用操作
  • 父元件向子元件傳值(簡單的單層元件之間的值傳遞)

     首先在父元件中使用v-bind将數組綁定給子元件,再在子元件中,使用props收。

<body>
            <div id="app">
                <my-div :msg='孤獨的星星' imgsrc='img/estar.ico'></my-div>
            </div>
            <template id="my_div">
                <div>
                    <h1>{{msg}}</h1>
                    <img :src="imgsrc" width="100" height="100" />
                </div>
            </template>

            <script>
                //執行個體化元件
                Vue.component('my-div', {
                    template: '#my_div',
                    props:['msg','imgsrc'] //父元件通過props向子元件傳遞值
                });

                new Vue({
                    el: '#app'
                });
            </script>
        </body>
   
   或者使用綁定的方式将父元件的值傳遞給子元件:
    <body>
            <div id="app">
            	<!-- 使用綁定的方式,将父元件的資料綁定給子元件 -->
                <my-div :msg='msg' :imgsrc='imgsrc'></my-div>
            </div>
            
            <template id="my_div">
                <div>
                    <h1>{{msg}}</h1>
                    <img :src="imgsrc" width="100" height="100" />
                </div>
            </template>

            <script>
                //執行個體化元件
               const myCom =  Vue.component('my-div', {
				                    template: '#my_div',
				                    props:['msg','imgsrc'] //父元件通過props向子元件傳遞值,或者寫法如下
                                   //props: {
                                   //  msg: {
                                   //   type: String,   //type支援的類型有: String、Number、Boolean、Array、Object、Date、Function、Symbol
                                   //   default: '我是預設值,父元件沒有傳給我msg'
                                   // }
                                   // }
				                });

                new Vue({
                    el: '#app',
                    data:{
                    	msg:'孤獨的星星',
                    	imgsrc:'img/estar.ico'
                    },
                    components:{
                    	myCom
                    }
                });
            </script>
        </body>           
二、Vue常用操作

父元件向子元件傳值之單層元件傳值

  • 父元件向子元件傳值(多層元件之間的值傳遞)

二、Vue常用操作

多層元件傳值示意圖

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>

	<body>
		<div id="app">
			<!-- 使用父元件 -->
			<my-parent :imgtitle="title" :imgsrc="img"></my-parent>
		</div>
		<!-- 定義子元件 -->
		<template id="my_img">
			<img :src="imgsrc" width="200" />
		</template>
		<template id="my_title">
			<h2>{{title}}</h2>
		</template>
		<!-- 定義父元件 -->
		<template id="my_parent">
			<div>
				<child1 :imgsrc="imgsrc"></child1>
				<child2 :title="imgtitle"></child2>
			</div>
		</template>

		<script>
			//1.子元件的執行個體
			let child1 = Vue.extend({
				template: '#my_img',
				props: ['imgsrc']
			});
			let child2 = Vue.extend({
				template: '#my_title',
				props: ['title']
			});
			//2.注冊父元件
			Vue.component('my-parent', {
				props: ['imgtitle', 'imgsrc'],
				components: {
					'child1': child1,
					'child2': child2
				},
				template: '#my_parent'
			});

			new Vue({
				el: '#app',
				data: {
					title: '孤獨的星星',
					img: 'img/estar.ico'
				}
			});
		</script>
	</body>
 </html>           
二、Vue常用操作

父元件向子元件傳值之多層元件傳值

  • 父元件向子元件傳遞事件

   我們知道父元件是使用props傳遞資料給子元件,但如果子元件要把資料傳遞回去,則應該使用自定義事件來完成!

使用$on(eventName)監聽事件,使用$emit(eventName)來觸發事件,另外父元件可以在使用子元件的地方直接使用v-on來監聽子元件除法的事件。

描述: 我們在父元件中自定義一個total事件,當我們觸發這個total()事件的時候通過$emit('total')來觸發外界定義的@total="allcounter()"中
      的具體的方法allcounter()。注意在此案例中按鈕與按鈕之間是互相獨立的,互不影響。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
	</head>

	<body>
		<div id="app">
			<!—自定義事件-->
			<my-btn @total="allcounter()"></my-btn>
			<my-btn @total="allcounter()"></my-btn>
			<my-btn @total="allcounter()"></my-btn>
			<my-btn @total="allcounter()"></my-btn>
			<p>所有按鈕一共點選了{{totalCounter}}次</p>
		</div>
		<template id="my_btn">
			<button @click="total()">點選了{{counter}}次</button>
		</template>
		<script>
			Vue.component('my-btn', {
				template: '#my_btn',
				data() {
					return {
						counter: 0
					}
				},
				methods: {
					total() {
						this.counter += 1; //不同的按鈕享有不同的counter
						// 通知外界,我調用了這個方法
						this.$emit('total');
					}
				}
			});

			new Vue({
				el: '#app',
				data: {
					totalCounter: 0 //公共的資料
				},
				methods: {
					allcounter() {
						this.totalCounter += 1;
					}
				}
			});
		</script>
	</body>
 </html>           

測試結果:(描述我們低級不同的按鈕分别統計不同的按鈕點選次數,互不影響)

二、Vue常用操作
  • 父元件調用子元件方法

    $refs是和ref一起使用的。通過ref給某個子元件綁定一個特定的ID,然後我們使用$refs.ID就可以通路到子元件了。
<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title></title>
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>

	</head>

	<body>
		<div id="app">
			<button @click="countAdd">點我</button>
			<!-- 第一步,給子元件綁定一個ref -->
			<my-com ref="myComp"></my-com>
		</div>

		<template id="myTemp">
			<div>
				{{count}}
			</div>
		</template>
		<script>
			let myCom = Vue.extend({
				template: '#myTemp',
				data() {
					return {
						count: 1
					}
				},
				methods: {
					addCount() {
						this.count++
					}
				}
			})
			let app = new Vue({
				el: '#app',
				methods: {
					countAdd() {
						// 第二步,在父元件中使用this.$refs.id就行了
						console.log(this.$refs.myComp.count)
						this.$refs.myComp.addCount()
					}
				},
				components: {
					myCom
				}
			})
		</script>
	</body>
</html>           
二、Vue常用操作

八、插槽

  Slot插槽實作内容分發,結合日常生活中的電路闆,有指定插孔,我們可以插入任何電器插頭(匿名插槽),也有專門針對手機的USB插頭(實名插槽),無法插入其他電器插頭。

  • 匿名插槽
<body>
		<div id="app">
			<my-slot>
				<img src="img/estar.ico" width="200" alt="">
				<p>{{msg}}</p>
			</my-slot>
		</div>
		<template id="my_slot">
			<div>
				<header>插槽的頭部</header>
				<!--預留一個插槽,沒有則顯示該插槽内容-->
				<slot>可以替換任何标簽,預設顯示提示的内容</slot>
				<footer>插槽的尾部</footer>
			</div>
		</template>
		<script>
			Vue.component('my-slot', {
				template: '#my_slot'
			});

			new Vue({
				el: '#app',
				data: {
					msg: '孤獨的星星'
				}
			});
		</script>
	</body>           
二、Vue常用操作
  • 實名插槽
<body>
		<div id="app">
			<my-computer>
				<div slot="cpu">core-i7 6700HQ處理器</div>
				<div slot="memory">Kingston-32G記憶體條</div>
			</my-computer>
		</div>

		<template id="my_computer">
			<div>
				<slot name="cpu">預設插cpu的</slot>
				<slot name="memory">預設插記憶體條的</slot>
				<slot name="hard-drive">預設插硬碟的</slot>
			</div>
		</template>
		<script>
			Vue.component('my-computer', {
				template: '#my_computer'
			});

			new Vue({
				el: '#app'
			});
		</script>           
二、Vue常用操作

九、路由

參考部落格: https://www.jianshu.com/p/9a7d79249741  

                  https://www.jianshu.com/p/2acf9e23793a

前端路由和後端路由:

  • 後端路由:對于普通的網站,所有的超連結都是url位址,所有url都對應伺服器上對應的資源
  • 前端路由:對于單頁面應用程式來說,主要通過url的hash(#)來實作不同頁面的切換,同時hash還有一個特點HTTP請求中不會包含hash相關的内容,是以單頁面程式中的頁面跳轉主要用hash實作

    在單頁面應用程式中這種通過hash來改變頁面的方式稱作前端路由差別于後端路由

==>

由于Vue在開發時對路由支援的不足,于是官方補充了vue-router插件。vue的單頁面應用是基于路由群組件的,路由用于設定通路路徑,并将路徑群組件映射起來。
  • 引入vue-router

      <script src="lib/vue-router.js"></script>  

二、Vue常用操作

或者: <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

  • 路由入門
    建立一個路由對象,當導入vue-router包之後,在window全局對象中就有一個路由的構造函數VueRouter
在new路由對象的時候可以傳遞一個配置對象,這個配置對象的route表示路由器的比對規則
每個路由規則都是一個對象,這個規則對象身上必須有兩個屬性

屬性1 path表示監聽哪個路由連結位址

屬性2 component,表示如果路由是前面比對到的path,則展示component屬性對應的元件,component屬性值必須是一個元件模闆對象,不能是元件的引用名稱

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="lib/vue-2.6.12.js"></script>
		<script src="lib/vue-router.js"></script>
		<style>
			ul li {
				float: left;
				width: 300px;
				height: 70px;
				box-sizing: border-box;
				background-color: pink;
				list-style: none;
				line-height: 70px;
				text-align: center;
			}
			
			ul li a {
				text-decoration: none;
				font-size: 20px;
			}
			
			.content {
				clear: both;
				width: 900px;
				box-sizing: border-box;
				border: 1px solid blue;
				padding-left: 20px;
				margin-left: 40px;
			}
		</style>
	</head>
		<body>
			<div id="app">
				<!-- 使用 router-link 元件來導航. -->
				<!-- 通過傳入 `to` 屬性指定連結. -->
				<!-- <router-link> 預設會被渲染成一個 `<a>` 标簽 -->
				<ul>
					<li>
						<router-link to="/h5">HTML5學院</router-link>
					</li>
					<li>
						<router-link to="/python">Python學院</router-link>
					</li>
					<li>
						<router-link to="/java">Java學院</router-link>
					</li>
				</ul>
				<div class="content">
					<!-- 路由出口 -->
					<!-- 路由比對到的元件将渲染在這裡 -->
					<router-view></router-view>
				</div>
			</div>

			<template id="h5">
				<div>
					<h2>HTML5學院</h2>
					<p>掌握面向未來的神技!</p>
				</div>
			</template>
			<template id="python">
				<div>
					<h2>Python學院</h2>
					<p>人工智能的最佳選擇!</p>
				</div>
			</template>
			<template id="java">
				<div>
					<h2>Java學院</h2>
					<p>掌握面向工資程式設計!</p>
				</div>
			</template>
			<script>
				//1.建立元件
				const Html5 = Vue.extend({
					template: '#h5'
				});
				const Python = Vue.extend({
					template: '#python'
				});
				const Java = Vue.extend({
					template: '#java'
				});
				//2.定義路由
				const routes = [
					{ path: '/h5', component: Html5 },
					{ path: '/python', component: Python },
					{ path: '/java', component: Java },
					//配置根路由,預設顯示
					{ path: '/', redirect: '/h5' }
				];
				//3.建立路由執行個體
				const router = new VueRouter({
					routes
				});
				//4.建立Vue執行個體并挂載
				new Vue({
					router
				}).$mount('#app');
			</script>
		</body>
	</body>
</html>           

測試結果: (描述:我們點選不同的tab切換頁能實作展示不同的内容)

二、Vue常用操作

vue路由使用

補充:上述代碼存在一個弊端,就是<router-link

to="/h5">HTML5學院</router-link>路由時我們需要将路由路徑寫死在頁面上,建議采用動态綁定的方式會更好。下面采用給路由命名的方式來解決這個問題

<body>
		<div id="app">
			<!-- 使用 router-link 元件來導航. -->
			<!-- 通過傳入 `to` 屬性指定連結. -->
			<!-- <router-link> 預設會被渲染成一個 `<a>` 标簽 -->
			<ul>
				<li><router-link :to="{name:'h5'}">HTML5學院</router-link></li>
				<li><router-link :to="{name:'python'}">Python學院</router-link></li>
				<li><router-link :to="{name:'java'}">Java學院</router-link></li>
			</ul>
			<div class="content">
				<!-- 路由出口 -->
                <!-- 路由比對到的元件将渲染在這裡 -->
                <router-view></router-view>
			</div>
		</div>

		<template id="h5">
			<div>
				<h2>HTML5學院</h2>
				<p>掌握面向未來的神技!</p>
			</div>
		</template>
		<template id="python">
			<div>
				<h2>Python學院</h2>
				<p>人工智能的最佳選擇!</p>
			</div>
		</template>
		<template id="java">
			<div>
				<h2>Java學院</h2>
				<p>掌握面向工資程式設計!</p>
			</div>
		</template>
		<script>
			//1.建立元件
			const Html5 = Vue.extend({
				template: '#h5'
			});
			const Python = Vue.extend({
				template: '#python'
			});
			const Java = Vue.extend({
				template: '#java'
			});
			//2.定義路由
			const routes = [
				{ path: '/h5', component: Html5,name:'h5' },
				{ path: '/python', component: Python,name:'python' },
				{ path: '/java', component: Java ,name:'java'},
				//配置根路由,預設顯示
				{ path: '/', redirect: '/h5' }
			];
			//3.建立路由執行個體
			const router = new VueRouter({
				routes
			});
			//4.建立Vue執行個體并挂載
			new Vue({
				router
			}).$mount('#app');
		</script>
	</body>           
  • 多級子路由

    <body>
    		<div id="app">
    			<!-- 使用 router-link 元件來導航. -->
    			<!-- 通過傳入 `to` 屬性指定連結. -->
    			<!-- <router-link> 預設會被渲染成一個 `<a>` 标簽 -->
    			<ul>
    				<li><router-link to="/h5">HTML5學院</router-link></li>
    				<li><router-link to="/python">Python學院</router-link></li>
    				<li><router-link to="/java">Java學院</router-link></li>
    			</ul>
    			<div class="content">
    				<!-- 路由出口 -->
                    <!-- 路由比對到的元件将渲染在這裡 -->
                    <router-view></router-view>
    			</div>
    		</div>
    
    		<template id="h5">
    			<div>
    				<h2>HTML5學院</h2>
    				<p>掌握面向未來的神技!</p>
    			</div>
    		</template>
    		<template id="python">
    			<div>
    				<h2>Python學院</h2>
    				<p>人工智能的最佳選擇!</p>
    			</div>
    		</template>
    		<template id="java">
    			<div>
    				<h2>Java學院</h2>
    				<p>掌握面向工資程式設計!</p>
    				<!--子元件路由-->
    				<router-link  to="/java/base">基礎班</router-link>
                    <router-link  to="/java/advance">進階班</router-link>
    				<div>
    					<!-- 子元件出口 -->
                        <router-view></router-view>
                    </div>
    			</div>
    		</template>
    		<!-- 定義Java元件下的子元件 -->
    		<template id="base">
    	        <div>
    	            <h3>Java基礎班</h3>
    	            <p>快速掌握Java的三大特性!</p>
    	        </div>
    	    </template>
    
    	    <template id="advance">
    	        <div>
    	            <h3>Java進階班</h3>
    	            <p>掌握高并發高可用的架構!</p>
    	        </div>
    	    </template>
    		<script>
    			//1.建立元件
    			const Html5 = Vue.extend({
    				template: '#h5'
    			});
    			const Python = Vue.extend({
    				template: '#python'
    			});
    			const Java = Vue.extend({
    				template: '#java'
    			});		
    			//建立Java的子元件
    			const base = Vue.extend({
    				template: '#base'
    			});	
    			const advance = Vue.extend({
    				template: '#advance'
    			});	
    			
    			//2.定義路由
    			const routes = [
    				{ path: '/h5', component: Html5 },
    				{ path: '/python', component: Python },
    				{ path: '/java', component: Java,
    				children: [  //使用children屬性實作路由嵌套,子路由path前不要加/,否則永遠以根路徑開始請求
                        {path:'base', component: base},
                        {path:'advance', component: advance},
                        // 配置Java元件的根路由,預設顯示
                        {path:'/', redirect: 'base'}
                    ]
    				},
    				//配置根路由,預設顯示
    				{ path: '/', redirect: '/h5' }
    			];
    			//3.建立路由執行個體
    			const router = new VueRouter({
    				routes
    			});
    			//4.建立Vue執行個體并挂載
    			new Vue({
    				router
    			}).$mount('#app');
    		</script>
    	</body>           
二、Vue常用操作

vue多級子路由使用

  • 路由傳參
  1. 如果使用查詢字元串 給路由傳遞參數則不需要修改路由規則的path屬性,直接在元件當中使用 {$route.query.字段名}}即可擷取值。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="lib/vue-2.6.12.js"></script>
		<script src="lib/vue-router.js"></script>
	</head>
	<body>
		<div id="app">
			<!-- 路由入口 -->
			<router-link to="/login?username=zs&password=123">登入</router-link>

			<div>
				<!-- 路由出口 -->
				<router-view></router-view>
			</div>
		</div>
        
		<template id="userInfo">
			<div>
				使用者:{{$route.query.username}},密碼:{{$route.query.password}}
			</div>
		</template>
		<script>
			//1.建立元件
			const userInfo = Vue.extend({
				template: '#userInfo'
			});

			//2.定義路由
			const routes = [
				{ path: '/login', component: userInfo },
				//配置根路由,預設顯示
				{ path: '/', redirect: 'login' }
			];
			//3.建立路由執行個體
			const router = new VueRouter({
				routes
			});
			//4.建立Vue執行個體并挂載
			new Vue({
				router
			}).$mount('#app');
		</script>
	</body>
</html>           
二、Vue常用操作
2. 通過params方式傳遞路由參數,login後面會被解析為id的值
<router-link to="/login/zs">登入</router-link>

    { path: '/login/:username', component: userInfo }

    <template id="userInfo">
        <div>
            使用者:{{$route.params.username}}
        </div>
    </template>
           
二、Vue常用操作

十、過渡動畫

Vue中為我們提供了簡單的過渡動畫效果,隻需要按照vue提供的标準去寫一套固定的CSS即可。

<style>
    /* v-enter 這個是一個時間點,表示動畫進入之前,元素的起始狀态,此時還沒有進入 */
    /* v-leave-to 這是一個時間點,是動畫離開之後,元素的終止狀态,此時,元素動畫已經結束了 */
    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateX(50px);
    }
    
    /* v-enter-active 表示入場動畫的時間段 */
    /* v-leave-active 表示離場動畫的時間段 */
    .v-enter-active,
    .v-leave-active {
      transition: all 0.8s ease;
    }
  </style>

<body>
  <div id="app">
    <button @click="flag = !flag">點選</button>
    <transition>
      <div v-show="flag">這個是第一個div</div>
    </transition>
  </div>
</body>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      flag: true
    },
    methods: {
    }
  })
</script>           

此時如果我們想要讓div1消失後,div2進來,div2消失後div1進來,應該怎麼辦?隻需要寫兩套動畫即可

<transition>
      <div v-show="flag">這個是第一個div</div>
    </transition>
    <transition>
      <div v-show="!flag">這個是第二個div</div>
    </transition>           

如果div1和div2不想公用一套動畫,應該怎麼辦?這時候我們可以給transition命名,使用name屬性即可。定義了name之後,兩個transition則使用自己獨立的動畫效果。定義了name之後,動畫的相關class,要以name開頭,不能以v開頭。

<transition name="div1">
      <div v-show="flag">這個是第一個div</div>
    </transition>
    <transition name="div2">
      <div v-show="!flag">這個是第二個div</div>
    </transition>
  <style>
    /* v-enter 這個是一個時間點,表示動畫進入之前,元素的起始狀态,此時還沒有進入 */
    /* v-leave-to 這是一個時間點,是動畫離開之後,元素的終止狀态,此時,元素動畫已經結束了 */
    .div1-enter,
    .div1-leave-to {
      opacity: 0;
      transform: translateX(50px);
    }
    
    /* v-enter-active 表示入場動畫的時間段 */
    /* v-leave-active 表示離場動畫的時間段 */
    .div1-enter-active,
    .div1-leave-active {
      transition: all 0.8s ease;
    }
    /* v-enter 這個是一個時間點,表示動畫進入之前,元素的起始狀态,此時還沒有進入 */
    /* v-leave-to 這是一個時間點,是動畫離開之後,元素的終止狀态,此時,元素動畫已經結束了 */
    .div2-enter,
    .div2-leave-to {
      opacity: 0;
      transform: translateX(50px);
    }
    
    /* v-enter-active 表示入場動畫的時間段 */
    /* v-leave-active 表示離場動畫的時間段 */
    .div2-enter-active,
    .div2-leave-active {
      transition: all 0.2s ease;
    }
  </style>           

十一、生命周期

二、Vue常用操作

vue生命周期

vue生命周期示意圖

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="lib/vue-2.6.12.js"></script>
	</head>
	<body>
		<div id="app">
			<div id="divId">頁面還沒有渲染 --- {{msg}}</div>
		</div>
	</body>
	<script>
		var vue = new Vue({
			el: '#app',
			data: {
				msg: '頁面渲染完畢'
			},
			methods: {},
			filters: {},
			beforeCreate() {
				// 這是我們第一個遇到的生命周期函數,執行個體被建立出來,還沒有data、methods等時,會執行它
				let content = document.getElementById('divId')
				console.log('beforeCreate:', content.innerText)
				// 在js中,null和undefined是不同的含義。null表示有這個對象,但是這個對象的值是null。undefined表示壓根就沒有這個對象
				console.log('beforeCreate', this.msg)
			},
			created() {
				// Vue執行個體建立完畢,methods、data、filters等已經挂載到vue執行個體上。如果需要調用methods,使用data,最早隻能在這裡操作
				let content = document.getElementById('divId')
				console.log('created', content.innerText)
				console.log('created', this.msg)
			},
			beforeMount() {
				// Vue執行個體建立完畢,頁面尚未重新渲染
				let content = document.getElementById('divId')
				console.log('beforeMounte', content.innerText)
				console.log('beforeMounte', this.msg)
			},
			mounted() {
				// 頁面渲染完畢
				let content = document.getElementById('divId')
				console.log('mounted', content.innerText)
				console.log('mounted', this.msg)
			}
		})
	</script>
</html>           

十二、實戰演練

案例一: 本地模拟員工資訊的增删改查功能。  源碼:  

二、Vue常用操作
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!-- 引入layui樣式 -->
		<link rel="stylesheet" href="lib/layui/css/layui.css" />
		<!--引入vue.js-->
		<script src="lib/vue-2.6.12.js"></script>
		<!-- 引入layui.js -->
		<script src="lib/layui/layui.all.js"></script>
	</head>

	<body>
		<div id="app">
			<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
				<legend>員工管理</legend>
			</fieldset>
			<!-- 搜尋欄 -->
			<form class="layui-form">
				<div class="layui-form-item">
					<div class="layui-inline">
						<label class="layui-form-label">姓 名:</label>
						<div class="layui-input-inline">
							<input type="text" v-model="searchName" placeholder="請輸入姓名" class="layui-input">
						</div>
					</div>
					<div class="layui-inline">
						<button type="button" class="layui-btn layui-btn-normal  layui-icon layui-icon-search" @click="searchUser">查詢</button>
						<button type="reset" class="layui-btn layui-btn-warm  layui-icon layui-icon-refresh">重置</button>
						<button type="button" class="layui-btn layui-btn layui-icon layui-icon-addition" @click="saveOrUpdateDiv()">添加</button>
					</div>
				</div>
			</form>

			<!-- 資料表格 -->
			<table class="layui-table">
				<thead>
					<tr>
						<th>編号</th>
						<th>姓名</th>
						<th>年齡</th>
						<th>性别</th>
						<th>備注</th>
						<th>操作</th>
					</tr>
				</thead>
				<tbody>
					<tr v-for="item in userList" :key="item.id">
						<td>{{item.id}}</td>
						<td>{{item.name}}</td>
						<td>{{item.gender | handlerGender}}</td>
						<td>{{item.remark}}</td>
						<td>
							<button type="button" class="layui-btn layui-btn-normal" @click="saveOrUpdateDiv(item)">編輯</button>
							<button type="button" class="layui-btn layui-btn-danger" @click="delUser(item.id)">删除</button>
						</td>
					</tr>
				</tbody>
			</table>

			<!-- 添加和修改的彈出層開始 -->
			<div style="display: none;padding: 20px" id="saveOrUpdateDiv">
				<form class="layui-form">
					<div class="layui-form-item">
						<div class="layui-inline">
							<label class="layui-form-label">使用者id</label>
							<div class="layui-input-inline">
								<input type="text" v-model="user.id" placeholder="輸入使用者id" class="layui-input" readonly>
							</div>
							<label class="layui-form-label">使用者姓名</label>
							<div class="layui-input-inline">
								<input type="text" v-model="user.name" placeholder="請輸入姓名" class="layui-input">
							</div>
						</div>
					</div>
					<div class="layui-form-item">
						<div class="layui-inline">
							<label class="layui-form-label">性别</label>
							<div class="layui-input-inline">
								<input type="text" v-model="user.gender" placeholder="請輸入性别" class="layui-input">
							</div>
							<label class="layui-form-label">備注</label>
							<div class="layui-input-inline">
								<input type="text" v-model="user.remark" placeholder="請輸入備注" class="layui-input">
							</div>
						</div>
					</div>
					<div class="layui-form-item" style="text-align: center;">
						<div class="layui-input-block">
							<button type="button" class="layui-btn layui-btn-normal layui-btn-sm layui-icon layui-icon-release" v-if="!user.id" @click="addUser">新增</button>
							<button type="button" class="layui-btn layui-btn-normal layui-btn-sm layui-icon layui-icon-release" v-else @click="editUser(user)">修改</button>
							<button type="reset" class="layui-btn layui-btn-warm layui-btn-sm layui-icon layui-icon-refresh">重置</button>
						</div>
					</div>
				</form>
			</div>
			<!-- 添加和修改的彈出層結束 -->
		</div>
	</body>

	<script>
		var mainIndex;
		const vm = new Vue({
			el: '#app',
			data: {
				userList: [], //使用者清單
				data: [ //資料庫,存放使用者資料
					{ id: 1, name: '張三', gender: 1, remark: '姓張名三' },
					{ id: 2, name: '李四', gender: 2, remark: '姓李名四' },
					{ id: 3, name: '王五', gender: 1, remark: '姓王名五' },
					{ id: 4, name: '趙六', gender: 2, remark: '姓趙名六' }
				],
				user: {},
				searchName: '' //搜尋用的名稱
			},
			filters: {
				handlerGender(gender) {
					if(gender == 1) {
						return '男'
					} else {
						return '女'
					}
				}
			},
			methods: {
				saveOrUpdateDiv(user) { //打開新增或者修改的彈出層
					if(!user) {
						title = '添加使用者';
						//清空新增彈出層資料
						this.user = {};
					} else {
						title = '編輯'+user.name+'資訊';
						//回顯編輯的資料,注意不能直接 this.user = user;
						this.user = { ...user };
						//等價于this.user = {id: user.id, name: user.name,gender: user.gender,remark: user.remark}
					}
					mainIndex = layui.layer.open({
						type: 1,
						title: title,
						content: layui.jquery("#saveOrUpdateDiv"),
						area: ['700px', '250px'],
						maxmin: true
					});
				},
				getUserList(name) { //加載使用者資料
					if(!name) {
						name = '';
					}
					const dataList = this.data.filter(e => e.name.indexOf(name) >= 0);
					this.userList = dataList;
				},
				addUser() { //添加使用者
					const user = { ...this.user };
					//等價于 const user = {id: this.user.id, name: this.user.name,gender: this.user.gender,remark: this.user.remark};
					//随機生成id,範圍在1-100之間
					user.id = Math.round(Math.random() * (100 - 1) + 1)
					//添加到資料庫裡
					this.data.push(user);
					//關閉彈出層
					layui.layer.close(mainIndex);
					//重新加載資料
					this.getUserList();
				},
				delUser(id) {
					// 查到指定id所在數組索引下标
					const index = this.userList.findIndex(e => e.id === id)
					// 删除指定索引位置的資料
					this.data.splice(index, 1)
					// 删除成功後,重新家在資料
					this.getUserList()
				},
				editUser(user){ //修改使用者 
					const index = this.data.findIndex(e => e.id === user.id);
					this.data[index] = user;
					//關閉彈出層
					layui.layer.close(mainIndex);
					//重新加載資料
					this.getUserList();
				},
				searchUser() { // 搜尋使用者
					// 周遊使用者,找到所有複合條件的使用者
					this.getUserList(this.searchName)
				}
			},
			created() {
				// 進入頁面,元件建立之後,擷取資料
				this.getUserList()
			}
		})
	</script>
</html>           
二、Vue常用操作

vue+layui增删改查

案例二: 本地模拟品牌管理的增删改查功能。   源碼: 

二、Vue常用操作
<!DOCTYPE html>
<html lang="en">

	<head>
		<meta charset="UTF-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>品牌清單案例</title>
		<!-- 引入bootstrap樣式-->
		<link rel="stylesheet" href="lib/bootstrap.css">
		<style>
			body {
				padding: 15px;
				user-select: none;
			}
		</style>
	</head>
	<body>

		<div id="app">
			<!-- 卡片區域 -->
			<div class="card">
				<div class="card-header">
					添加品牌
				</div>
				<div class="card-body">
					<!-- 添加品牌的表單區域 -->
					<!-- form 表單元素有 submit 事件 -->
					<form @submit.prevent="add">
						<div class="form-row align-items-center">
							<div class="col-auto">
								<div class="input-group mb-2">
									<div class="input-group-prepend">
										<div class="input-group-text">品牌名稱</div>
									</div>
									<input type="text" class="form-control" placeholder="請輸入品牌名稱" v-model.trim="brand">
								</div>
							</div>
							<div class="col-auto">
								<button type="submit" class="btn btn-primary mb-2">添加</button>
							</div>
						</div>
					</form>
				</div>
			</div>

			<!-- 表格區域 -->
			<table class="table table-bordered table-hover table-striped">
				<thead>
					<tr>
						<th scope="col">#</th>
						<th scope="col">品牌名稱</th>
						<th scope="col">狀态</th>
						<th scope="col">建立時間</th>
						<th scope="col">操作</th>
					</tr>
				</thead>
				<tbody>
					<tr v-for="item in list" :key="item.id">
						<td>{{ item.id }}</td>
						<td>{{ item.name }}</td>
						<td>
							<div class="custom-control custom-switch">
								<!-- 使用 v-model 實作雙向資料綁定 -->
								<input type="checkbox" class="custom-control-input" :id="'cb' + item.id" v-model="item.status">
								<!-- 使用 v-if 結合 v-else 實作按需渲染 -->
								<label class="custom-control-label" :for="'cb' + item.id" v-if="item.status">已啟用</label>
								<label class="custom-control-label" :for="'cb' + item.id" v-else>已禁用</label>
							</div>
						</td>
						<td>{{ item.time | dateFormat }}</td>
						<td>
							<a href="javascript:;" @click="remove(item.id)">删除</a>
						</td>
					</tr>
				</tbody>
			</table>
		</div>

		<!-- 隻要導入了 dayjs 的庫檔案,在 window 全局,就可以使用 dayjs() 方法了 -->
		<script src="./lib/dayjs.min.js"></script>
		<script src="./lib/vue-2.6.12.js"></script>
		<script>
			// 聲明格式化時間的全局過濾器
			Vue.filter('dateFormat', function(time) {
				// 1. 對 time 進行格式化處理,得到 YYYY-MM-DD HH:mm:ss
				// 2. 把 格式化的結果,return 出去

				// 直接調用 dayjs() 得到的是目前時間
				// dayjs(給定的日期時間) 得到指定的日期
				const dtStr = dayjs(time).format('YYYY-MM-DD HH:mm:ss')
				return dtStr
			})

			const vm = new Vue({
				el: '#app',
				data: {
					// 使用者輸入的品牌名稱
					brand: '',
					// nextId 是下一個,可用的 id
					nextId: 4,
					// 品牌的清單資料
					list: [
						{ id: 1, name: '寶馬', status: true, time: new Date() },
						{ id: 2, name: '奔馳', status: false, time: new Date() },
						{ id: 3, name: '奧迪', status: true, time: new Date() },
					],
				},
				methods: {
					show(item){
						console.info(item)
					},
					// 點選連結,删除對應的品牌資訊
					remove(id) {
						this.list = this.list.filter(item => item.id !== id)
					},
					// 阻止表單的預設送出行為之後,觸發 add 方法
					add() {
						// 如果判斷到 brand 的值為空字元串,則 return 出去
						if(this.brand === '') return alert('必須填寫品牌名稱!')

						// 如果沒有被 return 出去,應該執行添加的邏輯
						// 1. 先把要添加的品牌對象,整理出來
						const obj = {
							id: this.nextId,
							name: this.brand,
							status: true,
							time: new Date()
						}
						// 2. 往 this.list 數組中 push 步驟 1 中得到的對象
						this.list.push(obj)
						// 3. 清空 this.brand;讓 this.nextId 自增 +1
						this.brand = ''
						this.nextId++
					}
				},
			})
		</script>
	</body>
</html>           

vue+bootstrap增删改查

附件清單