Vue的指令和生命周期
指令
指令讲解:https://www.bilibili.com/video/BV11s411A7h6?p=7
Vue的指令都带有前缀v,表示他是Vue特有的attribute。它们会在渲染的 DOM 上应用特殊的响应式行为。
插值指令
v-cloak
使用v-cloak能够解决插值闪烁的问题
v-text
默认v-text是没有闪烁问题的
v-test会替代元素中原本的内容,但是v-cloak不会,只会把{{}}中的内容替换
v-html
使用v-html能解析html中的内容
v-bind
用来绑定元素的属性,缩写是 :
在head中加上display属性,可以使得v-cloak中的{{msg}}在加载完前不会显示(也就是不会闪烁)
<style>
[v-cloak] {
display: none;
}
</style>
<body>
<!--vue控制的元素区,就是v-->
<div id="app">
<!--使用v-cloak能够解决插值表达式闪烁的问题-->
<p v-cloak>{{ msg }}</p>
<h4 v-text="msg"></h4> <!--默认v-test是没有闪烁问题的-->
<!--v-test会替代元素中原本的内容,但是v-cloak不会,只会把{{}}中的内容替换-->
<div v-html="msg2"></div>
<!--使用v-html可以直接解析html标签,v-html也会覆盖元素中原本的内容-->
<input type="button" value="按钮" v-bind:title="mytitle">
<!--v-bind用于绑定属性,mytitle就相当于一个变量。v-bind:也可以简写为:-->
</div>
<!--这个vm对象就是MVVM中的VM调度者-->
<script>
//创建Vue实例
var vm = new Vue({
el:'#app', //表示我们要控制的区域
//这里的data就是MVVM中的M,专门用来保存每一个页面的数据
data:{
msg:'欢迎学习Vue',
msg2:'<h1>我是一个h1标签</h1>',
mytitle:'我是一个title'
}
})
</script>
</body>
v-bind设置样式
通过v-bind绑定class属性来设置内部样式:
一些样式如下:
<style>
.red{
color:red
}
.thin{
font-weight: 200;
}
.italic{
font-style: italic;
}
.active{
letter-spacing: 0.5em;
}
</style>
如何用Vue设置元素的样式:
- 使用数组的形式
<body>
<div id="app">
<!--修改样式,第一种:直接传递一个数组。使用v-bind绑定。注意数组中是元素是样式的字符形式(不使用字符形式,则会将其看作变量)-->
<h1 v-bind:class="['thin','italic','red']">这是一个H1</h1>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
},
methods:{
}
})
</script>
</body>
- 使用三元表达式,实现样式的选择
<body>
<div id="app">
<!--使用三元运算,当flag为true时为red,否则就不为red-->
<h1 v-bind:class="['thin','italic',flag?'red':'']">这是一个H1</h1>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
flag : false
},
methods:{
}
})
</script>
</body>
- 数组中嵌套对象,实现样式的选择
<body>
<div id="app">
<!--在数组中 使用对象来代替三元表达书,red为类名,flag为值-->
<h1 v-bind:class="['thin','italic',{'red':flag}]">这是一个H1</h1>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
flag : true
},
methods:{
}
})
</script>
</body>
- 直接使用对象
<h1 v-bind:class="{red:true,italic:true,thin:true,active:false}">这是一个H1</h1>
通过v-bind绑定style属性来设置行内样式:
- 在style里面写上对象
<body>
<div id="app">
<!--直接在里面加上对象,对象就是无序的键值对集合-->
<h1 :style="{'color':'red','font-weight':200}">这是一个H1</h1>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
},
methods:{
}
})
</script>
</body>
- 将样式定义到data中,并引入到style中
通过数组可以引入多个
<body>
<div id="app">
<!--直接在里面加上对象,对象就是无序的键值对集合-->
<h1 :style="[styleObj1,styleObj2]">这是一个H1</h1>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
styleObj1:{'color':'red','font-weight':200},
styleObj2:{'fontStyle':'italic'}
},
methods:{
}
})
</script>
</body>
事件指令
v-on
使用v-on实现事件,缩写是@,他会在method中寻找方法。
<input type="button" value="按钮2" v-on:click="show"> <!--点击事件-->
<input type="button" value="按钮2" v-on:mouseover="show"> <!--鼠标触及事件-->
<script>
//创建Vue实例
var vm = new Vue({
el:'#app', //表示我们要控制的区域
methods:{ //在method中定义方法
show: function () {
alert('Hello')
}
}
})
</script>
事件修饰符
.stop
:阻止冒泡(事件的继续传播).prevent
:阻止默认事件.capture
:添加事件侦听器时使用事件捕获模式.self
:只有当事件在该元素本身(不包含子元素等)触发时触发回调,但是阻止别的冒泡.once
:事件只触发一次.passive
:默认会执行的事件,使用这个可以让事件快速产生,通常应用于滑动事件
注:不要把 .passive
和 .prevent
一起使用,因为 .prevent
将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive
会告诉浏览器你不想阻止事件的默认行为。
<body>
<div id="app">
<div class="inner" @click="divHandler">
<!--默认会先实现button的点击事件,然后触发div的点击事件-->
<!--如果在button后加上stop的事件修饰符,就会阻止事件的冒泡(也就是只会触发button的点击事件)-->
<input type="button" value="戳他" @click.stop="btnHandler">
<!--prevent阻止了默认行为的发生(这里就不会跳转到百度这个界面)。这个就可以用于权限上(没有权限就不能点击啥的)-->
<!--once是让事件只发生一次,也就是这里的prevent只阻止了一次-->
<a href="http://www.baidu.com" @click.prevent.once="linkClick">有问题,问百度</a>
</div>
<!--使用capture实现捕获触发事件的机制(在这里就是先触发外部的点击事件,再触发里面的)-->
<div class="inner" @click.capture="divHandler">
<input type="button" value="戳他" @click.stop="btnHandler">
</div>
<!--使用self,只有触发自己的事件才可以,冒泡或者孩子都不行-->
<div class="inner" @click.self="divHandler">
<input type="button" value="戳他" @click.stop="btnHandler">
</div>
</div>
<script>
//创建一个Vue实例,得到ViewModel
var vm = new Vue({
el:'#app',
data:{
},
methods:{
divHandler(){
console.log("触发了div的点击事件")
},
btnHandler(){
console.log("触发了btn的点击事件")
},
linkClick(){
console.log("跳转至百度")
}
}
})
</script>
</body>
按键修饰符
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on
在监听键盘事件时添加按键修饰符:
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
.enter
.tab
.delete
(捕获“删除”和“退格”键).esc
.space
.up
.down
.left
.right
v-for循环
v-for可以循环一个普通数组、对象数组、对象,也可以迭代数字(从1开始)
<body>
<div id="app">
<!--循环普通数组,第一个位置的item就是list中遍历的值,第二个位置的i为索引值-->
<p v-for="(item,i) in list">索引值:{{i}} --- {{item}}</p>
<!--循环对象数组-->
<p v-for="user in list1">{{user.id}} --- {{user.name}}</p>
<!--循环对象中的属性,除了val和key,在第三个位置上是索引-->
<p v-for="(val,key) in user">值是:{{val}} --- 键是:{{key}}</p>
<!--迭代数字,这里的count是从1开始的-->
<p v-for="count in 10">这是第{{count}}次循环</p>
</div>
<script>s
var vm = new Vue({
el:'#app',
data:{
list:[1,2,3,4,5],
list1:[
{id:1,name:'a'},
{id:2,name:'b'},
{id:3,name:'c'},
{id:4,name:'d'},
{id:5,name:'e'},
],
user:{
id:1,
name:'Tom',
gender:'男'
}
},
methods:{
}
})
</script>
</body>
循环组件:
<body>
<div id="app">
<div>
<label>Id:
<input type="text" v-model="id">
</label>
<label>Name:
<input type="text" v-model="name">
</label>
<input type="button" value="添加" @click="add">
</div>
<!--循环组件-->
<!--指定了key值就可以指定循环的位置,如果没有的话,就默认以索引作为位置(而当动态变化数组的时候索引为变化,对应的位置就会变化)-->
<!--注意v-for的时候,key属性只能使用number获取string-->
<!--注意:key在使用的时候,必须使用v-bind属性绑定的形式,指定key的值-->
<p v-for="item in list2" v-bind:key="item.id">
<input type="checkbox">
{{item.id}}--{{item.name}}
</p>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
name:'',
id:'',
list2:[
{id:1,name:'软件工程'},
{id:2,name:'需求'},
{id:3,name:'数据库'},
{id:4,name:'vue'},
{id:5,name:'springboot'},
]
},
methods:{
add(){
//this.list2.push({id:this.id,name:this.name}) //直接使用push向里面添加(在数组后面添加)
this.list2.unshift({id:this.id,name:this.name}) //使用unshift添加(在数组前面添加)
}
}
})
</script>
</body>
v-if和v-show
<body>
<div id="app">
<input type="button" value="按钮" @click="toggle">
<!--v-if是只要没有了,就是将其删除-->
<!--v-show不会删除组件,不会进行DOM的删除和创建,只是切换了display:none样式-->
<!--v-if有较高的切换性能消耗-->
<!--v-show又较高的初始渲染消耗-->
<!--如果元素涉及到频繁的切换,最好不要使用v-if。如果元素可能永远不会显示出来(稳定的时候),则选择v-if好些-->
<h3 v-if="flag">这是用v-if控制的元素</h3>
<h3 v-show="flag">这是用v-show控制的元素</h3>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
flag:true
},
methods:{
toggle(){
this.flag = !this.flag
}
}
})
</script>
</body>
生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
生命周期图示:
原图地址: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
过程讲解:https://www.bilibili.com/video/BV11s411A7h6?p=36
注意:
生命周期函数不能使用箭头函数,因为箭头函数里面是没有this的,而在生命周期中我们需要频繁的使用this。
钩子函数:
beforeCreate
在实例初始化之后,数据观测(data observer)和event/watcher事件配置之前被调用。(整个页面创建之前调用的生命周期)
created
实例创建完之后被立即调用。
此时,实例已经完成了数据观测(data observer),属性和方法的运算,watcher/event事件回调。
但是挂载阶段还没有开始,$el属性目前不可见。
beforeMount
在挂载开始之前被调用,相关的渲染函数首次被调用。
mounted
挂载成功之后调用的函数,el被新创建的vm.$el替换
beforeUpdate
数据更新是调用,发生在虚拟DOM打补丁之前。这里适合在更新之前访问现有DOM。
updated
数据更改导致虚拟DOM重新渲染和补丁,在这之后会调用此钩子
数据、组件更新完毕时调用
beforeDestory
实例销毁之前调用。在这一步,实例仍然完全可用。
destoryed
实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
浅谈Vue3生命周期
Vue3新特性:http://www.liulongbin.top:8085/#/
setup()函数会在buforeCreate()之后,created之前执行
钩子函数的变化:
-> usebeforeCreate
setup()
-> usecreated
setup()
beforeMount
->onBeforeMount
mounted
->onMounted
beforeUpdate
->onBeforeUpdate
updated
->onUpdated
beforeDestroy
->onBeforeUnmount
destroyed
->onUnmounted
所有的函数都需要先导入,然后再setup中书写
其中vue-compisition-api
是Vue团队开发的RFC,供开发者提前体验 vue 3.0 的新特性。
使用前需要先安装composition-api
import { onMounted, onUpdated, onUnmounted } from '@vue/composition-api'
const MyComponent = {
setup() {
onMounted(() => {
console.log('mounted!')
})
onUpdated(() => {
console.log('updated!')
})
onUnmounted(() => {
console.log('unmounted!')
})
}
}