Vue_生命周期
目标: Vue 框架内置函数,随着组件的生命周期阶段,自动执行
作用: 特定的时间点,执行特定的操作
场景: 组件创建完毕后,可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数据
分类: 4大阶段8个方法
阶段 | 方法名 | 方法名 |
---|
初始化 | beforeCreate 获取完成vue自己的方法和属性,如$on。$emit等;初始化vue的一些方法和属性访问不到data中的数据 | created 初始化完成当前组件的数据,如data中的数据methods中的数据等 | 挂载 | beforeMount 把模板里面的东西转化成虚拟dom,并没有挂载在页面,不能获取操作页面上的真实操作 | mounted 把虚拟dom转化为真实dom渲染到页面上 | 更新 | beforeUpdate 数据发生改变的时候执行,还拿不到更新的之后的dom | updated 页面更新完成,可以拿到更新后的dom | 销毁 | beforeDestroy 移除全局事件, 移除当前组件, 计时器, 定时器, eventBus移除事件$off方法; | destroyed 生命周期钩子函数被执行 |
export default {
//初始化vue的一些方法和属性访问不到data中的数据
beforeCreate() {
console.log(this.$on)
console.log('name', this.name)
},
//初始化组件中的datamethods等中的数据可以访问data相关数据
created() {
console.log('name', this.name)
this.timer = setTimeout(() => {
console.log('11')
}, 100)
},
//把模板转化为虚拟dom不能获取操作页面上的真实操作
beforeMount() {
console.log(document.getElementById('life'))
},
//把虚拟dom转化为真实dom渲染到页面上
mounted() {
console.log('mounted', document.getElementById('life'))
},
//页面还没更新
beforeUpdate() {
console.log('数据发生改变的时候执行,拿不到更新的之后的dom')
console.log(document.querySelector('h2').innerHTML)
},
//页面更新完成,可以拿到更新后的dom
updated() {
console.log('页面更新完成')
console.log(document.querySelector('h2').innerHTML)
},
//销毁之前
beforeDestroy() {
console.log('beforeDestroy')
clearTimeout(this.timer)
bus.$off('haside') //解绑eventbus
},
destroyed() {
console.log('destroyed')
},
data() {
return {
name: 'ls',
}
},
}
axios基本使用
axios文档:(http://www.axios-js.com/)
在使用之前需要下载axios包:yarn add axios
特点
基本使用语法:
axios({ ? method: '请求方式', // get post ? url: '请求地址', ? data: { ? ?// 拼接到请求体的参数, ?post请求的参数 ? ? xxx: xxx, ? }, ? params: { ?// 拼接到请求行的参数, get请求的参数 ? ??? ?xxx: xxx? ? } }).then(res => { ? console.log(res.data) // 后台返回的结果 }).catch(err => { ? console.log(err) // 后台报错返回 })
axios基本使用-传参
功能: 点击新增按钮, 把用户输入的书籍信息, 传递给后台 – 把结果打印在控制台
<script>
import axios from "axios";
export default {
data() {
return {
bName: "",
bookObj: { // 参数名提前和后台的参数名对上-发送请求就不用再次对接了
bookname: "",
author: "",
publisher: ""
}
};
},
methods: {
// ...省略了其他代码
sendFn(){
axios({
url: "/api/addbook",
method: "POST",
data: {
appkey: "7250d3eb-18e1-41bc-8bb2-11483665535a",
...this.bookObj
// 等同于下面
// bookname: this.bookObj.bookname,
// author: this.bookObj.author,
// publisher: this.bookObj.publisher
}
})
}
},
};
</script>
axios基本使用-全局配置
目标: 避免前缀基地址, 暴露在逻辑页面里, 统一设置
axios.defaults.baseURL = "http://123.57.109.30:3006"
// 所有请求的url前置可以去掉, 请求时, axios会自动拼接baseURL的地址在前面
getAllFn() {
axios({
url: "/api/getbooks",
method: "GET", // 默认就是GET方式请求, 可以省略不写
}).then((res) => {
console.log(res);
});
// axios()-原地得到Promise对象
},
$refs-获取DOM
目标: 利用 ref 和 $refs 可以用于获取 dom 元素 ,获取组件
<template>
<div>
<!-- ref和$refs获取dom元素 打印的是一个对象-->
<p>1、获取元素</p>
<h1 id="life" ref="harry">如果不是你就是我</h1>
<p>2、获取组件</p>
<demo ref="de"></demo>
<p>3、 vue更新DOM是异步的</p>
<h3 ref="txt">{{ txt }}</h3>
<button @click="change">改变</button>
<tick></tick>
</div>
</template>
<script>
import tick from './Tick.vue'
import demo from './Demo.vue'
export default {
components: { demo, tick },
mounted() {
//原生
console.log(document.getElementById('life'))
//vue的方法,打印的是一个对象
console.log(this.$refs)
console.log(this.$refs.harry)
console.log(this.$refs.de)
console.log(this.$refs.de.btn())
},
data() {
return {
txt: '111111',
}
},
methods: {
change() {
this.txt = '222'
this.$nextTick(() => {
// vue更新dom是异步的,我们更新data里面的数据并不能立马获取到
// 可以通过$nextTick解决
// 回调函数会在页面更新之后执行
console.log(this.$refs.txt.innerHTML)
})
},
},
总结: ref定义值, 通过$refs.值 来获取组件对象, 就能继续调用组件内的变量
$nextTick使用
Vue更新DOM-异步的
目标: 点击count++, 马上通过"原生DOM"拿标签内容, 无法拿到新值
<template>
<div>
<p>1. 获取原生DOM元素</p>
<h1 id="h" ref="myH">我是一个孤独可怜又能吃的h1</h1>
<p>2. 获取组件对象 - 可调用组件内一切</p>
<Demo ref="de"></Demo>
<p>3. vue更新DOM是异步的</p>
<p ref="myP">{{ count }}</p>
<button @click="btn">点击count+1, 马上提取p标签内容</button>
</div>
</template>
<script>
// 目标: 获取组件对象
// 1. 创建组件/引入组件/注册组件/使用组件
// 2. 组件起别名ref
// 3. 恰当时机, 获取组件对象
import Demo from './Child/Demo'
export default {
mounted(){
console.log(document.getElementById("h")); // h1
console.log(this.$refs.myH); // h1
let demoObj = this.$refs.de;
demoObj.fn()
},
components: {
Demo
},
data(){
return {
count: 0
}
},
methods: {
btn(){
this.count++; // vue监测数据更新, 开启一个DOM更新队列(异步任务)
console.log(this.$refs.myP.innerHTML); // 0
// 原因: Vue更新DOM异步
// 解决: this.$nextTick()
// 过程: DOM更新完会挨个触发$nextTick里的函数体
this.$nextTick(() => {
console.log(this.$refs.myP.innerHTML); // 1
})
}
}
}
</script>
总结:$nextTick可以解决在created阶段渲染dom
组件name属性使用
目标: 可以用组件的name属性值, 来注册组件名字
?components/Com.vue
<template>
<div>
<p>我是一个Com组件</p>
</div>
</template>
<script>
export default {
name: "ComNameHaHa" // 注册时可以定义自己的名字
}
</script>
App.vue - 注册和使用
<template>
<div>
<h1>1. 生命周期</h1>
<Life v-if="show"></Life>
<button @click="show = false">销毁组件</button>
<h1>组件对象里name属性</h1>
<ComNameHaHa></ComNameHaHa>
</div>
</template>
<script>
import Life from './components/Life'
import Com from './components/Com'
export default {
data(){
return {
show: true
}
},
components: {
Life,
[Com.name]: Com // 对象里的key是变量的话[]属性名表达式
// "ComNameHaHa": Com
}
}
</script>
相关面试题
1、Vue 的 nextTick 的原理是什么?
- 为什么需要 nextTick ,Vue 是异步修改 DOM 的并且不鼓励开发者直接接触 DOM,但有时候业务需要必须对数据更改--刷新后的 DOM 做相应的处理,这时候就可以使用 Vue.nextTick(callback)这个 api 了。
- 理解原理前的准备 首先需要知道事件循环中宏任务和微任务这两个概念,常见的宏任务有 script, setTimeout, setInterval, setImmediate, I/O, UI rendering 常见的微任务有 process.nextTick(Nodejs),Promise.then(), MutationObserver;
- 理解 nextTick 的原理正是 vue 通过异步队列控制 DOM 更新和 nextTick 回调函数先后执行的方式。如果大家看过这部分的源码,会发现其中做了很多 isNative()的判断,因为这里还存在兼容性优雅降级的问题。可见 Vue 开发团队的深思熟虑,对性能的良苦用心。
2、vue生命周期总共分为几个阶段?(必会)
Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
1)beforeCreate
在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
2)created
在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer), 属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
3)beforeMount
在挂载开始之前被调用:相关的 render 函数首次被调用。
4)mounted
el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
5)beforeUpdate
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
6)updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
7)activated
keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用。
8)deactivated
keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用。
9)beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。
10)destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
11)errorCaptured(2.5.0+ 新增)
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
3、第一次加载页面会触发哪几个钩子函数?(必会)
当页面第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子函数
|