Vue(一)模板语法、常用指令、计算属性及监听属性


前言

目标:

  1. 理解MVVM思想
  2. vue介绍
  3. 掌握Vue指令、计算属性、数据监听
  4. 掌握Vue单向、双向绑定的方法

一、MVVM思想

什么是MVVM?MVVM是Model-View-ViewModel的缩写。
MVVM最早由微软提出来,它借鉴了桌面应用程序的MVC思想,在前端页面中,把Model用纯JavaScript
对象表示,View负责显示,两者做到了最大限度的分离。
把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还
负责把View的修改同步回Model。

二、vue.js介绍

Vue是一套用于构建用户界面的渐进式的轻量级框架
Vue是MVVM设计模式的具体实现方案
Vue只关注视图层,便于与第三方库或既有项目整合
Vue可以与现代化的工具链和各种类库结合使用,为复杂的SPA提供驱动

三、模板语法

Vue.js中使用的是基于html的模版语法,可以将Dom元素绑定至Vue实例中的数据。
页面中模版即就是通过{{}}方式来实现模版数据绑定。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<!-- <script src="https://unpkg.com/vue@next"></script> -->
		<!-- 引入vue的库文件 -->
		<script src="js/v2.6.10/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
	<!-- 显示数据的层 -->
		<div id="app">
			<h1>Vue:{{message}}</h1><!-- 文本差值表达式 模板语法 {{data的属性名}}-->
			<h2 v-text="msg">Vue</h2>
			<h3 v-html="msg"></h3>
		</div>
		<script>
		/* 实例化 vue对象new Vue() 括弧放入json对象(key、value)*/
			var app=new Vue({
				el:"#app",// 绑定一个页面已经存在的DOM元素作为vue挂载目标
				data:{ //data表示vue实例的数据对象
					message:"hello vue",
					msg:"<b>hello vue</b>"
				}
			})
		</script>
	</body>
</html>

数据绑定的方式

单向绑定
方式1:使用两对大括号{{}}
方式2:使用v-text、v-html
双向绑定:v-model指令实现
v-once 数据只绑定一次

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>单向绑定</title>
		<script type="text/javascript" src="js/v2.6.10/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<!-- 模板语法 -->
			<!-- 1、单向绑定 双大括号语法 {{data数据属性名}} 插入文本值 -->
			<p>单向绑定大号括号语法:{{message}}</p> 
			<!-- v-html指令 插入html代码 -->
			<p>使用v-html指令 插入HTML代码: <span v-html="rawHtml"></span></p> 
			<!-- v-text指令 插入文本 -->
			<p>v-text指令 插入文本: <span v-text="rawHtml"></span></p> 
			<!-- v-once指令 表示数据只绑定一次 -->
			<p v-once>v-once指令:{{message}} </p>
		</div>
	</body>
	<script type="text/javascript">
		//实例化vue对象 
		var app = new Vue({ 
			el:"#app", //把页面已经存在的dom作为vue挂载目标 
			data:{ //vue实例的数据对象
			message: "hello vue", 
			rawHtml: "<a href='http://www.baidu.com'>百度</a>"
		}
		});
	</script>
</html>

效果展示:
在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>双向绑定</title>
		<script type="text/javascript" src="js/v2.6.10/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<!-- 单行文本 --> 
			<input type="text" v-model="message" />
			<p>message:{{message}}</p> 
			<!-- 多行文本 --> 
			<textarea v-model="message"></textarea>
			<p>message:{{message}}</p> 
			<!-- 单选框 --> 
			<input type="radio" v-model="gender" value="" /><input type="radio" v-model="gender" value="" /><p>gender:{{gender}}</p> 
			<!-- 复选框 --> 
			<input type="checkbox"v-model="hobbies" value="" /><input type="checkbox" v-model="hobbies" value="" /><input type="checkbox" v-model="hobbies" value="" /><input type="checkbox" v-model="hobbies" value="" /><p>hobbies:{{hobbies}}</p> 
			<!-- 下拉菜单 --> 
			<select v-model="grade">
				<option value="本科">本科</option>
				<option value="专科">专科</option>
				<option value="高中">高中</option>
			</select>
			<p>grade:{{grade}}</p>
			<hr/>
			<!-- 在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 -->
			<!-- 你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步: --> 
			<input type="text" v-model.lazy="message"/> 
			<p>message:{{message}}</p> 
			<!-- 可以自动去除用户输入的字符首尾的空白字符,可以给v-model添加trim修饰符: -->
			<input type="text" v-model.trim="message"/> 
			<p>message:{{message}}</p> 
			<!-- 转换用户输入的值为数值类型 ,可以给v-model添加number修饰符: -->
			<input type="text" v-model.number="message"/> 
			<p>message:{{message}}</p> </div> 
	</body> 
		<script type="text/javascript"> 
			var app = new Vue({
				el:"#app", 
				data:{
					message:"初始值", 
					gender:"男", 
					hobbies:["吃"],<!-- 每次都生成新的数组重新赋值给hobbies -->
					grade:"本科", 
					age:15 } 
				}); 
		</script> 
