ES6语法补充
块级作用域:
作用域:变量在什么范围内是可以使用的
没有块级作用域导致的问题:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<button>按钮6</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
var btns = document.getElementsByTagName('button');
for (var i=0;i<btns.length;i++){
btns[i].addEventListener('click',function () {
console.log('第'+ i + '个按钮被点击');
})
}
</script>
</body>
</html>
![image-20200225233409318](/Users/qzk/Library/Application Support/typora-user-images/image-20200225233409318.png)
- 上面出现的问题是var没有块级作用域,导致i被for循环的时候更改。
- 解决办法之1:闭包函数,因为函数是有块级作用域的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<button>按钮6</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
// es5之前,因为if for都是没有块级作用域的,因此在很多时候,
// 我们要借助function的块级作用域来解决应用作用域外面变量的问题
// var btns = document.getElementsByTagName('button');
// for (var i = 0; i < btns.length; i++) {
// btns[i].addEventListener('click', function () {
// console.log('第' + i + '个按钮被点击');
// })
// }
// es6中通过let来声明变量的时候,就可以很好的解决块级作用域的问题
const btns = document.getElementsByTagName('button');
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function () {
console.log('第' + i + '个按钮被点击');
})
}
</script>
</body>
</html>
![image-20200225234704835](/Users/qzk/Library/Application Support/typora-user-images/image-20200225234704835.png)
const 的使用和注意点
- 一旦给const修饰的标识符被赋值之后,不能修改
const name = 'qzk';
name = 'asdaf';
// 不能修改
- 在使用const定时标识符的时候,必须进行赋值:
// 错误示范
const name
- 常量的含义是:是指向的对象不能修改,但是可以改变对象内部的属性
const obj_str = 'qzk';
obj_str = 'kobe';
![image-20200226232325354](/Users/qzk/Library/Application Support/typora-user-images/image-20200226232325354.png)
const obj = {
name:'qzk',
age:18,
height:1.88
};
console.log(obj);
obj.age=27;
obj.name ='kobe';
obj.height = 1.89;
console.log(obj)
![image-20200226232534800](/Users/qzk/Library/Application Support/typora-user-images/image-20200226232534800.png)
对象的增强写法
属性的增强写法
const name = 'qzk';
const age = 18;
// es5写法
const obj = {
name:name,
age:age
}
console.log(obj)
// es6的增强语法写法
const objES6 = {
name,
age
}
console.log(objES6)
![image-20200226233605929](/Users/qzk/Library/Application Support/typora-user-images/image-20200226233605929.png)
函数的增强写法
// 函数的增强语法
// es5写法,没有增强语法
const func = {
eat:function () {
console.log('eat')
},
running:function () {
console.log('running')
}
}
const funcES6 = {
running(){
console.log('running')
},
eat(){
console.log('eat')
},
}
————————————————————————————————————————————————————————————————————————
创建vue实例传入的options
el:
- 类型:string | HTMLElement(字符串或者 html)
- 作用:决定之后vue 实例会管理哪一个DOM
data
- 类型: Object | Function(组件中data必须是一个函数)
- 作用:Vue 实例对应的数据对象
methods
-
类型:
-
作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用
ps:
方法与函数的区别:通俗的说在 类里面的是方法,单独写的不在类里面的是函数
vue的生命周期(钩子函数)-->hook(callHook)
生命周期:事物从诞生到消亡的整个过程
vue的生命周期:创建出Vue对象到Vue对象的消亡。
生命周期函数:
参考链接:
https://blog.csdn.net/zjhzjh893/article/details/83691155
https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
绿色部分:vue源码内部执行的操作
红色部分:我们可以写的钩子函数
示例代码:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>计数器</h2>
<h1>{{counter}}</h1>
<button v-on:click="add">+</button>
<button v-on:click="sub">-</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
// 语法糖:简写的意思
// proxy
const obj = {
counter: 0,
message: 'abc'
}
const app = new Vue({
el: '#app',
data: {
counter: 0,
},
methods: {
add: function () {
console.log('add,+1');
this.counter++
},
sub: function () {
console.log('sub,-1');
this.counter--
}
}
})
</script>
</body>
</html>
vue的模版语法
插值操作
如何将data中的文本数据,插入到html中呢?
- Mustache语法(也就是双大括号):响应式的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>{{body}}</h1>
<h2>{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好',
body: 'qzk'
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>计数器</h2>
<!-- v-once 指令,指定当 {{ }} 内的变量的值发生改变的时候,变量所展示的还是原来的值-->
<h1 v-once>{{message}}</h1>
<h1 >{{message}}</h1>
<h1 >{{message}},你好啊</h1>
<!-- v-text='变量名',在html标签中渲染变量,并且会覆盖原标签内的文本-->
<h1 v-text="message"></h1>
<h1 v-text="message">你好啊</h1>
<!-- v-htm='url变量名',在html标签中渲染a标签-->
<h1 v-html="url"></h1>
<h1>url</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
// 语法糖:简写的意思
// proxy
const obj = {
counter: 0,
message: 'abc'
}
const app = new Vue({
el: '#app',
data: {
counter: 0,
message:'123',
url:'<a href="https://www.baidu.com">百度一下</a>'
},
methods: {
add: function () {
console.log('add,+1');
this.counter++
},
sub: function () {
console.log('sub,-1');
this.counter--
}
}
})
</script>
</body>
</html>
指令之v-pre:
V-pre 用于跳过这个元素和他的字元素的编译过程,用于显示原本的Mustache语法
指令之v-cloak:
在某些情况下,我们浏览器可能会直接显示出来未编译的Mystache标签
因此,v-cloak就是防止改现象发生的指令。
下述代码,执行过程中设置了一秒的延迟:
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{counter}}</h2>
<h2 v-cloak>
{{counter}}
</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
// 语法糖:简写的意思
// proxy
const obj = {
counter: 0,
message: 'abc'
}
setTimeout(function () {
const app = new Vue({
el: '#app',
data: {
counter: 0,
},
methods: {
add: function () {
console.log('add,+1');
this.counter++
},
sub: function () {
console.log('sub,-1');
this.counter--
}
}
})
},1000)
</script>
</body>
</html>
v-bind介绍
前面我们学习的指令主要作用是将值插入到我们的模版内容中,但是,除了内容需要动态来决定外,某些属性我们也希望可以动态来绑定。
比如:
- 动态绑定a元素的href
- 比如动态绑定img元素的src属性
这个时候,我们就可以使用 v-bind指令:
- 作用:动态绑定属性
- 缩写::
- 预期:any(with arguement | Object(without arguement))
- 参数:attrOrProp(optional)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 该方式不可取,因为mastache语法只能添加在文本中,不可在属性中使用-->
<img src="{{imgURL}}" alt="">
<!-- 正确做法,适应v-bind: 这样 src属性中 imgURL会被看作变量,回去 vue实例中去找我们的imgurl属性-->
<img v-bind:src="imgURL" alt="">
<!-- 缩写形式-->
<img :src="imgURL" alt="">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el: '#app',
data: {
imgURL: 'http://uploads.5068.com/allimg/1802/78-1P22QAK3-51.jpg'
}
})
</script>
</body>
</html>
效果如图:
![image-20200223194903180](/Users/qzk/Library/Application Support/typora-user-images/image-20200223194903180.png)
v-bind绑定对象class(对象语法与数组绑定)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 对象语法 -->
<h2 :class="{active:isActive,line:isLine}">{{message}}</h2>
<!-- 对象语法加函数-->
<h2 :class="GetClass()">{{message}}</h2>
<!-- 数组语法-->
<!-- ['',''] 加单引号当字符串去解析-->
<h2 :class="['active','line']">{{message}}</h2>
<!-- 不加单引号,当变量去解析-->
<h2 :class="[isActive,isLine]">{{message}}</h2>
<h2 :class="GetListClass()">{{message}}</h2>
<button v-on:click="btnClick">点击</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'qzk',
isActive: true,
isLine: false,
imgURL: 'http://uploads.5068.com/allimg/1802/78-1P22QAK3-51.jpg',
ahref: 'https://www.baidu.com'
},
methods: {
btnClick: function () {
alert(this.isActive);
this.isActive = !this.isActive
},
GetClass: function () {
return {active: this.isActive, line: this.isLine}
},
GetListClass: function () {
return [this.isActive, this.isLine]
}
}
})
</script>
</body>
</html>
vue计算属性的基本使用(computed)
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{FullName}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el:'#app',
data:{
firstName:'qzk',
lastName:'test'
},
// 计算属性
computed:{
/**
* @return {string}
*/
// 将data 计算称 FullName 在html中返回
FullName:function () {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>总价:{{totalPrice}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el: '#app',
data: {
books: [
{id: 100, name: '深入理解计算机原理0', price: 100},
{id: 101, name: '深入理解计算机原理1', price: 100},
{id: 102, name: '深入理解计算机原理2', price: 100},
{id: 103, name: '深入理解计算机原理3', price: 100}
]
},
// 计算属性
computed: {
/**
* @return {string}
*/
totalPrice: function () {
let result = 0;
for (let i = 0; i < this.books.length; i++) {
result += this.books[i].price
}
// es6语法实现
for (let i in this.books){
}
// es6语法2
for (book in this.books){
}
return result;
}
}
})
</script>
</body>
</html>
计算属性(在mustache语法中不需要加()),有些时候在 computed中做属性的操作,更方便。
计算属性为什么不是按照函数方式执行而是按照data方式执行--getter和setter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div>{{fullName}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
firstName:'qian',
lastName:'zhengkai'
},
computed:{
// fullName: function () {
// return this.firstName + ' ' + this.lastName
// },
fullName:{
// 计算属性一般不建议使用set方法
set:function (newName) {
// 一般用于设置data中变量的属性,且需要传入参数
const name=newName.split(' ');
this.firstName = name[0];
this.lastName = name[1];
},
get:function () {
// 如果 这里 fullName return的是 abc 则返回abc
// return 'abc'
return this.firstName + ' ' + this.lastName
}
}
}
});
</script>
</body>
</html>
![image-20200225230342617](/Users/qzk/Library/Application Support/typora-user-images/image-20200225230342617.png)
计算属性的缓存(计算属性和methods的对比)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 直接拼接的方式 此方法不推荐使用-->
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{fullName()}}</h2>
<h2>{{fullName()}}</h2>
<h2>{{fullName()}}</h2>
<h2>{{fullName()}}</h2>
<h2>{{fullName()}}</h2>
<h2>{{fullName1}}</h2>
<h2>{{fullName1}}</h2>
<h2>{{fullName1}}</h2>
<h2>{{fullName1}}</h2>
<h2>{{fullName1}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
firstName:'qian',
lastName:'ZHENGKAI',
},
computed:{
fullName1: function () {
console.log('full_computed');
return this.firstName + ' ' + this.lastName
}
},
methods:{
fullName: function () {
console.log('full_method');
return this.firstName + ' ' + this.lastName
}
}
});
</script>
</body>
</html>
![image-20200225231703471](/Users/qzk/Library/Application Support/typora-user-images/image-20200225231703471.png)
v-on使用
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>方法一:</h1>
<h2>{{counter1}}</h2>
<button v-on:click="counter1++">+</button>
<button v-on:click="counter1--">-</button>
<h1>方法二:</h1>
<h2>{{counter2}}</h2>
<button v-on:click="increment">+</button>
<button v-on:click="increment">-</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
counter1: 0,
counter2: 0
},
methods: {
// ES6增强写法
increment() {
this.counter2++
},
// ES6 增强写法
decrement() {
this.counter2--
}
}
});
</script>
</body>
</html>
![image-20200309005857554](/Users/qzk/Library/Application Support/typora-user-images/image-20200309005857554.png)
v-on语法糖是 @ ,例如 v-on:click. = @click
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>方法一:</h1>
<h2>{{counter1}}</h2>
<!--@ 是 v-on 语法糖-->
<button @click="counter1++">+</button>
<button @click="counter1--">-</button>
<h1>方法二:</h1>
<h2>{{counter2}}</h2>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
counter1: 0,
counter2: 0
},
methods: {
// ES6增强写法
increment() {
this.counter2++
},
// ES6 增强写法
decrement() {
this.counter2--
}
}
});
</script>
</body>
</html>
v-on参数问题(传递参数)
当通过methods中定义的方法,以供@click调用的时候,需要注意参数问题
- 情况一:如果该方法不需要额外参数,那么方法后的()可以不添加
- 但是注意:如果方法本身中有一个参数,那么会默认将原省时间event参数传递进去
- 情况二:如果需要同事传入某个参数,同时需要event时,可以通过$event传入事件
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- <h1>方法一:</h1>-->
<!-- <h2>{{counter1}}</h2>-->
<!-- 演示 @click 不传递参数-->
<button @click='btn1Click'>按钮1</button>
<button @click='btn1Click()'>按钮2</button>
<!-- 在事件定义时,写函数时省略小括号,但是方法本身时需要一个参数的-->
<button @click='btn3Click(123)'>按钮3</button>
<!--如果我们的方法在定义时需要传入参数,但是没有传入则默认值为undefined-->
<button @click='btn3Click()'>按钮3</button>
<!--如果不加括号,则浏览器会默认将event事件对象传入到函数中,这里表现为 MouseEvent-->
<button @click='btn3Click'>按钮3</button>
<!-- 方法定义时同时需要event又需要其他参数的情况-->
<!-- 在调用方法时,如何手动的获取d到浏览器的eventd对象:$event -->
<button @click='btn4Click(abc,$event)'>按钮4</button>
<!-- -->
<!-- <button @click='btn5Click'>按钮5</button>-->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
counter1: 0,
counter2: 0,
abc:123
},
methods: {
// ES6增强写法
btn1Click() {
console.log('点击')
},
btn3Click(abc) {
console.log('----->', abc)
},
btn4Click(abc, event) {
console.log('++++>', abc, event)
}
}
});
</script>
</body>
</html>
![image-20200309012332654](/Users/qzk/Library/Application Support/typora-user-images/image-20200309012332654.png)
![image-20200309013207410](/Users/qzk/Library/Application Support/typora-user-images/image-20200309013207410.png)
v-on修饰符
在某些情况下,我们拿到event的魔都可能是进行一些事件处理,vue提供了修饰符来帮助我们方便的处理事件:
- stop---调用 event.stopPropagation()
- .prevent ---- 调用 event.preventDefault()
- .{keyCode|KeyAlias} - 只当前时间是从特定键出发时才触发
- .native ---监听组件根元素的原生事件
- .once --- 只出发一次回调
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--.stop 来阻止冒泡事件-->
<div id="app">
<div @click="divClick">
<h3>asdf</h3>
<button @click.stop='submit1Click'>按钮</button>
</div>
<br>
<div>
<!-- 该方法form提交一次,但是submit2click 方法也执行了, 其中 input点击的默认事件是 提交form-->
<h2>form提交 submit</h2>
<form action="baidu">
<input type="submit" value="提交1" @click='submit2Click'>
</form>
<br>
<!-- 我们可以通过 .prevent 来阻止默认事件 -->
<h2>通过method click事件操作form</h2>
<form action="baidu">
<input type="submit" value="提交2" @click.prevent='submit3Click'>
</form>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
counter1: 0,
counter2: 0
},
methods: {
divClick() {
console.log('divclick')
},
submit1Click() {
console.log('提交1')
},
submit2Click() {
console.log('提交2')
},
submit3Click() {
console.log('提交3')
}
}
});
</script>
</body>
</html>
![image-20200309015551554](/Users/qzk/Library/Application Support/typora-user-images/image-20200309015551554.png)
v-if用法
<!--基本使用-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- isShow为true的时候显示-->
<h2 v-if="isShow">{{message}}</h2>
<!-- isShow 为false的时候显示-->
<h2 v-else>isshow为false的时候显示我</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
message: 'hello',
isShow: true
}
});
</script>
</body>
</html>
![image-20200309231810077](/Users/qzk/Library/Application Support/typora-user-images/image-20200309231810077.png)
V-else-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- isShow为true的时候显示-->
<h2 v-if="score>=85">优秀</h2>
<!-- 这里使用 v-else-if 的时候 不需要再写 <85 ,因为上面条件不满足的时候才会执行下面-->
<h2 v-else-if="score>=75">还可以</h2>
<h2 v-else-if="score>=60">及格</h2>
<h2 v-if="score<60">不及格</h2>
<!-- isShow 为false的时候显示-->
<!-- 也可以利用计算属性来实现上述的代码-->
<h1>{{result}}</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
score:99
},
computed:{
result(){
let showMessage = '';
if(this.score >=85){
showMessage = '优秀'
}else if (this.score >=75){
showMessage = '还可以'
}else if (this.score>=60){
showMessage = '及格'
}else{
showMessage = '不及格'
}
return showMessage
}
}
});
</script>
</body>
</html>
![image-20200309232828788](/Users/qzk/Library/Application Support/typora-user-images/image-20200309232828788.png)
用户登陆方式选择的小案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div v-if="isUserLogin">
<span>
<label for="username">用户名登陆</label>
<input type="text" id="username" placeholder="请输入用户名">
</span>
</div>
<div v-else>
<span>
<label for="email">用户邮箱登陆</label>
<input type="text" id='email' placeholder="请输入邮箱" >
</span>
</div>
<button @click="changeLogin">更改登陆方法</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
isUserLogin:true
},
methods:{
changeLogin(){
this.isUserLogin = !this.isUserLogin;
console.log(this.isUserLogin)
}
}
});
</script>
</body>
</html>
![image-20200309234523710](/Users/qzk/Library/Application Support/typora-user-images/image-20200309234523710.png)
![image-20200309234541999](/Users/qzk/Library/Application Support/typora-user-images/image-20200309234541999.png)
注意:
- vue底层为了性能优化,有搞一个虚拟dom放在内存中,这样尽可能的复用已存在的可服用的dom
- 在上面的案例中,vue内部会发现原来的input元素不在使用,直接做else中的input来使用了
解决方法:
- 如果我们不希望vue出现类似的重复利用的问题,可以给对应的input添加key
- 并且保证key的不同
实现示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div v-if="isUserLogin">
<span>
<label for="username">用户名登陆</label>
<input type="text" id="username" placeholder="请输入用户名" key="username">
</span>
</div>
<div v-else>
<span>
<label for="email">用户邮箱登陆</label>
<input type="text" id='email' placeholder="请输入邮箱" key="email">
</span>
</div>
<button @click="changeLogin">更改登陆方法</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
isUserLogin:true
},
methods:{
changeLogin(){
this.isUserLogin = !this.isUserLogin;
console.log(this.isUserLogin)
}
}
});
</script>
</body>
</html>
v-show
v-show和v-if非常相似,也是用来决定一个元素是否渲染。
v-show 和 v-if 比较:
- v-if 当条件为false时,压根不会有对应的元素在dom中
- v-show 当条件为false时,仅仅是对元素的display属性设置为none而已
开发中如何选择:
- 当需要在显示与盈仓之间切换很频繁时,使用v-show
- 当只有一次切换时,使用v-if
示例:略
v-for使用:
- V-for 遍历数组:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in names">{{item}}</li>
</ul>
<!--index 为 元素的索引-->
<ul>
<li v-for="(index,item) in names">
{{index}} ----> {{item}}
</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
names:['q','z','k','1']
}
});
</script>
</body>
</html>
V-for 遍历对象
![image-20200312222701846](/Users/qzk/Library/Application Support/typora-user-images/image-20200312222701846.png)
上图是v-for获取对象(字典的相关数据)
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 1.在遍历的过程中如果只获取一个值,获取到的时value-->
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<!-- 2.获取 key和value 用 (key,value)-->
<ul>
<li v-for="(key,value) in info">{{key}},{{value}}</li>
</ul>
<!-- 3.获取key和value和索引index,用 (key,value,index)-->
<ul>
<li v-for="(key,value,index) in info">{{index}}+{{key}}+{{value}}</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
let app;
app = new Vue({
el: '#app',
data: {
info:{
name:'qzk',
age:18,
height:180
}
}
});
</script>
</body>
</html>
组件的key属性
官方推荐我们在使用v-for时,给对应的元素或组件添加上一个:key属性
- 为什么需要加上key属性呢?
- 这个其实和vue的虚拟DOM的Diff算法有关
- 当某一层油很多相同节点的时候,也就是列表节点时,我们希望插入一个新的节点
- 我们希望可以再b和c之间插入f, Diff算法默认执行起来是这样的
- 即把C更新成F ,D更新成C 。。。。
- 所以我们用key 来给每个节点做一个唯一标识
- diff 算法就可以正确的识别出此节点
- 找到正确的位置插入新的节点
- 所以:key的作用主要是为了更高效的更新虚拟DOM
表单绑定之v-model(常用)
- 表单控件在实际开发中是非常常见的,特别是对用户信息的提交。需要大量的表单。
- Vue 中使用 v-model 指令来实现变淡元素数据的双向绑定。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--通过v-model 绑定表单元素 ,这样如果 input输入的信息改变的时候 data中的message 也会随之改变。两者之间建立了绑定关系-->
<input type="text" v-model="message">
{{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:'你好'
}
})
</script>
</body>
</html>
双向绑定的本质:实际上相当于两个指令的集合
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<label>
<!-- <input type="text" v-model="message">-->
<input type="text" :value="message" @input="message = $event.target.value">
</label>
{{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message:'你好'
}
})
</script>
</body>
</html>
V-model绑定radio
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<label for="male">
<input type="radio" id="male" name="sex" v-model="sex" value="男">男
</label>
<label for="female">
<input type="radio" id="female" name="sex" v-model="sex" value="女">女
</label>
<h2>您选择的性别是:{{sex}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el: '#app',
data: {
"sex":''
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1. 修饰符:lazy(懒加载) 使用.lazy修饰符后,双向绑定的标签会在敲击回车键或失去焦点后进行实时绑定,这样可以降低加载的次数提升性能-->
<label for="test1">
<input type="text" id="test1" v-model.lazy="msg">
</label>
<h2>{{msg}}</h2>
<!-- 2. 修饰符:trim 删除input左右两边的空格-->
<label for="test2">
<input type="text" id="test2" v-model.trim="name">
</label>
<h2>{{name}}</h2>
<!-- 3。 修饰符:number 使用这个时候默认输入的就是num类型不需要在进行数字类型转换-->
<label for="test3">
<input type="number" id="test3" v-model.number="age">
</label>
<h2>{{age}}-{{typeof age}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script>
const app = new Vue({
el: '#app',
data: {
"msg":'你好',
"name":'',
"age":''
}
})
</script>
</body>
</html>