Vue 生命周期 钩子函数 Axios的使用 $ref和$next 的使用

一、Vue生命周期

生命周期是什么?

lifecycle.png

 

二、钩子函数 

Vue框架内置函数,随着组件的生命周期阶段,自动执行!
场景:组件创建完毕后,可以在created生命周期函数中发起Ajax请求,从而初始化data数据

分为 四大阶段 8个方法

例如 before Create 初始化之前 created 初始化之后

阶段

方法名  

方法名

初始化

beforeCreate 初始化之前

created 初始化之后

挂载

beforeMount 

mounted

更新

beforeUpdate

updated

销毁

beforeDestroy

destroyed

1、如何知道Vue生命周期到达了什么阶段?

使用钩子函数

2、钩子函数有哪些?

初始化 / 挂载 / 更新 / 销毁

对应的方法有哪些

初始化 beforeCreate created

挂载  beforeMount mounted

更新 beforeUpdate updated

销毁 befoteDestroy destroyed

三、四大阶段

重点:

①new Vue() vue实例化组件

②Init Events & Lifecycle 初始化事件 和 生命周期函数

③beforeCreate 生命周期枸杞函数被执行

④created 生命周期钩子函数被执行

⑤Init injections&reactivity - Vue内部添加data 和 methods 等

⑥has el  opition? 是否有 el 选项 检查挂载到哪里

没有 调用 $mount()方法

有 继续检查template选项

3.1初始化 beforeCreate() 和 created初始化之后

 


<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("created -- 执行");
        console.log(this.msg); // hello, Vue

        this.timer = setInterval(() => {
            console.log("哈哈哈");  //所有函数执行完了再执行
        }, 1000)
    }
}
</script>

Vue实例从创建到编译模板执行了那些钩子函数?

beforeCreate/created

created 函数触发能获取到data?

能获取到data 但是不能获取真实的DOM

3.2挂载阶段 beforeMount 挂载之前 mounted 挂载之后

①template选项检查

有 - 编译template返回render渲染函数

无 – 编译el选项对应标签作为template(要渲染的模板)

②.虚拟DOM挂载成真实DOM之前

③.beforeMount – 生命周期钩子函数被执行

④.Create … – 把虚拟DOM和渲染的数据一并挂到真实DOM上

⑤.真实DOM挂载完毕

⑥.mounted – 生命周期钩子函数被执行

 


<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("created -- 执行");
        console.log(this.msg); // hello, Vue

        this.timer = setInterval(() => {
            console.log("哈哈哈");
        }, 1000)
    }
}
</script>

在Vue实例从创建到显示都经历了那些钩子函数?

beforeCreate / created / before Mount / mounted

在 ceated 函数里面 能获取真实的DOM吗?

不能获取真实的DOM

在什么钩子函数可以获取真实的DOM

mounted

3.3更新阶段

①当data里数据改变,更新DOM之前

②beforeUpdate 生命周期钩子函数被执行

③Virtual DOM .... 虚拟DOM 重新渲染 打补丁到真实DOM

④updated - 生命周期钩子函数被执行

⑤当有data数据改变 - 重复这个循环

 准备ul+li循环, 按钮添加元素, 触发data改变->导致更新周期开始

<template>
  <div>
      <p>学习生命周期 - 看控制台打印</p>
      <p id="myP">{{ msg }}</p>
      <ul id="myUL">
          <li v-for="(val, index) in arr" :key="index">
              {{ val }}
          </li>
      </ul>
      <button @click="arr.push(1000)">点击末尾加值</button>
  </div>
</template>

<script>
export default {
    data(){
        return {
            msg: "hello, Vue",
            arr: [5, 8, 2, 1]
        }
    },
    // ...省略其他代码

    // 三. 更新
    // 前提: data数据改变才执行
    // 更新之前
    beforeUpdate(){
        console.log("beforeUpdate -- 执行");
        console.log(document.querySelectorAll("#myUL>li")[4]); // undefined
    },
    // 更新之后
    // 场景: 获取更新后的真实DOM
    updated(){
        console.log("updated -- 执行");
        console.log(document.querySelectorAll("#myUL>li")[4]); // li
    }
}
</script>

