Vue.js学习笔记(基础)

本文最后更新于2024.05.30-05:09,某些文章具有时效性,若有错误或已失效,请在下方留言或联系涛哥

 前言

Vue 是一个渐进式的 JavaScript 框架,用于构建用户界面。它的核心库专注于视图层,使得 Vue 易于上手且便于与第三方库或既有项目整合。Vue 的设计允许开发者从简单的组件开始,逐步构建到复杂的前端应用程序。它采用组件化、模板语法、响应式数据绑定和虚拟 DOM 等核心概念,使得开发人员可以更轻松地构建和维护复杂的应用程序。Vue 的生态系统非常强大,拥有许多第三方库和插件,可以解决各种问题和扩展 Vue 的功能。

Vue 的优点包括:

  • 轻量级框架,只关注视图层,易于学习和使用。
  • 双向数据绑定,保留了 Angular 的特点,在数据操作方面更为简单。
  • 组件化,实现了 HTML 的封装和重用,在构建单页面应用方面有着独特的优势。
  • 视图、数据、结构分离,使得数据变得更为简单,不需要进行逻辑代码修改,只需要操作数据就可以完成相关操作。
  • 虚拟 DOM,极大解放了 DOM 操作,提高了性能。

要开始学习 Vue,首先需要掌握 HTML 和 CSS、JavaScript 基础知识,包括 ES6+ 特性。此外,熟悉前端开发工具如 VSCodeNode.js 和 Git 也很有帮助。Vue 的官方文档和在线教程是深入学习 Vue 的重要资源。

Vue.js - 渐进式 JavaScript 框架 | Vue.js

 1,hello vue

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue学习</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
		<style type="text/css">
			.box{
				width: 200px;
				height: 200px;
				background-color: aquamarine;
			}
		</style>
	</head>
	<body>
		<!-- 容器 -->
		<!-- 第一层 -->
		<div id="box">
			<h1>第一个:{{msg}}</h1>
		</div>
	</body>
	<script type="text/javascript">
		//一个Vue对象管理一个容器
		//id一般给javascript使用  class给样式使用
		//生产模式Vue:没有错误提示,代码被压缩。
		//开发者模式Vue:是有错误提示,没有被压缩的。
		
		//关掉开发环境的警告
		Vue.config.productionTip = false;
		
		/* 
			var 经常使用 没有值的时候输出 undefined
			let 块级变量方法内不受影响
			const 必须给一个初始化的值 
		*/
		
		const v = new Vue({
			el:'#box',
			data:{
				msg:'Hello Vue'
			}
		});
	</script>
</html>

2,插值语法和指令语法的基本使用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>插值语法和指令语法</title>
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1>插值语法</h1>
			<h3>你好:{{name}}</h3>
			<h1>指令语法</h1>
			<a v-bind:href="webUrl">{{webName}}</a>
			<a href="#" v-bind:del="del">删除</a>
			<a href="" :chage="chage">修改</a>
			<!-- 
			指令语法的两种写法:
			v-bind:属性="data的key"
			:属性="data的key" 
			-->
			
			<h3>ID:{{user.id}} 姓名:{{user.name}} 性别:{{user.sex}}</h3>
		</div>
		<!-- 
		为什么Script的标签会放在body结束标签之前?
		一、避免堵塞
		二、HTML2.0起放在</body>下是不符合标准的
		-->	
		<script type="text/javascript">
			//关掉开发环境的警告
			Vue.config.productionTip = false;
			
			const v = new Vue({
				el:'#box',
				data:{
					name:'张三',
					webName:'百度',
					webUrl:"http://www.baidu.com",
					del:"101",
					chage:"101",
					user:{
						id:1,
						name:'张三',
						sex:'男'
					}
				}
			});
			
		</script>
	</body>
</html>

 3, 数据绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>数据绑定</title>
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1>单项数据绑定</h1>
			用户名:<input type="text" name="name" v-bind:value="name"/><br>
			<h1>双向数据绑定</h1>
			用户名:<input type="text" name="name" v-model:value="name"/><br>
			<!-- 注意:v-model 只能用在表单元素上 -->
			<!-- 
			单项绑定:
				v-bind 或 :
			双向绑定
				v-model:value 或 v-model 
			-->
			
			<!-- 以下是这两个的简写方式 -->
			<h1>单项数据绑定</h1>
			用户名:<input type="text" name="name" :value="name"/><br>
			<h1>双向数据绑定</h1>
			用户名:<input type="text" name="name" v-model="name"/><br>
		</div>
		
		
		
		<script type="text/javascript">
			/* 
			const v = new Vue({
				data:{
					name:'张三'
				}
			}); 
			*/
		   
		   //目前两种都可以,学到组件过后只能用这种
		   const v = new Vue({
				data:function(){
					return{
						name:'张三'
					}
				}
		   });
			
			//ES6函数写法
			setTimeout(() => {
				//手动挂载
				v.$mount("#box");
			},3000);
			
			/* setTimeout(function(){
				
			},3000); */
		</script>
	</body>