</html>

效果展示:
在这里插入图片描述

四.常用指令

1.v-bind

使用v-bind指令进行DOM属性绑定
v-bind 用法:v-bind:属性名=“属性值”   简写 :属性名=“属性值” (:src=“” )
style和class属性用法:
style: .txt{color:#ff0000;} .bgcolor{background-color: #ccc;}
html:<span :class="{txt:true,bgcolor:true}"> 文本内容 </span>

v-bind属性数据绑定代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/v2.6.10/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<p v-bind:id="dynamicId">使用v-bind指令实现属性数据绑定</p>
			<p :id="dynamicId">使用v-bind指令的简写方式实现属性数据绑定</p>
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
			el: "#app",
			data: {
				dynamicId: "E201503"
			}
		});
	</script>
</html>

效果展示:
在这里插入图片描述
v-bind属性操作class和style的实例代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/v2.6.10/vue.js"></script>
		<style type="text/css">
			.active {
				color: #ff0000;
			}
			.bgcolor {
				background-color: #ccc;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<div :class="{active:isActive,bgcolor:isBgcolor}">绑定class</div>
			<div :style="{color:activeColor,fontSize:fontSize}">绑定内联样式</div>
			<div v-bind:style="styleObject">绑定内联样式(绑定样式对象,代码更清晰)</div>
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
			el: "#app",
			data: {
				isActive: true,
				isBgcolor: true,
				activeColor: "blue",
				fontSize: "30px",
				styleObject: {
					fontSize: "30px",
					color: "green"
				}
			}
		});
	</script>
</html>

相当于如下代码:
在这里插入图片描述

2.v-if、v-else-if、v-else

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true值的时候被渲染。
可以使用v-else-if指令来充当 v-if 的“else-if 块”,可以连续使用。
可以使用 v-else 指令来表示 v-if 的“else块”。
v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。

控制切换一个元素是否显示也相当简单。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/v2.6.10/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<div v-if="isBl">显示</div>
			<div>哈哈</div> 
			<!-- v-else必须紧跟在v-if或者v-else-if后面-,否则不显示-->
			<div v-else>不显示</div>
			<div v-if="type==='A'">A</div>
			<div v-else-if="type==='B'">B</div>
			<div v-else-if="type==='C'">C</div>
			<div v-else>非ABC</div>
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
			el: "#app",
			data: {
				isBl: false,
				type: 'B'
			}
		});
	</script>
</html>

3.v-for

基于源数据多次渲染元素或模板块,对数组或对象进行循环操作。遍历一个数组和数组对象

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>v-for</title>
		<script type="text/javascript" src="js/v2.6.10/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<!-- 1、v-for遍历一个数组 -->
			<!-- v-for 指令需要使用item in items 形式的特殊语法,其中items是元数据数组 而item 是正在被迭代的数组元素别名-->
			<ul>
				<li v-for="item in arr"> {{item}} </li>
			</ul> 
			<!-- 2、v-for支持第二个参数 index表示索引 -->
			<ul>
				<li v-for="(item,index) in arr"> 索引为:{{index}},元素值为:{{item}} </li>
			</ul> 
			<!-- 3、v-for遍历一个对象数组 -->
			<ul>
				<li v-for="item in objs"> {{item.name}} </li>
			</ul> 
			<!-- 4、v-for遍历一个对象数组 -->
			<ul>
				<li v-for="(item,index) in objs"> {{index}}--{{item.id}}--{{item.name}} </li>
			</ul>
			<table border="1px" cellspacing="0px">
				<tr>
					<td>编号</td>
					<td>用户名</td>
				</tr>
				<tr v-for="item in objs">
					<td>{{item.id}}</td>
					<td>{{item.name}}</td>
				</tr>
			</table>
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
					el: "#app",
					data: { 
						//格式:key:value 
						info:"父作用域中的属性", 
						//value是一个数组,用[]表示一个数组 
						arr:['a','b','c'], 
						//value是对象数组,[]表示数组,{}表示对象,对象中每一对属性为key和value 
						objs:[
							{id:1,name:"A"}, 
							{id:2,name:"B"}, 
							{id:3,name:"C"} ] ,
					} ,
				}); 
	</script>
