- 2.1 v-on可以监听多个方法吗?
- v-on 绑定单个或多个事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" :value="name" @input="onInput" @focus="onFocus" @blur="onBlur" />
<input v-on:keyup.enter="submit" v-on:focus="onFocus">
<!-- <button v-on:click="myclick('hello','world','你好世界',$event)" >button1</button> -->
<button @click="myclick('hello','world','你好世界',$event)">点我text</button>
<!-- v-on绑定多个事件教程里这样子写,但是貌似已经不支持这样子的写法了,
内联方式下事件处理器只能绑定一个方法,要是想要绑定多个事件,用下面第二行的方式-->
<!-- <button v-on="{mouseenter: onEnter,mouseleave: onLeave}">鼠标进来</button> -->
<button @mouseenter="onEnter" @mouseleave="onLeave">鼠标进来</button>
<!-- 一个事件绑定多个函数,按顺序执行,这里分隔函数可以用逗号也可以用分号-->
<button @click="a(),b()">点我ab</button>
<button @click="one()">点我onetwothree</button>
<!-- v-on修饰符 .stop .prevent .capture .self 以及指定按键.{keyCode|keyAlias} -->
<!-- 这里的.stop 和 .prevent也可以通过传入&event进行操作 -->
<!-- 全部按键别名有:enter tab delete esc space up down left right -->
<form @keyup.delete="onKeyup" @submit.prevent="onSubmit">
<input type="text" placeholder="在这里按delete">
<button type="submit">点我提交</button>
</form>
</div>
<script src="vue221.js"></script>
<script>
var vm = new Vue({
el:"#app",
methods:{
//这里是es6对象里函数写法
a(){console.log("a");},
b(){console.log("b");},
one(){
console.log("one");
this.two();
this.three();
},
two(){
console.log("two");
},
three(){
console.log("three");
},
myclick(msg1,msg2,msg3,event){
console.log(msg1+msg2+"--"+msg3);
console.log(event);
},
onKeyup(){
console.log("you press 'delete'");
},
onSubmit(){
console.log("sumited");
},
onEnter(){
console.log("mouse enter");
},
onLeave(){
console.log("mouse leave");
}
}
});
</script>
</body>
</html>
- 2.2 vue中 key 值的作用
数组的v-for
item in items
item of items
item,index in items
(item,index) in items
对象的v-for(键值,键名,索引)
value in object
(value, key) in object
(value, key, index) in object
key的作用主要是为了高效的更新虚拟DOM。
另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,
其目的也是为了让vue可以区分它们,
否则vue只会替换其内部属性而不会触发过渡效果。
key的用法一般是:key='id',意思是为元素绑定一个key属性,这个key属性为元素添加了一个唯一身份标识符。
之后,当数据改变,Vue底层通过对比能够更快的获取到更新的内容并显示到页面上。
总之就是一句话,key属性能够提升性能(主要作用于数据更新时)。
- 2.3 vue-cli工程升级vue版本
package.json 里面修改vue的版本 同时修改 vue-template-compiler 为相同的版本.后者在devdepen....里面.然后npm install;
在项目目录里运行 npm upgrade vue vue-template-compiler,不出意外的话,可以正常运行和 build。如果有任何问题,删除 node_modules 文件夹然后重新运行 npm i 即可。
- 2.4 基于Vue cli生成的Vue项目的webpack4升级
参考大佬https://www.colabug.com/3206468.html
https://github.com/littlematch0123/blog-client
https://github.com/littlematch0123
- 2.5 vue事件中如何使用event对象?
div id="app">
<button v-on:click="click">click me</button>
</div>
...
var app = new Vue({
el: '#app',
methods: {
click(event) {
console.log(typeof event); // object
}
}
});
<div id="app">
<button v-on:click="click()">click me</button>
</div>
...
var app = new Vue({
el: '#app',
methods: {
click(event) {
console.log(typeof event); // undefined
}
}
});
<div id="app">
<button v-on:click="click($event, 233)">click me</button>
</div>
...
//获取事件对象 , 方法参数传递 $event
var app = new Vue({
el: '#app',
methods: {
click(event, val) {
console.log(typeof event); // object
}
}
});
<div id="app">
<button v-on:click="click(233)">click me</button>
</div>
...
var app = new Vue({
el: '#app',
methods: {
click(val) {
console.log(typeof event); // object
}
}
});
第一种是没有带圆括号,注意这时在处理函数的形参中是定义了 event 的,vue 在执行的时候,自动将 event 对象作为参数传入到其中了,所以我们取到的 event 对象其实是真正传入到处理函数中的参数,一定程度上可以理解成是该函数的局部变量;
第二种是带了圆括号的,这时的形参表里并没有定义 event 这一个参数,当前作用域并没有定义 evnet 这一个对象,所以 js 会尝试在定义这个处理函数的上级作用域中搜索 event 变量,仍未找到,最终到达全局作用域上,找到了 window.event 这一个对象,但是这一个对象并不是我们期望的 event 对象。
准确的说,是因为这一个对象存在兼容性问题,js 代码中常见的 var event = event || window.event; 就是这个道理,查 MDN 上说只有 IE/Edge/Chrome 支持。(实际上 Safari 也支持)
<li v-for="img in willLoadImg" @click="selectImg($event)">
<img class="loadimg" :src="img.url" :data-id="img.id" alt="">
</li>
currentTarget:currentTarget 事件属性返回其监听器触发事件的节点,即当前处理该事件的元素、文档或窗口。
通俗一点说,就是你的点击事件绑定在哪一个元素上,currentTarget获取到的就是哪一个元素。
target:target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。
通俗一点说,就是你当前点击的是哪一个元素,target获取到的就是哪一个元素。
methods: {
selectImg(event) {
console.log(event.currentTarget);
console.log(event.target);
}
}
//获得event对象兼容性写法
event || (event = window.event);
//获得target兼容型写法
event.target||event.srcElement
//阻止浏览器默认行为兼容性写法
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
//阻止冒泡写法
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
- 2.6 $nextTick的使用
this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
假设我们更改了某个dom元素内部的文本,而这时候我们想直接打印出这个被改变后的文本是需要dom更新之后才会实现的,也就好比我们将打印输出的代码放在setTimeout(fn, 0)中;
- 2.7 Vue 组件中 data 为什么必须是函数?
类比引用数据类型
Object是引用数据类型,如果不用function 返回,每个组件的data 都是内存的同一个地址,一个数据改变了其他也改变了;
javascipt只有函数构成作用域(注意理解作用域,只有函数的{}构成作用域,对象的{}以及 if(){}都不构成作用域),data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响
const MyComponent = function() {};
MyComponent.prototype.data = {
a: 1,
b: 2,
}
const component1 = new MyComponent();
const component2 = new MyComponent();
component1.data.a === component2.data.a; // true;
component1.data.b = 5;
component2.data.b // 5
如果两个实例同时引用一个对象,那么当你修改其中一个属性的时候,另外一个实例也会跟着改;
两个实例应该有自己各自的域才对,需要通过下面的方法来进行处理
const MyComponent = function() {
this.data = this.data();
};
MyComponent.prototype.data = function() {
return {
a: 1,
b: 2,
}
};
这样每一个实例的data属性都是独立的,不会相互影响了.因此每个实例可以维护一份被返回对象的独立的拷贝
所以,你现在知道为什么vue组件的data必须是函数了吧。这都是因为js本身的特性带来的,跟vue本身设计无关。其实vue不应该把这个方法名取为data(),应该叫setData或其他更容易理解的方法名。
- 2.8 v-for 与 v-if 的优先级
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
上面的代码只传递了未完成的 todos。
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if
置于外层元素 (或 <template>
)上。如:
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
题外话
永远不要把 v-if 和 v-for 同时用在同一个元素上。
一般我们在两种常见的情况下会倾向于这样做:
为了过滤一个列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。在这种情形下,请将 users 替换为一个计算属性 (比如 activeUsers),让其返回过滤后的列表。
为了避免渲染本应该被隐藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。这种情形下,请将 v-if 移动至容器元素上 (比如 ul, ol)。
<ul v-if="shouldShowUsers">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
</li>
</ul>