</html>

4,MVVM

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>MVVM</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1>你好{{name}}</h1>
		</div>
		
		<script type="text/javascript">
			Vue.config.productionTip = false;
			
			const vm = new Vue({
				el:'#box',
				data:{
					name:'张三'
				}
			})
			console.log(vm);
		</script>
	</body>
</html>

5,数据代理

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue - 数据代理</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			Vue.config.productionTip = false;
			
			let user = {
				age:18,
				name:'张三'
			}
			
			let rSex = "男";
			
			//不可修改
			Object.defineProperty(user,'sex',{
				//value:'男',  不能和set get同时使用
				//writable:true, //设置值是否可修改  默认false  不能和set get 同时使用
				configurable:true,//设置属性是否可删除 默认false
				enumerable:true,//设置属性是否可枚举 默认false
				get:()=>{
					//console.log("有人在读值");
					return rSex;
				},
				set:(value)=>{
					rSex = value;
				}
			})
			
			//循环枚举
			for(let key in user){
				console.log(user[key]);
			}
			
			setTimeout(()=>{
				rSex = "女";
			},3000);
			console.log(user);
		</script>
	</body>
</html>

 6,插值语法高级

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue插值语法2</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1>你好{{name}}</h1>
			<h1>{{1+1}}</h1>
			<h1>{{1==1}}</h1>
			<h1>{{$options}}</h1>
			<!-- 
				插值语法: 
					可以进行算术运算,可以进行判断,插值语法实际上找的就是vm,vm里面有什么这里就可以放什么。
			-->
		</div>
		
		<script>
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					name:'张三'
				}
			})
			
			console.log(vm);
		</script>
	</body>
</html>

7,点击事件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>vue的点击事件</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
		<style>
			.myul{
				width: 300px;
				height: 90px;
				overflow-y: auto;
			}
			.myul > li{
				width: 100%;
				height: 20px;
			}
			.myul > li:nth-child(odd){
				background-color: coral;
			}
		</style>
	</head>
	<body>
		<div id="box">
			<h1 v-on:click="msg">你点我试试</h1>
			<button type="button" @click="deleteUser(1001,$event)">删除</button><br>
			<a href="http://www.baidu.com" @click.prevent="baiduMsg">阻止默认行为</a><br><br><br><br>
			<div @click="msg2" style="width: 300px;height: 200px;background-color: aquamarine;">
				<button type="button" @click.stop="msg1">阻止事件冒泡</button>
			</div><br>
			<button type="button" @click.once="delete2">删除2(只执行一次)</button>
			
			<ul class="myul" @scroll="mywhell">
				<li>1</li>
				<li>2</li>
				<li>3</li>
				<li>4</li>
				<li>5</li>
				<li>6</li>
				<li>7</li>
			</ul>
			
		</div>
		<script>
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				methods:{
					msg(){
						alert("试试就试试");
					},
					deleteUser(uid,event){
						alert("删除成功"+1001);
						console.log(event);
					},
					baiduMsg(){
						alert("点击了百度");
					},
					msg1(){
						alert("消息1触发");
					},
					msg2(){
						alert("消息2触发");
					},
					delete2(){
						alert("我被删除了");
					},
					mywhell(){
						console.log("正在滚动");
					}
					
				}
			})
		</script>
	</body>
</html>

 8,键盘事件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>键盘事件</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<input type="text" placeholder="请输入用户名" @keydown="userName"/><br>
			<!-- 自定义别名 -->
			<input type="text" placeholder="自定义别名" @keydown.caps-lock="capsLock"><br>
			<!-- 组合按键 -->
			<input type="text" placeholder="组合按键" @keydown.ctrl.s="save">
		</div>
		<script>
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				methods:{
					userName(e){
						console.log(e.key,e.keyCode);
					},
					capsLock(){
						console.log("你打开了大小写");
					},
					save(){
						console.log("保存成功");
					}
					
				}
			})
		</script>
	</body>
</html>

 9,小练习

a,插值语法实现

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>插值语法实现</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			姓名:<input type="text" v-model="name"><br>
			公司:<input type="text" v-model="company"><br>
			<h2>{{name}}@{{company}}.com</h2>
		</div>
		
		<script type="text/javascript">
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					name:'',
					company:''
				}
			})
		</script>
	</body>
</html>

b,方法实现

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>通过方法实现</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			姓名:<input type="text" v-model="name"><br>
			公司:<input type="text" v-model="company"><br>
			<h2>{{email()}}</h2>
			<h2>{{email()}}</h2>
			<h2>{{email()}}</h2>
		</div>
		
		<script type="text/javascript">
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					name:'',
					company:''
				},
				methods:{
					email(){
						console.log("执行");
						return this.name + "@" + this.company + ".com";
					}
				}
			})
		</script>
	</body>