</html>

效果展示:
在这里插入图片描述

4.v-on

用来绑定事件,用法:v-on:事件=“函数”,简写方式@事件=“函数”

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript" src="js/v2.6.10/vue.js" ></script>
	</head>
	<body>
		<div id="app">
			<input type="button" v-on:click="method1()" value="无参"/>
			<input type="button" v-on:click="method2('王守义')" value="有参"/>
			<input type="button" v-on:click="method4('王守义')" value="传参"/>
			<input type="button" @click="method4('王守义')" value="@"/>
		</div>
		<script type="text/javascript">
			new Vue({
				el:"#app",
				data:{
					arr:[1,2,3,4,5,6,7],
					objs:[
					{id:1,name:"张三"},
					{id:2,name:"李四"},
					{id:3,name:"王五"}
					],
					obj:{id:4,name:"赵六"},
					id:5,
					name:"王致和"
				},
				methods: {
					method1:function() {
						alert(this.name)
					},
					method2:function(str) {
						this.name=str;
						alert(this.name)
					},
					method3:function(str){
						return "Welcom"+str+"onLoad!"
					},
					method4:function(str1){
						var ss=this.method3(str1);
						alert(ss);
					}
				},
			})
		</script>
	</body>
</html>

效果展示:
在这里插入图片描述

五、计算属性

计算属性也是用来存储数据的,但具有以下几个特点:

  1. 数据可以进行逻辑处理操作
  2. 可以对计算属性中的数据进行监视

注意:

  1. 计算属性是基于它的依赖进行更新的,只有在相关依赖发生改变时才能更新。
  2. 计算属性是缓存的,只要相关依赖没有改变,多次访问计算属性得到的值是之前缓存的
  3. 计算结果,不会多次执行

get和set方法

  1. 计算属性由两部分组成:get和set,分别用来获取计算属性和设置计算属性的操作。
  2. 默认只有get方法。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/v2.6.10/vue.js"></script>
	</head>
	<body>
		<!--split('')按照字符分割,如果split参数是空字符串,那么就是所有单词分割 --> 
		<!-- reverse()把数组的元素反转(数组原地反转) --> 
		<!-- join('')把数组的元素按照传入的分隔符拼接,如果参数为空字符串,那么就是把数组元素 直接拼接 -->
		<div id="app">
			<p>{{message}}</p>
			<p>{{message.split('').reverse('').join('')}}</p>
			<p>{{reverse1}}</p>
			<input type="text" v-model.lazy="phone"/>
			<p>{{myphone}}</p> <!-- 返回myphone的计算变量 -->
			<div>如下代码是插值调用methods定义的方法</div>
			<!--插值表达式调用方法-->
			<!--注意不要丢失方法后面的小括号-->
			<p>{{reversemethod()}}</p>
			<p>{{reversemethod()}}</p>
			<div>如下代码是调用Mymessage计算属性</div>
			<!--调用myReverseMessage计算属性-->
			<p>{{Mymessage}}</p>
			<p>{{Mymessage}}</p>
			<input type="button" @click="changeMessage()" value="改变"/>
		</div>
		<script>
			new Vue({
				el:"#app",
				data:{
					message:"fighting",
					phone:""
				},
				computed: {
					//计算属性 
					//计算属性缓存:计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖 发生改变时它们才会重新求值。 
					//这就意味着 message还没有发生改变,多次访问reverseMessage,计算属性立刻 返回之前的计算结果,而不必执行函数 
					//计算属性就是一个属性,只不过属性值由计算函数得到的 
					//格式:属性名:function(){....} 
					//这个是计算属性get(计算属性只有一个函数就是默认get)
					reverse1:function() {
						// 计算完后相当于一个变量
						return this.message.split('').reverse('').join('');
					},
					myphone:function(){
						if(this.phone.length!==11)return this.phone
						var arr=this.phone.split('')
						arr.splice(3,0,'-')
						arr.splice(8,0,'-')
						return arr.join('');
					},
					Mymessage:{
						cache:false,
						get:function(){
							console.log("get");
							return this.message.split('').reverse('').join('');
						},
						set:function(msg){
							console.log("set");
							this.message=msg;
						}
					}
				},
				methods: {
					reversemethod:function() {
						// 计算完后仍是一个函数
						// console.log(this.reverse1);
						return this.message.split('').reverse('').join('');
					},
					changeMessage:function(){
						console.log("触发了changeMessage方法,设置Mymessage计算属性的值");
						this.Mymessage="word";
					}
				},
			})
		</script>
	</body>
