点击跳转:Vue学习(二)
点击跳转:Vue学习(三)
点击跳转:Vue学习(四)
点击跳转:Vue学习(五)
点击跳转:Vue学习(六)
点击跳转:Vue学习(七)
点击跳转:Vue学习(八)
文章预览:
1、Vue简介
1.1、Vue是什么
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
1.2、谁开发的
1.3、Vue特点
- 采用组件化模式,提高代码复用率,且让代码更好维护
- 声明式编码,让编码人员无需直接操作DOM,提高开发效率
- 使用虚拟DOM+优秀的Diff算法,尽量复用DOM节点
1.4、搭建Vue开发环境
可以打开官网链接去查看安装步骤:Vue官网地址
直接用script引入
- CDN
完整版(包含完整的警告和调试模式):
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
压缩版(删除了警告):
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
- 最好使用下载Vue Devtools
2、Vue核心
2.1、初始Vue
- 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
- root容器里的代码依然符合HTML规范,只不过混入了一些特殊的Vue语法
- root容器里的代码被称为Vue模板
- 真实开发中只有一个Vue实例,并且会配合着组件一起使用;
- {xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性
- 例如:{{name.toUpperCase()}} 大写,{{1+1}}输出值为二,{{Date.now()}}获取时间戳
- 一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
注意区分:js表达式 和 js代码(语句)
1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
(1). a
(2). a+b
(3). demo(1)
(4). x === y ? 'a' : 'b'
2.js代码(语句)
(1). if(){}
(2). for(){}
- Vue实例和模板是一一对应的关系,以下两段代码中,均无法正常解析渲染
<div class="root">
<h1>hello,{{name}}</h1>
</div>
<div class="root">
<h1>hello,{{name}}</h1>
</div>
<script>
new Vue({
el: '.root',
data: {
name:'cez'
},
methods: {}
});
</script>
<div id="root">
<h1>hello,{{name}},{{address}}</h1>
</div>
<script>
new Vue({
el: '#root',
data: {
name:'cez'
},
methods: {}
})
new Vue({
el: '#root',
data: {
address:'山东'
},
methods: {}
});
</script>
完全版代码:
<!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.toUpperCase()}},{{address}},{{1+1}},{{Date.now()}}</h1>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
//创建Vue实例
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。\
// el:document.getElementById('root'),也可以这么写,但不推荐
data: { //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name: 'zgc',
address: '北京'
}
})
</script>
</body>
</html>
2.2、模板语法
Vue模板语法有两大类:
- 插值语法:
- 功能:用于解析标签体内容
- 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性
- 指令语法:
- 功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…)
- 举例:
v-bind:href="xxx"
或 简写为:href="xxx"
,xxx同样要写js表达式,且可以直接读取data中的所有属性,Vue中有很多的指令,且形式都是:v-???,此处只是拿v-bind举例子
<!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">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<hr />
<h1>指令语法</h1>
<a v-bind:href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1</a>
<a :href="school.url" v-bind:x="hello">点我去{{school.name}}学习2</a>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el: '#root',
data: {
name: 'zgc',
school: {
name: '清华',
url: 'http://www.atguigu.com',
},
hello: '你好'
}
})
</script>
</html>
2.3、数据绑定
Vue有两种数据绑定的方式:
- 单向绑定(
v-bind
):数据只能从data流向页面。 - 双向绑定(
v-model
):数据不仅能从data流向页面,还可以从页面流向data。
备注:
- 双向绑定一般都应用在表单类元素上(如:input、select等)
v-model:value
可以简写为v-model
,因为v-model默认收集的就是value值。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>数据绑定</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<!-- 普通写法 -->
<!--
单向数据绑定:<input type="text" v-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只能应用在表单类元素(输入类元素)上,即有value值的元素,因为其默认与value绑定 -->
<!-- <h2 v-model:x="name">你好啊</h2> -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el: '#root',
data: {
name: '尚硅谷'
}
})
</script>
</html>
2.4、el与data的两种写法:
data与el的2种写法
1.el有2种写法
(1).new Vue时候配置el属性。
(2).先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。
2.data有2种写法
(1).对象式
(2).函数式
如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
3.一个重要的原则:
由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。
Vue管理的函数举例:data(),method方法中定义的函数等,this会变成Window
1、el
el 属性又称挂载点,可认为是 element 的简写,创建一个 vue实例 得知道是在哪一块元素上创建 Vue实例 ,对哪一块视图进行操作。
1. 设置 el 属性
<div id="app"></div>
new Vue({
el: "#app",
render: h => h(App)
})
2. 使用 $mount 接口
new Vue({
render: h => h(App)
}).$mount("#app");
const vm = new Vue({
render: h => h(App)
})
vm.$mount("#app");
2、data
data 属性又称内部数据,该属性值可以是对象,也可以是函数,但优先推荐使用函数,对象里的函数又称方法。并且若是组件中的 data 则必须使用函数。
优先推荐使用函数的原因是在使用同一个 options 对象作为参数创建多个 Vue实例 时,若 data 属性值为对象,在使用 new Vue(options) 创建 Vue实例 时会将 options.data 属性值直接赋值给 Vue实例.data的属性 ,由于对象的赋值是复制的地址,因此多个实例的 data 属性值都是指向同一个对象的地址,则多个实例会共用一个 data对象,当一个实例改变 data对象 时,另一个实例的 data对象 也会被改变。
而当 data 属性值为函数时,Vue 创建实例时是会执行该 data() 函数,并将函数执行的结果返回的对象赋值给 Vue实例.data 属性,每次函数执行返回的对象都是不同的对象,因此多个实例的 data 属性值对应的是不同的对象,一个改变不会影响另外一个,各自独立不影响。
1. 使用对象
data:{ n: 0 }
2. 使用函数
//data:function(){ return{ n: 0 } }简写
data(){ //声明data函数时this指向Vue实例,千万不要用箭头函数,其this指向window
return{ n: 0 }
}
2.5、MVVM
MVVM:Model-View-ViewModel 是一种软件架构模式
- M:Model 对应data中的数据
- V: 视图(View) 模板
- VM:视图模式(ViewModel) Vue实例对象
data中所有的属性,最后都出现在了vm身上
vm身上所有的属性,及Vue原型上所有属性,在Vue模板中都可以直接使用 如{{$options}} {{$emit}}
均有结果出现。
-
Data Bindings ---数据绑定
-
DOM Listeners ---页面监听
2.6、Object.defineProperty()
1、对象的定义与赋值
经常使用的定义与赋值方法obj.prop =value
或者obj['prop']=value
2、Object.defineProperty()语法说明
Object.defineProperty()
的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
Object.defineProperty(obj, prop, desc)
- obj 需要定义属性的当前对象
- prop 当前需要定义的属性名
- desc 属性描述符
一般通过为对象的属性赋值的情况下,对象的属性可以修改也可以删除,但是通过Object.defineProperty()定义属性,通过描述符的设置可以进行更精准的控制对象属性。
3、属性的特性以及内部属性
javacript 有三种类型的属性
-
命名数据属性:拥有一个确定的值的属性。这也是最常见的属性
-
命名访问器属性:通过
getter
和setter
进行读取和赋值的属性 -
内部属性:由JavaScript引擎内部使用的属性,不能通过JavaScript代码直接访问到,不过可以通过一些方法间接的读取和设置。比如,每个对象
都有一个内部属性
[[Prototype]]
,你不能直接访问这个属性,但可以通过Object.getPrototypeOf()
方法间接的读取到它的值。虽然内部属性通常用一个双中括号包围的名称来表示,但实际上这并不是它们的名字,它们是一种抽象操作,是不可见的,根本没有上面两种属性有的那种字符串类型的属性
4、属性描述符
通过Object.defineProperty()
为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符,存取描述符,下面分别描述下两者的区别:
5、数据描述符
特有的两个属性(value,writable)
let Person = {}
Object.defineProperty(Person, 'name', {
value: 'jack',
writable: true // 是否可以改变
})
注意,如果描述符中的某些属性被省略,会使用以下默认规则:
6、存取描述符
是由一对 getter、setter 函数功能来描述的属性
get
:一个给属性提供getter
的方法,如果没有getter
则为undefined
。该方法返回值被用作属性值。默认为undefined
。
set
:一个给属性提供setter
的方法,如果没有setter
则为undefined
。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认值为
undefined
。
let Person = {}
let temp = null
Object.defineProperty(Person, 'name', {
get: function () {
return temp
},
set: function (val) {
temp = val
}
})
7、存取器描述
使用存取器描述属性的特性的时候,允许设置以下特性属性:
var obj = {};
Object.defineProperty(obj,"newKey",{
get:function (){} | undefined,
set:function (value){} | undefined
configurable: true | false
enumerable: true | false
});
注意:当使用了getter或setter方法,不允许使用writable和value这两个属性
getter / setter
当设置或获取对象的某个属性的值的时候,可以提供getter/setter方法。
- getter 是一种获得属性值的方法
- setter是一种设置属性值的方法。
在特性中使用get/set属性来定义对应的方法。
var obj = {};
var initValue = 'hello';
Object.defineProperty(obj,"newKey",{
get:function (){
//当获取值的时候触发的函数
return initValue;
},
set:function (value){
//当设置值的时候触发的函数,设置的新值通过参数value拿到
initValue = value;
}
});
//获取值
console.log(obj.newKey); //hello
//设置值
obj.newKey = 'change value';
console.log(obj.newKey); //change value
注意:get或set不是必须成对出现,任写其一就可以。如果不设置方法,则get和set的默认值为undefined
8、数据描述符和存取描述均具有以下描述符
configrable
描述属性是否配置,以及可否删除enumerable
描述属性是否会出现在for in 或者 Object.keys()的遍历中
configrable 代码片段分析
configurable:false不能删除属性
configurable:false不能重新定义属性
等价上一张图的代码
与上一张图的代码进行对比
configurable:true
能删除属性
configurable:true
能够定义属性
configurable:false
与上图做对照
从以上代码运行结果分析总结可知:
configurable: false
时,不能删除当前属性,且不能重新配置当前属性的描述符(有一个小小的意外:可以把writable的状态由true改为false,但是无法由false改为true),但是在writable: true的情况下,可以改变value的值
configurable: true
时,可以删除当前属性,可以配置当前属性所有描述符。
9、enumerable 代码片段分析
注意:以下二种区别
10、不变性
1、 对象常量
结合 `writable: false` 和 `configurable: false` 就可以创建一个真正的常量属性(不可修改,不可重新定义或者删除)
2、禁止扩展
如果你想禁止一个对象添加新属性并且保留已有属性,就可以使用 `Object.preventExtensions(...)`
禁止扩展片段1
禁止扩展片段2
在非严格模式下,创建属性gender会静默失败,在严格模式下,将会抛出异常。
3、密封
`Object.seal()` 会创建一个密封的对象,这个方法实际上会在一个现有对象上调用 `object.preventExtensions(...)`并把所有现有属性标记为configurable:false。
所以, 密封之后不仅不能添加新属性,也不能重新配置或者删除任何现有属性(虽然可以改属性的值)
4、冻结
`Object.freeze()`会创建一个冻结对象,这个方法实际上会在一个现有对象上调用 `Object.seal()`,并把所有现有属性标记为 `writable: false`,这样就无法修改它们的值。
这个方法是你可以应用在对象上级别最高的不可变性,它会禁止对于对象本身及其任意直接属性的修改(但是这个对象引用的其他对象是不受影响的)
你可以深度冻结一个对象,具体方法为,首先这个对象上调用Object.freeze()
然后遍历它引用的所有对象,并在这些对象上调用Object.freeze()。但是一定要小心,因为这么做有可能会无意中冻结其他共享对象。
11、Vue相关
Vue数据劫持与数据代理,计算属性等都用到了这个方法,必须理解它
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>回顾Object.defineproperty方法</title>
</head>
<body>
<script type="text/javascript">
let number = 18
let person = {
name: '张三',
sex: '男',
}
//Object.defineProperty给对象添加属性
Object.defineProperty(person, 'age', {
//里面三个参数(对象,属性名,options配置对象{})
// value: 18,
// enumerable: true, //控制属性是否可以枚举(遍历),默认值是false
// writable:true, //控制属性是否可以被修改,默认值是false
// configurable:true //控制属性是否可以被删除,默认值是false
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get() {
console.log('有人读取age属性了')
return number
},
//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value) {
console.log('有人修改了age属性,且值是', value)
number = value
}
})
// console.log(Object.keys(person))
console.log(person)
</script>
</body>
</html>
2.7、 数据代理
何为数据代理
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>何为数据代理</title>
</head>
<body>
<!-- 数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)-->
<script type="text/javascript" >
let obj = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj.x
},
set(value){
obj.x = value
}
})
</script>
</body>
</html>
可以通过obj2对象操作obj对象中的属性
2.8、Vue数据代理
1.Vue中的数据代理:
通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:
更加方便的操作data中的数据,如果没有数据代理,data中所有属性就不能直接调用,前面应该加上 _data.
调用
3.基本原理:
通过`Object.defineProperty()`把data对象中所有属性代理到vm上
为每一个添加到vm上的属性,都指定一个getter/setter
在getter/setter内部去操作(读/写)data中对应的属性
<!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="root">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<!-- 如果没有数据代理,代码要这么写,寻找_data中的name属性与address属性,太过繁琐,
因为vm上没有这两个属性,通过数据代理将这两个属性放在vm身上一份
<h2>学校名称:{{_data.name}}</h2>
<h2>学校地址:{{_data.address}}</h2> -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el: '#root',
data: {
name: '尚硅谷',
address: '宏福科技园'
}
})
</script>
</html>
2.9、事件处理
1、事件的基本使用
事件的基本使用:
1.使用v-on:xxx
或 @xxx
绑定事件,其中xxx是事件名;
2.事件的回调需要配置在methods
对象中,最终会在vm上;
3.methods中配置的函数,不要用箭头函数!否则this就不是vm,而是Window;
4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
5.@click="demo"
和 @click="demo($event)"
效果一致,但后者可以传参;
2、事件修饰符
Vue中的事件修饰符:
-
prevent
:阻止默认事件(常用) -
stop
:阻止事件冒泡(常用) -
once
:事件只触发一次(常用) -
capture
:使用事件的捕获模式 -
self
:只有event.target是当前操作的元素时才触发事件 -
passive
:事件的默认行为立即执行,无需等待事件回调执行完毕;
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>事件修饰符</title>
<!-- 引入Vue -->
<script type="text/javascript" src="../js/vue.js"></script>
<style>
* {
margin-top: 20px;
}
.demo1 {
height: 50px;
background-color: skyblue;
}
.box1 {
padding: 5px;
background-color: skyblue;
}
.box2 {
padding: 5px;
background-color: orange;
}
.list {
width: 200px;
height: 200px;
background-color: peru;
overflow: auto;
}
li {
height: 100px;
}
</style>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>欢迎来到{{name}}学习</h2>
<!-- 阻止默认事件(常用) -->
<a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息</a>
<!-- 阻止事件冒泡(常用) -->
<div class="demo1" @click="showInfo">
<button @click.stop="showInfo">点我提示信息</button>
<!-- 在哪一层加了阻止事件冒泡,哪一层外面的所有祖先冒泡都会被阻止 -->
<!-- 修饰符可以连续写 -->
<!-- <a href="http://www.atguigu.com" @click.prevent.stop="showInfo">点我提示信息</a> -->
</div>
<!-- 事件只触发一次(常用) -->
<button @click.once="showInfo">点我提示信息</button>
<!-- 使用事件的捕获模式 -->
<div class="box1" @click.capture="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 只有event.target是当前操作的元素时才触发事件; -->
<div class="demo1" @click.self="showInfo">
<button @click="showInfo">点我提示信息</button>
</div>
<!-- 事件的默认行为立即执行,无需等待事件回调执行完毕; -->
<ul @wheel.passive="demo" class="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<!-- @wheel滚轮滚动事件 @scroll滚动条滚动事件 -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el: '#root',
data: {
name: '尚硅谷'
},
methods: {
showInfo(e) {
// e.stopPropagation()//阻止冒泡
// e.preventDefault()//阻止默认事件
//可以不用上面两种方法而改用事件修饰符
alert('同学你好!')
console.log(e.target)
},
showMsg(msg) {
console.log(msg)
},
demo() {
for (let i = 0; i < 100000; i++) {
console.log('#')
}
console.log('累坏了')
}
}
})
</script>
</html>
3、键盘事件
1.Vue中常用的按键别名:
- 回车 => enter
- 删除 => delete (捕获“删除”和“退格”键)
- 退出 => esc
- 空格 => space
- 换行 => tab (特殊,必须配合keydown去使用)
- 上 => up
- 下 => down
- 左 => left
- 右 => right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
3.系统修饰键(用法特殊):tab、ctrl、alt、shift、meta
(1).配合keyup
使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown
使用:正常触发事件
4.也可以使用keyCode去指定具体的按键(不推荐)
<input type="text" placeholder="按下回车提示输入" @keydown.13="showInfo">
5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
<!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>欢迎来到{{name}}学习</h2>
<input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo">
<!-- <input type="text" placeholder="按下回车提示输入" @keydown.enter="showInfo"> -->
<!--当有需求要同时按下两个键才能生效时
<input type="text" placeholder="按下回车提示输入" @keyup.ctrl.y="showInfo"> -->
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
Vue.config.keyCodes.huiche = 13 //定义了一个别名按键
new Vue({
el: '#root',
data: {
name: '尚硅谷'
},
methods: {
showInfo(e) {
// console.log(e.key,e.keyCode)
// if (e.keyCode !== 13) return 如果不是回车键,则弹出函数
console.log(e.target.value)
}
},
})
</script>
</html>
4、exact 修饰符
.exact
修饰符允许你控制由精确的系统修饰符组合触发的事件。
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>
5、鼠标按钮修饰符
这些修饰符会限制处理函数仅响应特定的鼠标按钮
.left
.right
.middle
<!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>欢迎来到{{name}}学习</h2>
<!-- <button v-on:click="showInfo">点我提示信息</button> -->
<button v-on:click="showInfo1">点我提示信息1(不传参)</button>
<button @click.right="showInfo1">右键点我提示信息1(不传参)</button>
<button @click="showInfo2($event,66)">点我提示信息2(传参)</button>
<!-- 有且只有 ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="showInfo1">A</button>
<!-- shift 即使 与(Alt 或 ctrl) 被一同按下时也会触发,即只要有shift就会触发 -->
<button v-on:click.shift="showInfo1">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="showInfo1">A</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el:'#root',
data:{
name:'尚硅谷',
},
methods:{
showInfo1(event){
//不传参默认收到event事件对象
// console.log(event.target.innerText)
// console.log(this) //此处的this是vm,可以用this拿到 _data(data)中的数据
alert('同学你好!')
},
showInfo2(event,number){
console.log(event,number)
// console.log(event.target.innerText)
// console.log(this) //此处的this是vm
alert('同学你好!!')
}
}
})
</script>
</html>