</html>

10,计算属性

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>计算属性</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			姓名:<input type="text" v-model="name"><br>
			公司:<input type="text" v-model="company"><br>
			<h2>{{email}}</h2>
			<h2>{{email}}</h2>
			<h2>{{email}}</h2>
		</div>
		<script>
			/* 
			计算属性:
				多处调用只会执行一次,用方法会执行多次,使用计算属性可以提高代码运行效率。
				和methods相比最大的好处是计算属性有缓存
			*/
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					name:'',
					company:''
				},
				computed:{
					email:{
						//当有人使用email这个属性时调用
						get(){
							console.log("执行")
							return this.name + "@" + this.company + ".com";
						}
					}
				}
			})
		</script>
	</body>
</html>

 

11,计算属性的简写

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>计算属性的简写</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			姓名:<input type="text" v-model="name"><br>
			公司:<input type="text" v-model="company"><br>
			<h2>{{email}}</h2>
			<h2>{{email}}</h2>
			<h2>{{email}}</h2>
		</div>
		<script>
			/* 
			计算属性:
				多处调用只会执行一次,用方法会执行多次,使用计算属性可以提高代码运行效率。
				和methods相比最大的好处是计算属性有缓存
			*/
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					name:'',
					company:''
				},
				computed:{
					email:function(){
							console.log("执行")
							return this.name + "@" + this.company + ".com";
					}
				}
			})
		</script>
	</body>
	
</html>

12,天气案例-监视属性

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>监视属性</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<!-- 不推荐 -->
			<!-- <h1>今天的天气是{{isHot ? '炎热' : '凉爽'}}</h1> -->
			<!-- 计算属性实现 -->
			<h1>今天的天气是{{weather}}</h1>
			<button type="button" @click="change">切换天气</button>
			<button type="button" @click="isHot = !isHot">切换天气简洁版</button>
		</div>
		
		<script>

			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					isHot:true
				},
				computed:{//计算属性
					weather(){//属性名称
						return this.isHot ? '炎热' : '凉爽';//返回值
					}
				},
				methods:{
					change(){
						/* if(this.isHot){
							this.isHot = false;
						}else{
							this.isHot = true;
						} */
						this.isHot = !this.isHot;
					}
				}
				/* ,watch:{//监视属性
					isHot:{//被监视的属性
						handler(nv,ov){//nv 新值  ov 改之前的值
							console.log("isHot被修改了");
							console.log(nv,ov);
						},
						immediate:true//初始化就立即执行一次
					}
				} */
			})
			
			
			//	第二种监视属性打开方法
			setTimeout(() =>{//5秒后开始监视
				vm.$watch('isHot',{
					handler(nv,ov){//nv 新值  ov 改之前的值
						console.log("isHot被修改了");
						console.log(nv,ov);
					}
				})
			},5000);
			
			
			
		</script>
	</body>
</html>

13,深度监视

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>深度监视</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1>{{number.a}}</h1>
			<button type="button" @click="number.a++">number增加</button>
		</div>
		<script>
		
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					number:{
						a:1,
						b:5
					}
				}
				,watch:{//监视属性
					/* 'number.a':{//被监视的属性
						handler(nv,ov){//nv 新值  ov 改之前的值
							console.log("number被修改了");
							console.log(nv,ov);
						}
					}, */
					number:{
						deep:true,//深度监视的开启,监视多级属性中所有的属性发生变化 
						//缺点:只能获取属性值改变之后的值,获取不了改变之前的值
						handler(nv,ov){//nv 新值  ov 改之前的值
							console.log("number被修改了");
							console.log(nv,ov);
						}
					}
				}
			})

			
		</script>
	</body>
</html>

14,样式绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>样式绑定</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
		<style type="text/css">
			.ball{
				width: 200px;
				height: 200px;
				background-color: aquamarine;
			}
			.ballRadius{
				border-radius: 50%;
			}
			.ballAlign{/* 文本左右居中 */
				text-align: center;
				font-size: 35px;
			}
			.ballLine{/* 文本上下居中 */
				line-height: 200px;
				color: azure;
				
			}
		</style>
	</head>
	<body>
		<div id="box">
			<!-- 样式绑定第一种方式 :class 单个属性 -->
			<div class="ball" :class="ballRadius">
				{{ball}}
			</div>
			<!-- 样式绑定第二种方式 :class 数组-->
			<div class="ball"  :class="ballStyle">
				{{ball}}
			</div>
			<!-- 样式绑定第三种方式 :class 对象 true 和 false 控制样式的加载和移除 -->
			<div class="ball"  :class="ballObj" @click="ballObj.ballRadius = !ballObj.ballRadius">
				{{ball}}
			</div>
			<!-- 样式绑定第四种方式 :style -->
			<div class="ball" :class="ballObj" :style="ballColor">
				{{ball}}
			</div>
		</div>
		<script>
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					ball:'这是一个球',
					ballRadius:'ball-radius',//单样式
					ballStyle:['ballRadius','ballAlign','ballLine'],//多样式
					ballObj:{
						ballRadius:true,
						ballAlign:true,
						ballLine:true
					},
					ballColor:{
						color: 'green',
						'font-size': '20px'
					}
				}
			})
		</script>
	</body>
