第二单元 methods,computed,watch,生命周期
二、本单元教学目标
(Ⅰ)重点知识目标
1. methods 写法注意事项
2. computed用法
3. methods,computed 区别
4. watch 和 computed 区别
5. 生命周期函数
二、本单元知识详讲
2.1 Methods选项
使用场景:
在开发中,我们经常需要用到函数, 通过将一些需要复用的逻辑封装在函数里,多次调用这个函数来增强逻辑代码复用性,在vue中,函数被定义在methods选项里来使用,定义完后就可以在vue 表达式中调用函数
2.2.1 基本用法
语法结构:
<!-- 1. 声明方法 -->
<script>
createApp({
data: {
return {}
},
methods: {
// 下面两种格式都能实现功能
方法一名:function(){
//逻辑代码
},
方法二(){
//逻辑代码
},
},
}).mount('#app')
</script>
<!-- 2. 调用方法 -->
<!-- 2.1 在vue实例中用this调用 -->
<script>
createApp({
data: {
return {}
},
methods: {
// 下面两种格式都能实现功能
方法一名:function(){
//逻辑代码
},
方法二(){
//逻辑代码
},
},
}).mount('#app')
</script>
<!-- 2.2 在标签中调用 -->
<标签 @click="方法一()"></标签>
特点:
- 为什么加s,因为可以定义多个方法
- methods选项的值:对象,对象中定义方法
- methods选项表示:当前Vue实例可以用到的方法
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="js/vue3.js"></script>
<style>
#app{
width: 600px;
margin: 30px auto;
}
</style>
</head>
<body>
<div id="app">
<button @click="showInfo(2)">单击1</button>
<button @click="showInfo2">单击2</button>
<span>{{msg}}</span>
</div>
<script>
Vue.createApp({
data: {
return {
msg: '初始值',
}
},
methods: {
// 下面两种格式都能实现功能
showInfo:function(){
this.msg = '点击1更改的内容'
},
showInfo2(){
this.msg = '点击2更改的内容'
},
},
}).mount('#app')
</script>
</body>
</html>
运行效果,如图:
2.2.2 注意事项
下面我们了解下定义Methods中的方法时,需要注意的有哪些:
- 在html中写入需要传递的值:
<button @click="showInfo(2)">单击1</button>
在方法里面接收:methods: { showInfo:function(num){ console.log('这是我接收到的数字:',num) this.msg = '点击1更改的内容' }}
控制台输出:> 这是我接收到的数字:2 - methods里的方法第二个参数$event:它传递的是关于鼠标的一些属性和方法
- methods里面的方法不能使用箭头函数代码演示:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title> <script src="js/vue3.js"></script> <style> #app{ width: 600px; margin: 30px auto; } </style></head><body> <div id="app"> <button @click="showInfo">单击1</button> <button @click="showInfo2">单击2</button></div> <script> Vue.createApp({ data: { return { msg: '初始值', } }, methods: { showInfo:function(){ console.log('this->',this) }, showInfo2:()=>{ console.log('箭头函数种得this->',this) }, }, }).mount('#app') </script></body></html>
打开控制台,运行效果,如图:结论:如上述做法,在methods里定义的函数showInfo2(),如果用箭头函数的写法,this指向的将会是windows,并且windows根本访问不到data,属性中返回的数据undefined,所以不可在methods选项中使用箭头函数
2.2 计算属性
Vue中的
computed
属性称为计算属性。
使用场景:
我们学习Vue的模板相关的知识的时候,知道在模板内可以使用表达式,这种表达式非常的便利,但这种便利是有一定的限制的,它们实际上是只适合用于一些简单的运算。也就是说,如果在模板中放入太多的逻辑会让模板过重而且难以维护,例如:
<div id="app"> <h1>{{ message.split('').reverse().join('') }}</h1> </div>
在这个示例中,模板不再简单和清晰。看到这段代码才能意识到,这里是想要显示变量
message
的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理,所以这就是我们使用计算属性的原因
语法结构:
<!-- 调用方式 -->
<div id="app">
<h1>{{ reverseString }}</h1>
</div>
<!-- 构建方式 -->
<script type="text/javascript">
Vue.createApp({
data: {
return {}
},
methods: {},
//computed 属性 定义 和 data 已经 methods 平级
computed: {
// reverseString 这个是我们自己定义的名字
reverseString(){
}
}
}).mount('#app')
</script>
reverseString
这个是我们自己定义的名字computed
属性 定义 和 data 已经methods
平级- 调用方式
{{ reverseString }}
。错误示范:{{ reverseString() }}
特点:
- 使用计算属性可以让模板更加的简洁
- 计算属性是基于它们的响应式依赖进行缓存的(与method方法的区别会详细讲解)
- computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是说多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化
代码演示:
实现字符串反转
<body>
<div id="app">
<h1>{{ reverseString }}</h1>
</div>
</div>
</body>
<script type="text/javascript">
Vue.createApp({
data: {
return {
message: 'Nihao',
num: 100
}
},
computed: {
reverseString(){
return this.message.split('').reverse().join('');
}
}
});
</script>
效果图:
2.2.1 计算属性中的set和get方法
特点:
- get:函数中的值被调用时启用该方法
- set:绑定的数据被修改后会启用
- get方法一般情况下,我们只是使用了computer中的gettter属性,默认只有 getter,例如:
<body> <div id="app"> <div class="hello"> <div id="example"> <!-- 1. 渲染fullName时会调用 fullName的get方法, 2. 控制台输出:调用了getter属性 --> <p>fullName值: {{fullName}}</p> </div> </div> </div></body><script> Vue.createApp({ data () { return { firstName: 'Foo' } }, computed: { // 注意格式,需要深刻理解 fullName: { get() { console.log('调用了getter属性') return '***' + this.firstName + '***' } } } }).mount('#app')</script>
说明:1. 渲染fullName时会调用 fullName的get方法2. 控制台输出:调用了getter属性3. 实际上就是我们通常使用的这种方法: computed: { reverseString: function(){ console.log('computed') var total = 0; return total; }
运行效果: - set方法
<body> <div id="app"> <div class="hello"> <!-- 点击后,调用fullName的set方法 --> <button @click="ClickCeshi">点击改变fullName的值</button> </div> </div></body><script> Vue.createApp({ data () { return { firstName: 'Foo' } }, methods: { ClickCeshi () { this.fullName = 'fullName的新值' } }, computed: { // 注意格式,需要深刻理解 fullName: { get () { console.log('调用了getter属性') return '***' + this.firstName + '***' }, set (newValue) { console.log('调用了settter属性') console.log(newValue) this.firstName = newValue } } } }).mount('#app');</script>
说明:点击后fullName的值改变,计算属性调用fullName的set方法,更新fullName的值运行结果,如图:
计算属性具有依赖性,只有当依赖的值发生改变,才会重新计算
同等条件下,计算属性优于 方法 以及 js表达式。
案例:模糊搜索
```vue
<div id="app">
<input type="text" v-model="keyword" />
<ul>
<li v-for="value in searchList">
<p>{{value}}</p>
</li>
</ul>
</div>
<script>
const { createApp } = Vue
createApp({
data() {
return {
keyword: '',
list: ['百度', '百度翻译', '百度地图', '百度网盘', '百度新闻', '新浪', '新闻', '新加坡']
}
},
computed: { //设置计算属性
searchList() {
if (this.keyword) {
return this.list.filter((value) => { //过滤数组元素
return value.includes(this.keyword); //如果包含字符返回true
});
}
}
}
}).mount('#app')
</script>
2.3 couputed 与 methods 的区别
- methods 和 computed 看起来都可以实现我们的功能,那么为什么还要多一个计算属性这个东西呢?
<body>
<div id="app">
<p>{{ name }}</p>
<!-- 每次渲染走到这里都是函数执行,即使这次渲染的数据跟我这个函数无关 -->
<p>{{ reversedMsg() }}</p>
</div>
</body>
<script>
const { createApp } = window.Vue
const app = createApp({
data() {
return {
msg: 'Hello',
name: 'shanshan'
}
},
methods: {
reversedMsg: function () {
console.log('方法执行啦');
return this.msg.split('').reverse().join('');
}
}
})
app.mount('#app')
</script>
vm.name = 'duyi';
// 看控制台 reversedMsg执行了2次
- 如果是计算属性,当给数据name重新赋值时,计算属性并不会执行。
computed 区别于 methods 的核心
在官方文档中,强调了computed 区别于 methods 最重要的两点:
- computed 是属性调用
{{computedTest}}
,而 methods 是函数调用{{methodTest()}}
- 方法是每次触发重新渲染,调用方法将总会再次执行函数。 - computed 带有缓存功能,而 methods 没有- 计算属性是基于响应式依赖进行缓存的,计算属性的值一直存于缓存中,只要它依赖的data数据不改变,每次访问计算属性,都会立刻返回缓存的结果,而不是再次执行函数。- 那么,为什么需要缓存呢?(好处)——节省性能开销
- 对于任何复杂逻辑,都应当使用计算属性
- computed 依赖于 data 中的数据,只有在它的相关依赖数据发生改变时才会重新求值
- computed如果要传参数 就需要在内部返回一个函数(利用闭包)
- 计算属性和方法重名时 方法权重高
**怎么给计算属性 传参数? 利用闭包 **
2.4 watch监听器
使用场景:数据变化时执行异步或开销比较大的操作。
2.4.1 定义:
- 侦听属性,响应数据(data&computed)的变化
- 是一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。
- 当监听的key数据变化时,会立刻执行对应的value
- watch 中的属性 一定是data 中 已经存在的数据
- 一般用于异步或者开销较大的操作
- 注意:也不可以使用箭头函数,同methods
Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。
2.4.2 语法类型:
函数、对象、字符串、数组
watch: {
key: value
}
当监听的key数据变化时,会立刻执行对应的value
2.4.3 函数类型
- 1、通过事件改变值
<body>
<div id="app">
<!-- 通过事件改变值 -->
<select @change="changeBrithday" v-model="year">
<option v-for="item in years" :value='item'>{{item}}</option>
</select>
<div>小明生日是{{year}},今年{{brithDay}}岁</div>
</div>
</body>
<script>
const { createApp } = Vue
const app = createApp({
data() {
return {
years: [1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000],
year: 1995,
brithDay: new Date().getFullYear() - 1995,
}
},
methods: {
changeBrithday() {
this.brithDay = new Date().getFullYear() - this.year
}
}
})
app.mount('#app')
</script>
- 2、通过watch配合 v-model 因为v-moel会动态改变data
<body>
<div id="app">
<select v-model="year">
<option v-for="item in years" :value='item'>{{item}}</option>
</select>
<div>小明生日是{{year}},今年{{brithDay}}岁</div>
</div>
</body>
<script>
const { createApp } = Vue
const app = createApp({
data() {
return {
years: [1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000],
year: 1995,
brithDay: new Date().getFullYear() - 1995,
}
},
watch: {
//侦听器函数,接收两个参数,第一个为newVal(被改变的数据),第二个为oldVal(赋值新值之前的值)。
year(newVal,oldVal){
console.log(newVal,oldVal);
this.brithDay=new Date().getFullYear()-this.year
}
},
})
app.mount('#app')
</script>
2.4.4 对象类型
- 写成对象类型时,为的是提供一些选项。
handler
- handler选项 ,一个函数, 被侦听的数据改变时执行的回调函数。必需。
- 其实就是上面写成函数形式的原型
- handler的值类型为函数/字符串,写成字符串时为一个方法的名字。
const { createApp } = Vue
const app = createApp({
data() {
return {
msg: '杉杉'
}
},
watch: {
msg: {
handler () {
console.log('msg的值改变啦');
}
}
}
})
vm.msg = 'hello'; // 此时回调函数会执行,控制台中打印出 ` msg的值改变啦 `
deep
- deep选项,布尔值。针对对象数据的侦听。
- 在默认情况下:- 侦听器侦听的数据是一个对象的话,只侦听这个对象引用的变化,只有在给对象重新赋值一个引用时它才能被监听到。- 这个对象数据内部的成员、内部对象成员里的成员,都是监听不到的。
- 所以需要使用deep选项:- 让其可以发现对象内部所有值的变化。- 默认是false,将deep的值设置为true,那么无论该对象被嵌套的有多深,都会被侦听到。
const { createApp } = Vue
const app = createApp({
data() {
return {
personObj: {
name: '小明',
age: 88
}
}
},
watch: {
personObj: {
handler () {
console.log('对象的值改变啦');
},
deep: true // 开启深度侦听
}
}
})
vm.obj.name = '明明很爱你'; // 此时回调函数会执行,控制台中打印出 ` 对象的值改变啦 `
- 注意,当对象的属性较多的时候,性能开销会比较大,因此没有必要给每一个深度属性都侦听,此时可以设置只监听对象的某个属性,这个可以用字符串类型的key解决。
immediate立即执行
- immediate选项,布尔值。
- 当页面第一次渲染时,数据只是添加侦听回调,并没有开启侦听。所以第一次渲染的时候侦听函数不会执行,只有后面数据变化才执行。
- 加上immediate选项后,回调将会在侦听开始之后立刻被调用。第一次渲染的时候就触发,而不是等待侦听的数据更改后才会调用。
const { createApp } = Vue
const app = createApp({
data() {
return {
msg: '杉杉'
}
},
watch: {
msg: {
handler () {
console.log('回调函数执行啦');
},
immediate: true
}
}
})
// 此时未更改msg的值,就会在控制台打印出来` 回调函数执行啦 `
flush回调的触发时机
当你更改了响应式状态,它可能会同时触发 Vue 组件更新和侦听器回调。
默认情况下,用户创建的侦听器回调,都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。
如果想在侦听器回调中能访问被 Vue 更新之后的 DOM,你需要指明
flush: 'post'
选项:
export default {
// ...
watch: {
key: {
handler() {},
flush: 'post'
}
}
}
2.4.5 字符串类型(了解)
- 其实就是把watch里面的方法抽离出来放到methods里
- watch里的值为方法methods中的名字,被侦听的数据改变时,会执行该方法。
const { createApp } = Vue
const app = createApp({
data() {
return {
msg: '杉杉'
}
},
watch: {
msg: 'msgChange'
},
methods: {
msgChange () {
console.log('msg的值改变啦');
}
}
})
vm.msg = 'hello'; // 此时msgChange函数会执行,控制台中打印出 ` msg的值改变啦 `
2.4.6 数组类型(了解)
- 可以将函数类型、字符串类型、对象类型等多种不同值类型写在一个数组中。如:
const { createApp } = Vue
const app = createApp({
data() {
return {
msg: '杉杉'
}
},
watch: {
msg: [
'msgChange', //字符串:函数名
function () {}, //函数
{//对象
handler () {},
deep: true,
immediate: true
}
]
}
})
2.4.7 字符串类型key值
- 当key值类型为字符串时,可以实现监听对象数据当中的某一个深层属性,如:
- 就不用开启深度侦听了
const { createApp } = Vue
const app = createApp({
data() {
return {
personObj: { name: '小明', age: 88 }
}
},
watch: {
'personObj.name' () {
console.log('对象的值改变啦');
}
}
})
vm.obj.name = '明明很爱你'; // 此时回调函数会执行,控制台中打印出 ` 对象的值改变啦 `
2.4.8 停止侦听器(了解)
用
watch
选项或者
$watch()
实例方法声明的侦听器,会在宿主组件卸载时自动停止。因此,在大多数场景下,你无需关心怎么停止它。
在少数情况下,你的确需要在组件卸载之前就停止一个侦听器,这时可以调用
$watch()
API 返回的函数:
js
const unwatch = this.$watch('foo', callback)
// ...当该侦听器不再需要时
unwatch()
2.4.9 watch 是异步的
const { createApp } = Vue
const app = createApp({
data() {
return {
msg: 'hello,你好呀,我是杉杉',
}
},
watch: {
msg () {
console.log('msg的值改变啦~');
}
},
methods: {
fn() {
console.log(1);
this.msg = 'hahaha';
console.log(2);
}
}
})
vm.fn(); // 1 2 msg的值改变啦
- 怎么让 console.log(2); 最后执行:利用
$nextTick
const { createApp } = Vue
const app = createApp({
data() {
return {
msg: 'hello,你好呀,我是杉杉',
}
},
watch: {
msg () {
console.log('msg的值改变啦~');
}
},
methods: {
fn() {
console.log(1);
this.msg = 'hahaha';
this.$nextTick(() => {//dom更新完成后才执行,$nextTick也是一个异步
console.log(2);
},0)
}
}
})
vm.fn(); // 1 msg的值改变啦 2
2.5 watch 与 computed的区别
- 两者都可以观察和响应Vue实例上的数据的变动。功能不同,计算属性用于解决模板语法冗余问题。侦听器侦听data中某一个数据变化1. 计算属性擅长处理的场景是:多个数据影响一个数据2. watch擅长处理的场景是:一个数据执行,一个函数影响多个数据。
- 计算属性有缓存机制,侦听器没有缓存机制
- 侦听器支持异步操作,计算属性不支持异步操作(即使写了异步会先return再执行异步)
- 计算属性可以给vue新增属性,侦听器必须是data中已有属性
- 计算属性只要使用了就会立即执行一次,侦听器默认只有当数据第一次调用才会执行
- 侦听器可以通过设置immerdiate为true,也可以像计算属性一样立即执行一次
// computed形式
const { createApp } = Vue
const app = createApp({
data() {
return {
firstName: 'su',
lastName: 'mei'
},
}
computed: {
fullName () {
return this.firstName + this.lastName;
}
}
})
// watch形式
const { createApp } = Vue
const app = createApp({
data() {
return {
firstName: 'su',
lastName: 'mei',
fullName: 'sumei'
}
},
watch: {//是不是麻烦一些
firtName () {
this.fullName = this.firstName + this.lastName;
},
lastName () {
this.fullName = this.firstName + this.lastName;
}
}
})
watch 只能监听data中的数据变化吗?
watch可以监听路由中的数据的变化
案例:图书购物车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<style>
.app .table,
.app .totalPrice {
width: 800px;
margin: 20px auto;
padding: 20px;
}
</style>
</head>
<body>
<div id="app">
<div v-if="books.length">
<table class="table table-hover">
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>书本价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in books" :key='index'>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<!-- <td>{{getFinallPrice(item.price)}}</td> -->
<td>{{item.price}}</td>
<td>
<button type="button" class="btn btn-default" @click="decrement(index)"
:disabled="item.count <=1">-</button>
<label>{{item.count}}</label>
<button type="button" class="btn btn-default" @click="increment(index)">+</button>
</td>
<td><button type="button" class="btn btn-warning" @click="removeClick(index)">移除</button></td>
</tr>
</tbody>
</table>
<h2 class="totalPrice">总价格:{{totalPrice}}</h2>
</div>
<h2 class="totalPrice" v-else>购物车为空!</h2>
</div>
<script src='https://unpkg.com/vue@3/dist/vue.global.js'></script>
<script>
const { createApp } = Vue
const app = createApp({
data() {
return {
books: [
{ id: 1001, name: '计算机操作原理', date: '2020-02-12', price: 108, count: 1 },
{ id: 1002, name: 'JavaScript高级程序设计', date: '2020-02-12', price: 99, count: 1 },
{ id: 1003, name: '计算机网络', date: '2020-02-12', price: 28, count: 1 },
{ id: 1004, name: '数据结构', date: '2020-02-12', price: 46, count: 1 },
{ id: 1005, name: 'C语言', date: '2020-02-12', price: 48, count: 1 }
]
}
},
methods: {
// 普通方法处理价格
getFinallPrice(price) {
return '¥' + price.toFixed(2)
},
increment(index) {
this.books[index].count++
},
decrement(index) {
this.books[index].count--
},
removeClick(index) {
this.books.splice(index, 1)
},
},
computed: {
totalPrice() {
let totalPrice = 0
// 方式一:普通for
// 方式二:for (let item of ...)
/* for (let item of this.books) {
totalPrice += item.price * item.count
} */
// 方式三:高阶函数reduce:汇总数组内的元素
this.books.reduce(function (preValue, book) {
totalPrice += book.price * book.count
}, 0)
return totalPrice
}
}
})
app.mount('#app')
</script>
</body>
</html>
2.6 Vue 的生命周期
学习:常见的8个生命周期钩子函数
vue2生命周期
每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM,在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,目的是给予用户在一些特定的场景下添加他们自己代码的机会。
Vue生命周期的主要阶段:4个before, 4个ed,创建,装载,更新,销毁
- 挂载(初始化相关属性)- beforeCreate ---- 备孕注意点:在此时不能获取data中的数据,也就是说 this.msg 得到的是- created ---- 怀上了- beforeMount ---- 怀胎十月- mounted【页面加载完毕的时候就是此时】 ---- 生下来了注意点:默认情况下,在组件的生命周期中只会触发一次
- 更新(元素或组件的变更操作)- beforeUpdate- updated注意点:可以重复触发的
- 销毁(销毁相关属性)- beforeDestroy --- game over前- destroyed --- game over
销毁(手动)使用 this.$destroy()
关于8个生命周期涉及到的方法,可以参考Vue官网API:
vue3生命周期
选项式API
中将
beforeDestroy
以及
destroyed
修改为
beforeUnmount
和
unmounted
,其余一致
生命周期钩子 | Vue.js
如果是vue2的生命周期钩子函数
完整案例:
16_lifeCycle_vue2.html
官方解释
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>13_vue2的v-if与v-for优先级</title>
</head>
<body>
<div id="app">
{{ count }}
<button @click="add">加1</button>
</div>
</body>
<script src="lib/vue.js"></script>
<script>
new Vue({
data: {
count: 10
},
methods: {
add () {
this.count++
if (this.count === 15) {
this.$destroy()
}
}
},
beforeCreate () {
console.log('beforeCreate')
},
created () {
// 有的人在此处请求数据,修改状态 ---- 不太建议 (请求数据-教育 - 胎教)
console.log('created')
},
beforeMount () {
console.log('beforeMount')
},
mounted () {
// 在此处请求数据 - (请求数据-教育 - 早教)
// DOM操作 (揍)
// 实例化 new Swiper('.container', {})
// 计时器,延时器等 (年龄从生下来才开始计算)
// 订阅
console.log('mounted')
},
beforeUpdate () {
console.log('beforeUpdate')
},
updated () {
// DOM操作
// 实例化
// 不要请求数据 - 死循环
console.log('updated')
},
beforeDestroy () {
// 消除定时器,延时器,取消订阅
console.log('beforeDestroy')
},
destroyed () {
console.log('destroyed')
}
}).$mount('#app')
</script>
</html>
15_lifeCycle_vue3.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>17_vue3生命周期</title>
</head>
<body>
<div id="app">
{{ count }}
<button @click="add">加1</button>
</div>
</body>
<script src="lib/vue.global.js"></script>
<script>
const app = Vue.createApp({
data () {
return {
count: 10
}
},
methods: {
add () {
this.count++
if (this.count === 15) {
app.unmount()
}
}
},
beforeCreate () {
console.log('beforeCreate')
},
created () {
// 有的人在此处请求数据,修改状态 ---- 不太建议 (请求数据-教育 - 胎教)
console.log('created')
},
beforeMount () {
console.log('beforeMount')
},
mounted () {
// 在此处请求数据 - (请求数据-教育 - 早教)
// DOM操作 (揍)
// 实例化 new Swiper('.container', {})
// 计时器,延时器等 (年龄从生下来才开始计算)
// 订阅
console.log('mounted')
},
beforeUpdate () {
console.log('beforeUpdate')
},
updated () {
// DOM操作
// 实例化
// 不要请求数据 - 死循环
console.log('updated')
},
beforeUnmount () {
// 消除定时器,延时器,取消订阅
console.log('beforeUnmount')
},
unmounted () {
console.log('unmounted')
}
})
app.mount('#app')
</script>
</html>
版权归原作者 m78星云第一深情 所有, 如有侵权,请联系我们删除。