什么时候执行updated 钩子函数

当数据发生变化 并更新页面后。

在哪里可以获取到更新后的DOM

在updated钩子函数里

3.4销毁阶段 beforeDestroy destroy 

重点

①.当$destroy()被调用 – 比如组件DOM被移除(例v-if)

②.beforeDestroy – 生命周期钩子函数被执行

③.拆卸数据监视器、子组件和事件侦听器

④.实例销毁后, 最后触发一个钩子函数

⑤.destroyed – 生命周期钩子函数被执行

<script>
export default {
    // ...省略其他代码
    
    // 四. 销毁
    // 前提: v-if="false" 销毁Vue实例
    // 场景: 移除全局事件, 移除当前组件, 计时器, 定时器, eventBus移除事件$off方法
    beforeDestroy(){
        // console.log('beforeDestroy -- 执行');
        clearInterval(this.timer) // 哈哈输出结束
    },
    destroyed(){
        // console.log("destroyed -- 执行");
    }
}
</script>
<Life v-if="show"></Life>
<button @click="show = false">销毁组件</button>

<script>
    data(){
        return {
            show: true
        }
    },
</script>

小结:

一般在beforeDestroy / destroyed 里做什么?

手动消除计时器  / 定时器/ 全局事件 

四、axios基本使用 -发布书籍 案例

axios 是一个专门用于发送ajax请求的库

1、官网: axios中文网|axios API 中文文档 | axios
2、特点
支持客户端发送Ajax请求
支持服务端Node.js发送请求
支持Promise相关用法
支持请求和响应的拦截器功能
自动转换JSON数据

axios 底层还是原生js实现, 内部通过Promise封装的

小结

1、什么是ajax?

一种前端异步请求后端的技术

2、ajax原理?

浏览器window接口的XMLHttpRequest

3、axios是什么?

基于原生ajax+Promise技术封装通用于前后端的请求库

案例:

获取所有图书信息

功能: 点击调用后台接口, 拿到所有数据 – 打印到控制台
接口: 参考预习资料.md – 接口文档
引入: 下载axios, 引入后才能使用

<template>
  <div>
    <div> Axios的使用 </div>
    <div>
      书名:<input type="text" v-model="bookname" /> <br />
      作者:<input type="text" v-model="author" /><br />
      出版社:<input type="text" v-model="publisher" /><br />
      <button @click="submitBook()">提交图书</button>
    </div>
  </div>
</template>
<script>
//1、下载包npm install axios
//2、引入包import 变量 from "包名"
//3、使用axios
///api/getbooks
import axios from 'axios';
export default {
  data() {
    return {
      bookname: '', //书名
      author: '', //作者
      publisher: '', //出版社
      id: 189
    };
  },
  async created() {
    //axios.get(url,参数)
    //axios原地会返回一个promise,也就是可以通过then和catch来捕获成功和失败的结果
    //配置请求的基地址(接口请求的地址都是统一的,一个项目里面会有多个接口请求,所以统一地址统一配置)
    axios.defaults.baseURL = 'http://ajax-api.itheima.net';
    //不带参数的 get请求
    // axios
    //   .get('/api/books')
    //   .then(res => {
    //     console.log(res);
    //   })
    //   .catch(() => {});

    try {
      //异步的请求会有返回值
      //async和awsit一块使用
      let data = await axios.get('/api/books');
      console.log(data);
    } catch (error) {
      console.log(error);
    }

    //不带参数的 get请求
    //直接使用axios方法,传入配置对象(url,请求方式,请求参数,、、、)
    axios({
      url: '/api/books',
      method: 'get'
    }).then(res => {
      console.log(res);
    });

    //带参数的 get请求
    axios({
      // url: `/api/books/${this.id}`,
      url: '/api/books/209',
      method: 'get'
    }).then(res => {
      console.log(res);
    });
  },

  methods: {
    async submitBook() {
      // 带参数的 post请求
      // axios({
      //   url: '/api/books',
      //   method: 'post',
      //   data: {
      //     //过去的写法,拿input的值,元素.value
      //     bookname: this.bookname,
      //     author: this.author,
      //     publisher: this.publisher
      //   }
      // }).then(res => {
      //   console.log(res);
      // });
      try {
        let obj = {
          url: '/api/books',
          method: 'post',
          data: {
            //过去的写法,拿input的值,元素.value
            bookname: this.bookname,
            author: this.author,
            publisher: this.publisher
          }
        };
        let data = await axios(obj);
        console.log(data);
      } catch (error) {}
    }
  }
};
</script>
<style scoped></style>