</html>

15,条件渲染

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>条件渲染</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<!-- v-show 做条件渲染 -->
			<div v-show="false">第一个{{ball}}</div>
			<div v-show="1===1">第二个{{ball}}</div>
			<!-- v-if 做条件渲染 -->
			<!-- v-if移除代码 v-show隐藏代码 -->
			<div v-if="false">第三个{{ball}}</div>
			<!-- 练习一 v-show 完成-->
			<h1 v-show="number === 1">Angualr</h1>
			<h1 v-show="number === 2">React</h1>
			<h1 v-show="number === 3">Vue</h1>
			<button type="button" @click="number++">切换</button>
			<!-- 练习二 if 完成-->
			<h1 v-if="number === 1">Angualr</h1>
			<h1 v-else-if="number === 2">React</h1>
			<h1 v-else-if="number === 3">Vue</h1>
			<h1 v-else>都不会</h1>
			<button type="button" @click="number++">切换</button>
			<!-- 
			注意:
				变化频率大使用show频率小使用if if会不停在Dom中进行增删 
			-->
			<!-- template 模板的意思,本身是不显示的,只会在渲染时起作用 -->
			<!-- template 只能配合v-if使用 -->
			<template v-if="number === 4">
				<h1>Angualr</h1>
				<h1>React</h1>
				<h1>Vue</h1>
			</template>
			
		</div>
		
		<script>
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					ball:'球',
					number:1
				}
			})
		</script>
		
	</body>
</html>

16,列表渲染

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>列表渲染</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<ul>
				<li v-for="u in userList">
					id:{{u.id}}  姓名:{{u.name}} 年龄:{{u.age}}
				</li>
			</ul>
			<!-- 显示序号 -->
			<ul>
				<li v-for="(u,index) in userList">
					序号:{{index+1}}  姓名:{{u.name}} 年龄:{{u.age}}
				</li>
			</ul>
		</div>
		<script>
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					userList:[
						{id:'1001',name:'张三',age:18},
						{id:'1002',name:'李四',age:28},
						{id:'1003',name:'王五',age:38}
					]
				}
			})
		</script>
	</body>
</html>

17,key的原理

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>key的原理</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<ul>
				<li v-for="u in userList" :key="u.id">
					姓名:{{u.name}} 年龄:{{u.age}}
					<input type="text" />
				</li>
			</ul>
			<button type="button" @click="addUser">添加数据</button>
		</div>
		<script>
			//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
			//key一般使用数据的id
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					userList:[
						{id:'1001',name:'张三',age:18},
						{id:'1002',name:'李四',age:28},
						{id:'1003',name:'王五',age:38}
					]
				},
				methods:{
					addUser(){
						var u = {id:'1004',name:'赵六',age:48};
						//添加数据(前面追加)
						//this.userList.unshift(u);
						//添加数据(后面追加)
						this.userList.push(u);
					}
				}
			})
		</script>
	</body>
</html>

