05 vue基础内容补充1
指令
v-once
- 该指令后面不需要跟任何表达式
- 该指令表示元素和组件只渲染一次,不会随着数据的改变而改变
v-pre
v-pre用于跳过整个元素和它子元素的编译过程,用于显示原本的Mustache语法
例子
-
第一个h2元素中的内容会被编译解析出来对应的内容
-
第二个h2元素中会直接显示{{message}}
<div id="app">
<h2>{{message}}</h2>
<h2 v-pre>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
v-cloak
某些情况下,我们浏览器可能会直接显示出为编译的Mustache标签
而v-cloak指令可以在vue解析结束后消失
例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<h2>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
// 在vue解析之前, div中有一个属性v-cloak
// 在vue解析之后, div中没有一个属性v-cloak
setTimeout(function () {
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
}, 1000)
</script>
</body>
</html>
v-if、v-else-if、v-else
- 这三个指令与JavaScript的条件语句if、else、else if类似。
- Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件
例子
<div id="app">
<h2 v-if="score>=90">优秀</h2>
<h2 v-else-if="score>=80">良好</h2>
<h2 v-else-if="score>=60">及格</h2>
<h2 v-else>不及格</h2>
</div>
补充
- Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素
- 如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key,并且我们需要保证key的不同
v-model补充
搭配radio
例子
<div id="app">
<label for="male">
<input type="radio" id="male" value="男" v-model="sex">男
</label>
<label for="female">
<input type="radio" id="female" value="女" v-model="sex">女
</label>
<h2>您选择的性别是: {{sex}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
sex: '女'
}
})
</script>
搭配checkbox
例子
<div id="app">
<!--1.checkbox单选框-->
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>您选择的是: {{isAgree}}</h2>
<!--<button :disabled="!isAgree">下一步</button>
<!--2.checkbox多选框-->
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<h2>您的爱好是: {{hobbies}}</h2>
<label v-for="item in originHobbies" :for="item">
<input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
</label>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isAgree: false, // 单选框
hobbies: [], // 多选框,
originHobbies: ['篮球', '足球', '乒乓球', '羽毛球', '台球', '高尔夫球']
}
})
</script>
搭配select
例子
<div id="app">
<!--1.选择一个-->
<select name="abc" v-model="fruit">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="葡萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruit}}</h2>
<!--2.选择多个-->
<select name="abc" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="榴莲">榴莲</option>
<option value="葡萄">葡萄</option>
</select>
<h2>您选择的水果是: {{fruits}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
fruit: '香蕉',
fruits: []
}
})
</script>
修饰符
lazy修饰符
- 默认情况下,v-model默认是在input事件中同步输入框的数据的。
- 也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。
- lazy修饰符可以让数据在失去焦点或者回车时才会更新
number修饰符
- 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。
- 但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。
- number修饰符可以让在输入框中输入的内容自动转成数字类型
trim修饰符
- 如果输入的内容首尾有很多空格,通常我们希望将其去除
- trim修饰符可以过滤内容左右两边的空格
例子
<div id="app">
<!--1.修饰符: lazy-->
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>
<!--2.修饰符: number-->
<input type="number" v-model.number="age">
<h2>{{age}}-{{typeof age}}</h2>
<!--3.修饰符: trim-->
<input type="text" v-model.trim="name">
<h2>您输入的名字:{{name}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
age: 0,
name: ''
}
})
</script>
conputed
介绍
-
我们知道,在模板中可以直接通过插值语法显示一些data中的数据。
-
但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示
-
比如我们有firstName和lastName两个变量,我们需要显示完整的名称。
-
但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}
-
-
我们可以将上面的代码换成计算属性:
- OK,我们发现计算属性是写在实例的computed选项中的。
例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Lebron',
lastName: 'James'
},
// computed: 计算属性()
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
},
methods: {
getFullName() {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>
</html>
setter和getter
-
每个计算属性都包含一个getter和一个setter
-
在上面的例子中,我们只是使用getter来读取。
-
在某些情况下,你也可以提供一个setter方法(不常用)。
-
在需要写setter的时候,代码如下:
const app = new Vue({ el: '#app', data: { firstName: 'Kobe', lastName: 'Bryant' }, computed: { fullName: { set: function(newValue) { const names = newValue.split(' '); this.firstName = names[0]; this.lastName = names[1]; }, get: function () { return this.firstName + ' ' + this.lastName } }, } })
-
当需要赋值给有set的属性时,就会进行setter的方法。
例子
<div id="app">
姓:{{firstName}}<br>
名:{{lastName}}<br>
姓名:<input type="text" v-model="fullName"><br>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Zhu',
lastName: 'Biang',
},
computed: {
fullName: {
get() { //当需要读取当前属性值时执行,根据getter返回值
return this.firstName + ' ' + this.lastName
},
set(val) { //当属性值发生变化时执行,比如被赋值,通过setter方法更新相关的属性数据
const names = val.split(' ');
this.firstName = names[0];
this.lastName = names[1];
}
}
}
})
</script>
缓存
-
我们可能会考虑这样的一个问题:
- methods和computed看起来都可以实现我们的功能,
- 那么为什么还要多一个计算属性这个东西呢?
- 原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次。
ES6补充
let/var
介绍
-
事实上var的设计可以看成JavaScript语言设计上的错误. 但是这种错误多半不能修复和移除, 以为需要向后兼容.
- 大概十年前, Brendan Eich就决定修复这个问题, 于是他添加了一个新的关键字: let.
- 我们可以将let看成更完美的var
-
块级作用域
- JS中使用var来声明一个变量时, 变量的作用域主要是和函数的定义有关.
- 针对于其他块定义来说是没有作用域的,比如if/for等,这在我们开发中往往会引起一些问题。
例子
如果要给所有button标签添加上点击事件
const btns = document.getElementsByTagName('button')
如果用的是这种代码(var)
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function() {
console.log('第' + i + '个按钮被点击');
})
}
会出现的问题,无论点击哪个按钮,都是执行console.log(‘第’ + btns.length + ‘个按钮被点击’)
通过闭包可以解决该问题,在js基础篇 05 函数补充 作用域 预解析 对象中的 作用域 作用域分类/局部作用域 中有提到
又称函数作用域 在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用
for (var i=0; i<btns.length; i++) {
(function (num) {
btns[i].addEventListener('click', function () {
console.log('第' + num + '个按钮被点击');
})
})(i)
}
这样子通过函数作用域将var声明的i包装起来,i就不会随着全局变量i的变化而变化
而let就不需要考虑这一点
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function() {
console.log('第' + i + '个按钮被点击');
})
}
比较清晰易懂
const
介绍
- 在很多语言中已经存在, 比如C/C++中, 主要的作用是将某个变量修饰为常量.
- 在JavaScript中也是如此, 使用const修饰的标识符为常量, 不可以再次赋值.
使用时机
- 当我们修饰的标识符不会被再次赋值时, 就可以使用const来保证数据的安全性.
建议 : 在 ES6 开发中 , 优先使用 const, 只有需要改变某一个标识符的时候才使用 let.
注意
- const修饰的标识符的值不可改变
- const修饰的标识符必须初始化
对象增强写法
-
属性初始化简写
const name = 'why'; const age = 18; const height = 1.88 //ES5的写法 const obj = { name: name, age: age, height: height } //ES6的写法:省去了:值 const obj = { name, age, height, } console.log(obj);
-
方法的简写
//ES5的写法 const obj = { run: function () { }, eat: function () { } } //ES6的写法:省去了function const obj = { run() { }, eat() { } }
组件的key属性
-
官方推荐我们在使用v-for时,给对应的元素或组件添加上一个:key属性。
-
为什么需要这个key属性呢(了解)?
-
这个其实和Vue的虚拟DOM的Diff算法有关系。
-
当某一层有很多相同的节点时,也就是列表节点时,我们希望插入一个新的节点
A、B、C、D、E
我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的。
A B C D E
↓ ↓ ↓ ↓ ↓
A B F C D E
即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
- 所以我们需要使用key来给每个节点做一个唯一标识
Diff算法就可以正确的识别此节点
找到正确的位置区插入新的节点。
- 所以一句话,key 的作用主要是为了高效的更新虚拟 DOM 。