Vue3.0----组件高级【上】(第四章)

一、watch 侦听器

1. 什么是 watch 侦听器

watch 侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。例如,监视用户名的变化并发 起请求,判断用户名是否可用。

2. watch 侦听器的基本语法

开发者需要在 watch 节点下,定义自己的侦听器。实例代码如下:

export default {
  data() {
       return { 
          username: ''
         }
     },
watch: {
//监听username的值的变化,
//形参列表中,第一个值是“变化后的新值”,第二个值是“变化之前的旧值”
  username(newval,oldval) {
       console.log(newVal,oldVal)
           },
    },
}

3. 使用 watch 检测用户名是否可用

监听 username值的变化,并使用 axios 发起 Ajax 请求,检测当前输入的用户名是否可用:

import axios from 'axios'
export default {
 data() {
     return { 
       username: " "
       }
},
watch: {
    async username(newVal,oldVal) {
        const { data: res } = await axios.get( `https: / /www.escook.cn/api/finduser/$ {newVal} `)
   console.log(res)
      },
},

4. immediate 选项

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器立即被调用,则需要使用immediate选项。实例代码如下:

watch: {
 // 1.监听username值的变化username: {
//  2. handler属性是固定写法:当username变化是,调用handlerasync 
handler(newVal,oldVal) {
const { data: res } = await axios.get(`https:/ /ww.escook.cn/api/finduserl${newNal}`)
      console.log(res)
     },
//  3.表示组件加载完毕后立即调用一次当前的watch侦听器immediate: true
},

5. deep 选项

当watch 侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用deep 选项,代码示例如下:

data() {
  return {
    info: { username: 'admin' }, // info 中包含username属性
   }
 },
watch: {
   info: {     //直接监听info对象的变化async 
      handler(newVal,oldVal) {
        const { data: res } = await axios.get(`https://ww.escook.cn/api/finduser/${newVal.username} `)
      console.log(res)
},
deep: true  //需要使用deep 选项,否则username值的变化无法被监听到},

6. 监听对象单个属性的变化

如果只想监听对象中单个属性的变化,则可以按照如下的方式定义 watch 侦听器:

data() {
   return {
      info: { username: 'admin ', password: '' },   // info 中包含username属性
},

watch: {
      'info.username ' : {    //只想监听info.username属性值的变化async 
       handler(newVal,oldVal) {
        const { data: res } = await axios.get(`https: / /ww.escook.cn/api/finduser /${newNal} `)
        console.log(res)
    },
},

7. 计算属性 vs 侦听器

计算属性和侦听器侧重的应用场景不同:

计算属性侧重于监听多个值的变化,最终计算并返回一个新值

侦听器侧重于监听单个数据的变化,最终执行特定的业务处理,不需要有任何返回值

二、组件的生命周期

1. 组件运行的过程

 组件的生命周期指的是:组件从创建-> 运行(渲染) -> 销毁的整个过程,强调的是一个时间段。

2. 如何监听组件的不同时刻

vue 框架为组件内置了不同时刻的生命周期函数,生命周期函数会伴随着组件的运行而自动调用。例如:

①当组件在内存中被创建完毕之后,会自动调用created函数

②当组件被成功的渲染到页面上之后,会自动调用mounted函数

③当组件被销毁完毕之后,会自动调用unmounted函数

 3. 如何监听组件的更新

当组件的data 数据更新之后,vue 会自动重新渲染组件的 DOM 结构,从而保证View 视图展示的数据和Model 数据源保持一致。

当组件被重新渲染完毕之后,会自动调用updated生命周期函数。

4. 组件中主要的生命周期函数

注意:在实际开发中,created是最常用的生命周期函数!

5. 组件中全部的生命周期函数

疑问:为什么不在 beforeCreate 中发 ajax 请求初始数据?

6. 完整的生命周期图示

可以参考 vue 官方文档给出的“生命周期图示”,进一步理解组件生命周期执行的过程: https://www.vue3js.cn/docs/zh/guide/instance.html#生命周期图示

三、组件之间的数据共享

1. 组件之间的关系

在项目开发中,组件之间的关系分为如下 3 种:

① 父子关系

② 兄弟关系

③ 后代关系

 2. 父子组件之间的数据共享

父子组件之间的数据共享又分为:

①父 -> 子共享数据

②子 -> 父共享数据

③父<-> 子双向数据同步

2.1 父组件向子组件共享数据

父组件通过v-bind 属性绑定向子组件共享数据。同时,子组件需要使用props 接收数据。示例代码如下:

//父组件
<my-test-1 :msg="message": user="userinfo"></my-test-1>
data() {
return {
message: 'hello vue ' ,
userinfo: { name : 'zs', age: 20 },}
}

 2.2 子组件向父组件共享数据

 子组件通过自定义事件的方式向父组件共享数据。示例代码如下:

//子组件
export default {
emits: [ 'n1change'],     // 1.声明自定义事件
data() { 
    return { 
     n1:0 
 }
},
methods:{
      addN1() {
      this.n1++
      // 2.数据变化时,触发自定义的事件this.$emit( 'n1change ' , this.n1)},
         },
}

2.3 父子组件之间数据的双向同步

父组件在使用子组件期间,可以使用v-model 指令维护组件内外数据的双向同步:

 3. 兄弟组件之间的数据共享

兄弟组件之间实现数据共享的方案是EventBus。可以借助于第三方的包mitt 来创建eventBus 对象,从而实现兄弟组件之间的数据共享。示意图如下:

 3.1 安装 mitt 依赖包

在项目中运行如下的命令,安装 mitt 依赖包:

npm install [email protected]

3.2 创建公共的 EventBus 模块

在项目中创建公共的eventBus 模块如下:

// eventBus.js
//导入mitt包
import mitt from 'mitt'
//创建EventBus的实例对象
const bus = mitt()
//将EventBus的实例对象共享出去
export default bus

3.3 在数据接收方自定义事件

在数据接收方,调用bus.on('事件名称', 事件处理函数) 方法注册一个自定义事件。示例代码如下:

//导入eventBus.js 模块,得到共亭的bus 对象
import bus from './eventBus.js'
export default {
    data() {
      return { count: 0 }
   },
created() {
//调用bus.on()方法注册一个自定义事件,通过事件处理函数的形参接收数据
    bus.on( ' countChange ', (count) =>{
     this.count = count
   }
}

4. 后代关系组件之间的数据共享

后代关系组件之间共享数据,指的是父节点的组件向其子孙组件共享数据。此时组件之间的嵌套关系比较复杂,可以使用provide和inject实现后代关系组件之间的数据共享。

 4.1 父节点通过provide共享数据

父节点的组件可以通过provide 方法,对其子孙组件共享数据:

export default {

 data() {
   return {
     color: 'red' ll 1.定义"父组件“要向"子孙组件“共享的数据
   },
provide() { // 2. provide函数 return 的对象中,包含了"要向子孙组件共享的数据
return {
     color: this.color ,
    }
  },
}

4.2 子孙节点通过inject接收数据

子孙节点可以使用inject数组,接收父级节点向下共享的数据。示例代码如下:

<template>
    <h5>子孙组件--- {
   
   {color}}</h5>
</template>
<script>
export default {
//子孙组件,使用inject 接收父节点向下共享的 color 数据,并在页面上使用
inject: [ 'color'],
</script>

4.3 父节点对外共享响应式的数据

父节点使用 provide 向下共享数据时,可以结合computed 函数向下共享响应式的数据。示例代码如下:

import { computed } from 'vue'    // 1.从 vue中按需导入 computed 函数
export default {
 data() {
   return { color : 'red'}
  },
provide() {
    return {
      // 2.使用computed函数,可以把要共享的数据“包装为"响应式的数据
     color : computed(() =>this.color ),
    }
},

4.4 子孙节点使用响应式的数据

如果父级节点共享的是响应式的数据,则子孙节点必须以.value 的形式进行使用。示例代码如下:

<template>
<!--响应式的数据,必须以.value的形式进行使用-->
<h5>子孙组件--- {
   
   {color.value}}</h5>
</template>
<script>
export default {
//接收父节点向下共享的 color数据,并在页面上使用
inject: [ 'color' ],
}
</script>

5. vuex

vuex 是终极的组件之间的数据共享方案。在企业级的 vue 项目开发中,vuex 可以让组件之间的数据共享变得高效、清晰、且易于维护。

6. 总结

⚫父子关系

①父 -> 子属性绑定

②子 -> 父事件绑定

③父 子组件上的 v-model

⚫兄弟关系

④EventBus

⚫后代关系

⑤provide& inject

⚫全局数据共享

⑥vuex

四、vue 3.x 中全局配置 axios

1. 为什么要全局配置 axios

在实际项目开发中,几乎每个组件中都会用到 axios 发起数据请求。此时会遇到如下两个问题:

①每个组件中都需要导入 axios(代码臃肿)

②每次发请求都需要填写完整的请求路径(不利于后期的维护)

 2. 如何全局配置 axios

在main.js 入口文件中,通过app.config.globalProperties 全局挂载 axios,示例代码如下:

视频:

黑马程序员Vue全套视频教程,从vue2.0到vue3.0一套全覆盖,前端学习核心框架教程_哔哩哔哩_bilibili

此文章是本人学习视频自我总结,如有侵犯还望原谅。侵权必删。

猜你喜欢

转载自blog.csdn.net/QQ675396947/article/details/127486848
今日推荐