18,音乐搜索案例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>音乐搜索案例</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			搜索: <input type="text" v-model="searchValue">
			<ul>
				<li v-for="m in searchList" :key="m.id">
					<div style='width:200px;float: left;'>
						音乐:{{m.name}}
					</div>
					<div style='width:200px;float: left;'>
						歌手:{{m.sname}}
					</div>
					
				</li>
			</ul>
		</div>
		<script>
			//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
			//key一般使用数据的id
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					searchValue:'',//用户搜索
					musicList:[],//数据
					searchList:[]//搜索结果
				}
			})
			
			vm.musicList = [
				{id:'1', name:'想唱就唱',sname:'张含韶'}
				,{id:'2', name:'冰点与沸点',sname:'张含韶'}
				,{id:'3', name:'夕阳无限好',sname:'陈奕迅'}
				,{id:'4', name:'爱的证明',sname:'沈建祥'}
				,{id:'5', name:'刻下纹身之后' ,sname:'小鸣'}
				,{id:'6', name:'双面人' ,sname:'伍佰'}
				,{id:'7', name:'长情' ,sname:'黎明'}
				,{id:'8', name:'我得你' ,sname:'张学友'}
				,{id:'9', name:'人人望放假' ,sname:'张学友'}
				,{id:'10', name:'太平洋的风' ,sname:'胡德夫'}
				,{id:'11', name:'吻下留人' ,sname:'许志安'}
				,{id:'12', name:'顺时针' ,sname:'梁咏琪'}
				,{id:'13', name:'回来我的爱' ,sname:'阳一'}
				,{id:'14', name:'两只蝴蝶' ,sname:'庞龙'}
				,{id:'15', name:'老鼠爱大米' ,sname:'杨臣刚'}
				,{id:'16', name:'丁香花' ,sname:'唐磊'}
				,{id:'17', name:'爱你' ,sname:'冷草莓'}
				,{id:'18', name:'美梦成真' ,sname:'冷草莓'}
				,{id:'19', name:'老鼠爱大米' ,sname:'huanggm2'}
				,{id:'20', name:'谢谢你的爱1999' ,sname:'cznana'}
				,{id:'21', name:'老鼠爱大米' ,sname:'英文版'}
				,{id:'22', name:'猪之歌' ,sname:'香香'}
				,{id:'23', name:'“吻别”英文版' ,sname:'Michael..'}
				,{id:'24', name:'别说我的眼泪你无..' ,sname:'东来东往'}
				,{id:'25', name:'追杀邱比特' ,sname:'蔡依林'}
				,{id:'26', name:'被风吹过的夏天' ,sname:'金莎'}
				,{id:'27', name:'你到底爱谁' ,sname:'刘嘉亮'}
				,{id:'28', name:'六月的雨' ,sname:'胡歌'}
				,{id:'29', name:'酸酸甜甜就是我' ,sname:'张含韵'}
				,{id:'30', name:'你好,周杰伦' ,sname:'安又淇'}
				,{id:'31', name:'江南' ,sname:'林俊杰'}
				,{id:'32', name:'情人' ,sname:'刀郎'}
				,{id:'33', name:'两只蝴蝶' ,sname:'庞龙'}
				,{id:'34', name:'2002年的第一场雪' ,sname:'刀郎'}
				,{id:'35', name:'看我七十二变' ,sname:'蔡依林'}
				,{id:'36', name:'恭喜发财' ,sname:'刘德华'}
				,{id:'37', name:'童话' ,sname:'光良'}
				,{id:'38', name:'寓言' ,sname:'张韶涵'}
				,{id:'39', name:'宁夏' ,sname:'梁静茹'}
				,{id:'40', name:'断点' ,sname:'张敬轩'}
				,{id:'41', name:'快乐崇拜' ,sname:'潘玮柏'}
				,{id:'42', name:'一首简单的歌' ,sname:'王力宏'}
				,{id:'43', name:'孤单北半球' ,sname:'欧得洋'}
				,{id:'44', name:'十年' ,sname:'陈奕迅'}
				,{id:'45', name:'男人海洋' ,sname:'周传雄'}
				,{id:'46', name:'挥着翅膀的女孩' ,sname:'容祖儿'}
				,{id:'47', name:'我们的爱' ,sname:'F.I.R'}
				,{id:'48', name:'第一次爱的人' ,sname:'王心凌'}
			];
			//监视属性
			vm.$watch('searchValue',function(nv){
				//console.log("用户搜索"+nv);
				//filter会把数据进行循环,如果为false则会移除数据,为true保留数据,最终返回一个集合。
				this.searchList = this.musicList.filter((p) => {//ES6
					if(p.name.indexOf(nv) !== -1){//包含
						return true;
					}else{
						return false;
					}
				});
			},{
				//初始化执行一次
				immediate:true,
			});
		</script>
	</body>