</html>

六、监听属性

1.watch

监听属性watch它是一个对data的数据监听回调, 当依赖的data的数据变化时, 会执行回调。在回调中会传入newVal和oldVal两个参数。Vue实列将会在实例化时调用$watch(), 他会遍历watch对象的每一个属性。
watch的使用场景是:当在data中的某个数据发生变化时, 我们需要做一些操作, 或者当需要在数据变化时执行异步或开销较大的操作时. 我们就可以使用watch来进行监听。
watch分为普通监听和深度监听

普通监听:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/v2.6.10/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<p>信息:{{message}}</p> <!-- 双向绑定数据属性age -->
			<p>年龄:<input type="text" v-model="age" /></p>
		</div>
	</body>
	<script type="text/javascript">
		var app = new Vue({
					el: "#app",
					data: {
						message: "",
						age: 31,
						desc: "单身"
					},
					watch: { 
						//监听数据属性age,当age发生变化,触发如下的匿名函数,但是第一次加载页面不触 发函数 
						age:function(newVal,oldVal){ 
							this.message = '今年'+newVal+"岁,"+this.desc; 
							} ,
						} ,
					}); 
	</script>
</html>

效果展示:
在这里插入图片描述

2.理解handler方法及immediate属性

如上watch有一个特点是: 第一次初始化页面的时候, 是不会去执行age这个属性监听的, 只有当age值发生改变的时候才会执行监听计算. 因此我们上面第一次初始化页面的时候, ‘message’ 属性值默认为空字符串。那么我们现在想要第一次初始化页面的时候也希望它能够执行 ‘age’ 进行监听, 最后能把结果返回给 ‘message’ 值来。因此我们需要修改下我们的 watch的方法,需要引入handler方法和immediate属性。

3.理解deep属性

watch里面有一个属性为deep,含义是:是否深度监听某个对象的属性的值, 该值默认为false。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="js/v2.6.10/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<div>双向绑定属性age,初始化便实现监听</div>
			<p>{{message}}</p>
			<p>年龄:<input type="text" v-model="age"/></p>
			<div>双向绑定属性age,deep深度监听某个对象的属性的值, 该值默认为false</div>
			<p>{{obj.message1}}</p>
			<p>年龄:<input type="text" v-model="obj.age1"/></p>
		</div>
	</body>
	<script>
		new Vue({
			el:"#app",
			data:{
				age:20,
				message:"",
				desc:"单身",
				obj:{
					age1:30,
					message1:"",
					desc1:"已婚"
				}
			},
			watch:{
			//监听数据属性age,当age发生变化,触发如下的handler方法 
			//age监听还加入了immediate为true的属性,表示第一次页面加载的时候也会执行该 handler函数的
				age:{
					handler:function(newVal,oldVal){
						this.message="今年"+newVal+"岁"+this.desc;
					},
					immediate:true
				},
				obj:{
					handler:function(newVal,oldVal){
						this.obj.message1="今年"+newVal.age1+"岁"+this.obj.desc1;
					},
					immediate:true,
					deep:true//需要添加deep为true即可对obj进行深度监听
				}
			}
		})
	</script>
</html>

如上述代码, 如果我们不把 deep: true添加的话,当我们在输入框中输入值的时候,改变obj.age值后,obj对象中的handler函数是不会被执行到的。受JS的限制, Vue不能检测到对象属性的改变。它只能监听到obj这个对象的变化,比如说对obj变化操作会被监听到,但是对obj的内部属性的值变化监听不到。

4.watch 和 computed的区别是

相同点:他们两者都是观察页面数据变化的。
不同点:computed只有当依赖的数据变化时才会计算, 当数据没有变化时, 它会读取缓存数据。watch每次都需要执行函数。watch更适用于数据变化时的异步操作。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君知燕云归

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值