目录
一、钩子函数
Vue 框架内置函数,随着组件的生命周期阶段,自动执行
⚫ 作用: 特定的时间点,执行特定的操作
⚫ 场景: 组件创建完毕后,可以在created 生命周期函数中发起Ajax 请求,从而初始化 data 数
⚫ 分类: 4大阶段8个方法
1.钩子函数-初始化阶段
⚫beforeCreate():new Vue()之后,vue内部给实例对象添加了一些属性和方法,data和methods初始化之前
⚫create():data和methods初始化之后
使用场景:网络请求,注册全局事件:页面滚动
<template>
<div>
<p>学习生命周期 - 看控制台打印</p>
<p>{{ msg }}</p>
</div>
</template>
<script>
export default {
data() {
return {
msg: "hello vue",
};
},
// 一、初始化
// new Vue()之后,vue内部给实例对象添加了一些属性和方法,data和methods初始化之前
beforeCreate() {
console.log("beforeCreate --- 执行");
console.log(this.msg); //undefined
},
//data和methods初始化之后
//使用场景:网络请求,注册全局事件:页面滚动
created() {
console.log("create --- 执行");
console.log(this.msg); //hello vue
},
methods: {},
};
</script>
<style lang="scss" scoped></style>
2.钩子函数-挂载阶段
⚫beforeMount()挂载 真实DOM挂载之前,拿不到真实DOM
场景:预处理data,不会触发updated钩子函数
⚫mounted() 真实DOM挂载之后,拿到真实DOM
场景:挂载后真是DOM
beforeMount() {
console.log("beforeMounte --- 执行");
// console.log(document.getElementById("myP")); //null
},
mounted() {
console.log("mounted --- 执行");
// console.log(document.getElementById("myP")); //<p data-v-07b77a01 id="myP">hello vue</p>
},
3.钩子函数-更新阶段
⚫beforeUpdate()当data里数据改变, 更新DOM之前
⚫updated()当数据发生变化并更新页面后,获取最新的真实DOM
<template>
<div>
<ul id="myUL">
<li v-for="(val, index) in arr" :key="index">{{ val }}</li>
</ul>
<button @click="arr.push(100)">数组添加末尾值</button>
</div>
</template>
<script>
export default {
data() {
return {
arr: [1, 2, 3, 4],
};
},
beforeUpdate() {
console.log("beforeUpate -- 执行"); //第一次点击button按钮,此语句执行,但是获取不到第四个li
console.log(document.querySelectorAll("#myUL>li")[4]); //undefined
},
updated() {
console.log("updated -- 执行"); //第一次点击button按钮,此语句执行,获取第四个li
console.log(document.querySelectorAll("#myUL>li")[4]); //<li data-v-07b77a01="">100</li>
},
};
</script>
4.钩子函数-销毁阶段
⚫前提:v-if="false" 销毁Vue实例
⚫场景:移除全局事件,移除当前组件的计时器、定时器(因为即使当前组件被销毁,定时器仍然会一直执行)、eventBus移除事件$off方法
<template>
<div>
<life v-if="show"></life>
<button @click="show = false">销毁</button>
</div>
</template>
<script>
export default {
data() {
return {
timer: "",
};
},
beforeDestroy() {
console.log(" beforeDestroy -- 执行");
clearInterval(this.timer)//销毁life后将不再执行定时器
},
destroyed() {
console.log(" destroyed -- 执行");
},
};
</script>
5.常用的钩子函数
⚫created可以在此阶段获取data中的数据以及发送接口请求
⚫mounted在此阶段获取DOM元素,echars图标
⚫beforeDestroy在此阶段移除页面定时器和事件监听
二、axios
1.请求数据
使用async-awiat
<template>
<div>
<div>
<h1>获取图书数据</h1>
<button @click.prevent="getBooks">点击获取</button>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {};
},
methods: {
async getBooks() {
// axios({
// url: "http://liulongbin.top:3006/api/getbooks",
// // methods:"get"
// }).then(res=>{
// console.log(res);
// });
const res = await axios({
url: "http://liulongbin.top:3006/api/getbooks",
})
console.log(res);
},
},
};
</script>
<style lang="scss" scoped></style>
2.查询数据
<template>
<div>
<div>
<h1>2-查询某本书的信息</h1>
<input type="text" placeholder="请输入书名" v-model="bName" />
<button @click="findFn">查询</button>
</div>
</div>
</template>
export default {
methods: {
async findFn() {
const res = await axios({
url: "/api/getbooks",
params: {
bookname: this.bName,
},
});
console.log(res);
},
};
</script>
3.配置全局基地址
import axios from "axios";
axios.defaults.baseURL = "基地址";
import axios from "axios";
axios.defaults.baseURL = "http://liulongbin.top:3006";
export default {
methods: {
async getBooks() {
// axios({
// url: "http://liulongbin.top:3006/api/getbooks",
// // methods:"get"
// }).then(res=>{
// console.log(res);
// });
const res = await axios({
url: "/api/getbooks",
});
console.log(res);
},
},
};
</script>
三、组件进阶
1.$refs
子组件
<template>
<div>
<h1 ref="myH">这是一个P标签</h1>
</div>
</template>
<script>
export default {
data() {
return {
num:1
};
},
methods: {
fn(){
console.log("子组件的方法被调用");
}
},
};
</script>
父组件
<template>
<div>
<child ref="myChild"></child>
</div>
</template>
<script>
import child from "./components/child.vue";
export default {
components: {
child,
},
mounted() {
this.$refs.myChild.fn();
console.log(this.$refs.myChild.num);
},
};
</script>
控制台打印
2.$refs
<template>
<div>
<div>
<h1>6-vue更新DOM是异步的</h1>
<p ref="c">{{ count }}</p>
<button @click="add">点击count++</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
};
},
methods: {
add() {
this.count++; //vue检测数据更新是异步的,开启一个DOM更新队列(异步任务)
console.log(this.$refs.c.innerHTML);//第一次点击为0
},
},
};
</script>
原因:vue更新DOM是异步的
解决:await this.$nextTick();
过程:DOM更新完会依次触发$nextTick里的函数体
方法一
this.$nextTick(() => console.log(this.$refs.c.innerHTML)); //第一次点击为1
方法二
methods: {
async clickFn() {
this.count++;
await this.$nextTick();
console.log(this.$refs.myP.innerHTML);
},
},
3. refs案例---输入框聚焦
<template>
<div>
<input type="text" placeholder="输入框" v-if="show" ref="myInp" />
<button v-else @click="btn">点击搜索</button>
</div>
</template>
<script>
// 需求:点击按钮输入框显示并聚焦,按钮隐藏
export default {
data() {
return {
show: false,
};
},
methods: {
async btn() {
this.show = true;
// this.$refs.myInp.focus() 报错
// 原因:data变化更新DOM是异步的
// 输入框还没有挂载到真实DOM上
// 解决:
// 方法一
// this.$nextTick(() => {
// this.$refs.myInp.focus();
// });
// 方法二
await this.$nextTick();
this.$refs.myInp.focus();
},
},
};
</script>
<style lang="scss" scoped></style>