</html>

 19,音乐播放案例(带排序)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>音乐搜索案例</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			搜索: <input type="text" v-model="searchValue">
			<button @click="sortType = !sortType">排序</button>
			<ul>
				<li v-for="m in searchList" :key="m.id">
					<div style='width:300px;float: left;'>
						ID :{{m.id}}音乐:{{m.name}}
					</div>
					<div style='width:300px;float: left;'>
						歌手:{{m.sname}}
					</div>
					
				</li>
			</ul>
		</div>
		<script>
			//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
			//key一般使用数据的id
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					searchValue:'',//用户搜索
					musicList:[],//数据
					searchList:[],//搜索结果
					sortType:true//true代表升序false代表降序
				}
			})
			
			vm.musicList = [
				{id:'1', name:'想唱就唱',sname:'张含韶'}
				,{id:'2', name:'冰点与沸点',sname:'张含韶'}
				,{id:'3', name:'夕阳无限好',sname:'陈奕迅'}
				,{id:'4', name:'爱的证明',sname:'沈建祥'}
				,{id:'5', name:'刻下纹身之后' ,sname:'小鸣'}
				,{id:'6', name:'双面人' ,sname:'伍佰'}
				,{id:'7', name:'长情' ,sname:'黎明'}
				,{id:'8', name:'我得你' ,sname:'张学友'}
				,{id:'9', name:'人人望放假' ,sname:'张学友'}
				,{id:'10', name:'太平洋的风' ,sname:'胡德夫'}
				,{id:'11', name:'吻下留人' ,sname:'许志安'}
				,{id:'12', name:'顺时针' ,sname:'梁咏琪'}
				,{id:'13', name:'回来我的爱' ,sname:'阳一'}
				,{id:'14', name:'两只蝴蝶' ,sname:'庞龙'}
				,{id:'15', name:'老鼠爱大米' ,sname:'杨臣刚'}
				,{id:'16', name:'丁香花' ,sname:'唐磊'}
				,{id:'17', name:'爱你' ,sname:'冷草莓'}
				,{id:'18', name:'美梦成真' ,sname:'冷草莓'}
				,{id:'19', name:'老鼠爱大米' ,sname:'huanggm2'}
				,{id:'20', name:'谢谢你的爱1999' ,sname:'cznana'}
				,{id:'21', name:'老鼠爱大米' ,sname:'英文版'}
				,{id:'22', name:'猪之歌' ,sname:'香香'}
				,{id:'23', name:'“吻别”英文版' ,sname:'Michael..'}
				,{id:'24', name:'别说我的眼泪你无..' ,sname:'东来东往'}
				,{id:'25', name:'追杀邱比特' ,sname:'蔡依林'}
				,{id:'26', name:'被风吹过的夏天' ,sname:'金莎'}
				,{id:'27', name:'你到底爱谁' ,sname:'刘嘉亮'}
				,{id:'28', name:'六月的雨' ,sname:'胡歌'}
				,{id:'29', name:'酸酸甜甜就是我' ,sname:'张含韵'}
				,{id:'30', name:'你好,周杰伦' ,sname:'安又淇'}
				,{id:'31', name:'江南' ,sname:'林俊杰'}
				,{id:'32', name:'情人' ,sname:'刀郎'}
				,{id:'33', name:'两只蝴蝶' ,sname:'庞龙'}
				,{id:'34', name:'2002年的第一场雪' ,sname:'刀郎'}
				,{id:'35', name:'看我七十二变' ,sname:'蔡依林'}
				,{id:'36', name:'恭喜发财' ,sname:'刘德华'}
				,{id:'37', name:'童话' ,sname:'光良'}
				,{id:'38', name:'寓言' ,sname:'张韶涵'}
				,{id:'39', name:'宁夏' ,sname:'梁静茹'}
				,{id:'40', name:'断点' ,sname:'张敬轩'}
				,{id:'41', name:'快乐崇拜' ,sname:'潘玮柏'}
				,{id:'42', name:'一首简单的歌' ,sname:'王力宏'}
				,{id:'43', name:'孤单北半球' ,sname:'欧得洋'}
				,{id:'44', name:'十年' ,sname:'陈奕迅'}
				,{id:'45', name:'男人海洋' ,sname:'周传雄'}
				,{id:'46', name:'挥着翅膀的女孩' ,sname:'容祖儿'}
				,{id:'47', name:'我们的爱' ,sname:'F.I.R'}
				,{id:'48', name:'第一次爱的人' ,sname:'王心凌'}
			];
			//监视属性
			vm.$watch('searchValue',function(nv){
				//console.log("用户搜索"+nv);
				//filter会把数据进行循环,如果为false则会移除数据,为true保留数据,最终返回一个集合。
				const arr = this.musicList.filter((p) => {//ES6
					if(p.name.indexOf(nv) !== -1 || p.sname.indexOf(nv) !== -1){//包含
						return true;
					}else{
						return false;
					}
				});
				
				//排序
				//sort如果返回p1-p2升序 如果返回p2-p1就是降序
				arr.sort((p1,p2) => {
					if(this.sortType){//升序
						return p1.id-p2.id;
					}else{//降序
						return p2.id-p1.id;
					}
				});
				
				//赋值
				this.searchList = arr;
			},{
				//初始化执行一次
				immediate:true,
			});
		</script>
	</body>
</html>