小结

1、axios如何发起一次get请求?

在method选项配置为true / 也可以默认不写

2、axios函数调用原地结果是什么?

是一个Promise对象

3、如何拿到Promise里ajax的成功或失败的结果?

then() / catch()

五、$ref和$nextTick的使用

5.1$ref 获取原生dom元素

目前有两种获取方式 一个是通过ID 另一个通过ref 属性获取

真实的dom只有在 mounted 挂载之后才能获取到

①目标标签 - 添加 id / ref 

②通过 id、ref属性获取

什么时候 用ref 什么时候用refs?

单个标签的时候使用 ref

多个标签的时候使用refs

<h1 id="h" ref="myH">获取原生</h1>
  <h1 id="h2" ref="myHs">获取原生dom</h1>
mounted(){

    console.log(document.getElementByID("h"))//h1
    console.log(this.$refs)//myH myHS
   console.log(this.$refs.myH); //myH
   console.log(this.$refs.myHs); //myHs
}

5.1.1ref 组件对象

通过ref属性获取组件对象

1、创建Demo组件, 写一个方法

2、App.vue使用Demo组件, 给ref属性-名字随意

3、恰当时机, 通过ref属性 获取组件对象, 可调用组件对象里方法等

路径:components/Child/Demo.vue

<template>
  <div>
      <p>我是Demo组件</p>
  </div>
</template>
<script>
export default {
    methods: {
        fn(){
            console.log("demo组件内的方法被调用了");
        }
    }
}
</script>

 More.vue - 获取组件对象 - 调用组件方法

<template>
  <div>
      <p>1. 获取原生DOM元素</p>
      <h1 id="h" ref="myH">我是一个孤独可怜又能吃的h1</h1>
      <p>2. 获取组件对象 - 可调用组件内一切</p>
      <Demo ref="de"></Demo>
  </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
    }
}
</script>

小结

1、如何获取组件对象呢?

目标组件添加ref属性

this.$refs.名字 获取组件对象

2、拿到组件对象能做什么?

调用组件里的属性/方法

 5.2nextTick基础使用

目标:点击改data,获取原生DOM内容

1、创建标签显示数据

2、点击+1,马上获取原生DOM内容

原因: Vue更新DOM是异步的

目标:等DOM更新后, 触发此方法里函数体执行

1、语法: this.$nextTick(函数体)

<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: {
        ///写法1
        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
            })
        }
        ///写法2 通过 async await promis 函数的异步同步
        async btn(){
            this.count++; // vue监测数据更新, 开启一个DOM更新队列(异步任务)
            console.log(this.$refs.myP.innerHTML); // 0

   
             await this.$nextTick()
              this.$refs.myP.innerHTML
        }
    }
}
</script>

5.3nextTick使用场景

点击按钮自身隐藏, 出现输入框并马上处于激活状态

效果演示:

<template>
  <div>
      <input ref="myInp" type="text" placeholder="这是一个输入框" v-if="isShow">
      <button v-else @click="btn">点击我进行搜索</button>
  </div>
</template>

<script>
// 目标: 点按钮(消失) - 输入框出现并聚焦
// 1. 获取到输入框
// 2. 输入框调用事件方法focus()达到聚焦行为
export default {
    data(){
        return {
            isShow: false
        }
    },
    methods: {
        async btn(){
            this.isShow = true;
            // this.$refs.myInp.focus()
            // 原因: data变化更新DOM是异步的
            // 输入框还没有挂载到真实DOM上
            // 解决:
            // this.$nextTick(() => {
            //     this.$refs.myInp.focus()
            // })
            // 扩展: await取代回调函数
            // $nextTick()原地返回Promise对象
            await this.$nextTick()
            this.$refs.myInp.focus()
        }
    }
}
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值