20,音乐播放案例(计算属性实现)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>音乐搜索案例(计算属性)</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			搜索: <input type="text" v-model="searchValue">
			<button @click="sortType = !sortType">排序</button>
			<ul>
				<li v-for="m in searchList" :key="m.id">
					<div style='width:300px;float: left;'>
						ID :{{m.id}}音乐:{{m.name}}
					</div>
					<div style='width:300px;float: left;'>
						歌手:{{m.sname}}
					</div>
					
				</li>
			</ul>
		</div>
		<script>
			//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
			//key一般使用数据的id
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					searchValue:'',//用户搜索
					musicList:[],//数据
					sortType:true//true代表升序false代表降序
				},
				computed:{//计算属性
					searchList(){
						//console.log("用户搜索"+nv);
						//filter会把数据进行循环,如果为false则会移除数据,为true保留数据,最终返回一个集合。
						const arr = this.musicList.filter((p) => {//ES6
							if(p.name.indexOf(this.searchValue) !== -1 || p.sname.indexOf(this.searchValue) !== -1){//包含
								return true;
							}else{
								return false;
							}
						});
						
						//排序
						//sort如果返回p1-p2升序 如果返回p2-p1就是降序
						arr.sort((p1,p2) => {
							if(this.sortType){//升序
								return p1.id-p2.id;
							}else{//降序
								return p2.id-p1.id;
							}
						});
						
						//赋值
						return arr;
					}
				}
			})
			
			vm.musicList = [
				{id:'1', name:'想唱就唱',sname:'张含韶'}
				,{id:'2', name:'冰点与沸点',sname:'张含韶'}
				,{id:'3', name:'夕阳无限好',sname:'陈奕迅'}
				,{id:'4', name:'爱的证明',sname:'沈建祥'}
				,{id:'5', name:'刻下纹身之后' ,sname:'小鸣'}
				,{id:'6', name:'双面人' ,sname:'伍佰'}
				,{id:'7', name:'长情' ,sname:'黎明'}
				,{id:'8', name:'我得你' ,sname:'张学友'}
				,{id:'9', name:'人人望放假' ,sname:'张学友'}
				,{id:'10', name:'太平洋的风' ,sname:'胡德夫'}
				,{id:'11', name:'吻下留人' ,sname:'许志安'}
				,{id:'12', name:'顺时针' ,sname:'梁咏琪'}
				,{id:'13', name:'回来我的爱' ,sname:'阳一'}
				,{id:'14', name:'两只蝴蝶' ,sname:'庞龙'}
				,{id:'15', name:'老鼠爱大米' ,sname:'杨臣刚'}
				,{id:'16', name:'丁香花' ,sname:'唐磊'}
				,{id:'17', name:'爱你' ,sname:'冷草莓'}
				,{id:'18', name:'美梦成真' ,sname:'冷草莓'}
				,{id:'19', name:'老鼠爱大米' ,sname:'huanggm2'}
				,{id:'20', name:'谢谢你的爱1999' ,sname:'cznana'}
				,{id:'21', name:'老鼠爱大米' ,sname:'英文版'}
				,{id:'22', name:'猪之歌' ,sname:'香香'}
				,{id:'23', name:'“吻别”英文版' ,sname:'Michael..'}
				,{id:'24', name:'别说我的眼泪你无..' ,sname:'东来东往'}
				,{id:'25', name:'追杀邱比特' ,sname:'蔡依林'}
				,{id:'26', name:'被风吹过的夏天' ,sname:'金莎'}
				,{id:'27', name:'你到底爱谁' ,sname:'刘嘉亮'}
				,{id:'28', name:'六月的雨' ,sname:'胡歌'}
				,{id:'29', name:'酸酸甜甜就是我' ,sname:'张含韵'}
				,{id:'30', name:'你好,周杰伦' ,sname:'安又淇'}
				,{id:'31', name:'江南' ,sname:'林俊杰'}
				,{id:'32', name:'情人' ,sname:'刀郎'}
				,{id:'33', name:'两只蝴蝶' ,sname:'庞龙'}
				,{id:'34', name:'2002年的第一场雪' ,sname:'刀郎'}
				,{id:'35', name:'看我七十二变' ,sname:'蔡依林'}
				,{id:'36', name:'恭喜发财' ,sname:'刘德华'}
				,{id:'37', name:'童话' ,sname:'光良'}
				,{id:'38', name:'寓言' ,sname:'张韶涵'}
				,{id:'39', name:'宁夏' ,sname:'梁静茹'}
				,{id:'40', name:'断点' ,sname:'张敬轩'}
				,{id:'41', name:'快乐崇拜' ,sname:'潘玮柏'}
				,{id:'42', name:'一首简单的歌' ,sname:'王力宏'}
				,{id:'43', name:'孤单北半球' ,sname:'欧得洋'}
				,{id:'44', name:'十年' ,sname:'陈奕迅'}
				,{id:'45', name:'男人海洋' ,sname:'周传雄'}
				,{id:'46', name:'挥着翅膀的女孩' ,sname:'容祖儿'}
				,{id:'47', name:'我们的爱' ,sname:'F.I.R'}
				,{id:'48', name:'第一次爱的人' ,sname:'王心凌'}
			];

		</script>
	</body>
</html>

21.html标签

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>html标签</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<p>{{text}}</p>
			<p v-html="text"></p>
		</div>
		<script>
			/* 百度富文本编辑器  http://fex.baidu.com/ueditor/*/
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					text:"<b>这里显示一些内容</b>"
				}
			})

		</script>
	</body>
</html>

22,Set方法的使用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>set方法的使用</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1>{{user.age}}岁</h1>
			<!-- v-if 不会显示标签 -->
			<!-- v-show 会加上 display:none -->
			<h1 v-if="user.sex">{{user.sex}}性</h1>
			<button type="button" @click="user.age++">增加年龄</button>
			<button @click="addSex">添加性别为男性</button>
		</div>
		<script>
			//在做列表渲染的时候一定要加上:key 否者数据发生改变时,样式会错位。
			//key一般使用数据的id
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					user:{
						age:1
					}
				},
				methods:{
					addSex(){
						//vm.sex = "男";
						/* 追加的对象  对象名  值 */
						Vue.set(vm.user,'sex','男');
						//vue不允许动态添加根级别的响应式数据
						//Vue.set(vm,'money',100);
					}
				}
			})
			console.log(vm);

		</script>
	</body>
</html>

23,性能优化

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>性能优化</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<p>{{text}}</p>
			<p v-html="text"></p>
			<!-- v-pre跳过编译 -->
			<div v-pre v-show="false">
				<h1>{{text}}</h1>
				<h1>{{text}}</h1>
				<h1>{{text}}</h1>
			</div>
			{{text}}
			{{text}}
			{{text}}
		</div>
		<script>
			/* 百度富文本编辑器  http://fex.baidu.com/ueditor/*/
			Vue.config.productionTip = false;
			const vm = new Vue({
				el:'#box',
				data:{
					text:"<b>这里显示一些内容</b>"
				}
			})

		</script>
	</body>
</html>

24,自定义指令 - 全局

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>自定义指令</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1 v-my-title="title"></h1>
			<h2 v-my-title>这个也想居中</h2>
		</div>
		<script>
			/* 百度富文本编辑器  http://fex.baidu.com/ueditor/*/
			Vue.config.productionTip = false;
			//全局自定义指令
			Vue.directive('my-title',function(el, binding){
				//文字颜色
				el.style.color = "red";
				//文本居中
				el.style.textAlign = "center";
				if(binding.value.length > 0){//如果有内容才添加内容
					//内容
					//el.innerText = "新华社:"+binding.value;
					//添加内容
					el.innerHTML = "新华社:"+binding.value + "<hr>";
				}
			});
			
			const vm = new Vue({
				el:'#box',
				data:{
					title:"《人民的名义》总监制李学政:王立科曾想让该剧停播"
				}
			})
	
		</script>
	</body>
</html

25,自定义指令 - 局部

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>局部 - 自定义指令</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1 v-my-title="title"></h1>
		</div>
		<script>
			Vue.config.productionTip = false;
			
			const vm = new Vue({
				el:'#box',
				data:{
					title:"国庆节快乐"
				},
				directives:{//directives不要忘记加s
					'my-title':{
						bind(el, binding){
							//让文字从右往左显示
							//split("") 字符串转数组
							//reverse() 数组倒叙排序
							//join("") 数组转字符串
							el.innerHTML = binding.value.split("").reverse().join("");
						}
					}
				}
			})
	
		</script>
	</body>
</html>

26,Vue的生命周期(一)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue的生命周期(一)</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1 :style="{opacity}">渐变效果</h1>
			{{change()}}
		</div>
		<script>
			Vue.config.productionTip = false;
			
			const vm = new Vue({
				el:'#box',
				data:{
					opacity:1
				},
				methods:{
					change(){
						console.log("我执行了");
						setInterval(() =>{
							this.opacity -= 0.1;
							if(this.opacity <= 0){
								this.opacity = 1;
							}
						},1000);
					}
				}
				
			})
			
			
		</script>
	</body>
</html>

27,Vue的生命周期(二)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue的生命周期(二)</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<h1 :style="{opacity}">渐变效果</h1>
		</div>
		<script>
			Vue.config.productionTip = false;
			
			const vm = new Vue({
				el:'#box',
				data:{
					opacity:1
				},
				methods:{
					
				},
				mounted(){//页面上所有的DOM元素渲染完成之后调用
					console.log("我执行了");
					setInterval(() =>{
						/* this.opacity -= 0.1;
						if(this.opacity <= 0){
							this.opacity = 1;
						} */
						this.opacity <= 0 ? this.opacity=1 : this.opacity -= 0.1;
					},100);
				}
				
			})
			
		</script>
	</body>
</html>

28,组件的基本使用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>组件的基本使用</title>
		<!-- 开发环境版本,包含了有帮助的命令行警告 -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	</head>
	<body>
		<div id="box">
			<ntitle></ntitle>
			<ntitle></ntitle>
			<ntitle></ntitle>
			<ntitle></ntitle>
		</div>
		<script>
			Vue.config.productionTip = false;
			
			//通过组件的形式调用,创建标题
			//1、创建组件
			const ntitle = Vue.extend({
				template:`
					<div>
						<h1>{{title}}</h1>
						<h3>编辑:{{name}}</h3>
					</div>
				`,
				data(){
					return {
						title:'科学家研究表明,不吃饭会饿。',
						name:'张三'
					}
				}
			})
			
			const vm = new Vue({
				el:'#box',
				components:{//组件的注册
					ntitle
				}
			})
	
		</script>
	</body>
</html>
阅读剩余
THE END