【Vue】组件高级

news2024/9/22 3:56:00

文章目录

  • 组件高级
    • 一、watch 监听器
    • 二、组件的生命周期
      • 2.1 组件运行的过程
      • 2.2 监听组件的不同时刻
      • 2.3 监听组件的更新
      • 2.4 主要生命周期函数
    • 三、组件之间的数据共享
      • 3.1 组件关系及数据共享
      • 3.2 父子组件数据共享
      • 3.3 兄弟组件数据共享
      • 3.4 后代组件数据共享
      • 3.5 vuex
    • 四、全局配置 axios


组件高级


一、watch 监听器

1、监听器概念

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


2、基本语法

通过watch节点定义需要监听数据的函数,第一个参数是变化后的新值,第二个参数是变化之前的旧值:

<script>
export default{
	data(){
		return { username:''}
	},
	watch:{
		username(newVal,oldVal) {
			console.log(newVal, oldVal)
		}
	}
}
</script>

创建新的两个组件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WSqCLFoU-1687835106774)(null)]

在MyWatch组件中声明数据项 username,并添加监听器检测值的变化,在页面中新增输入框,双向绑定 username,并且使用trim过滤前后空格:

image-20230625102903657

我們設定初始 username 值为 admin,监听输入框中的数据值,每删除一个字符就会进行数据监听,控制台输出。


3、监测用户名是否可用

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

首先 npm install axios ,导入axios模块:

<script>
// 导入axios
import axios from 'axios'
    
export default {
  name: 'MyWatch',
  data() {
    return {
      username: 'admin',
    }
  },
  watch: {
   username(newVal,oldVal){
      // 解构:重命名
      async const { data:res} =await axios.get('https://www.escook.cn/api/finduser/${newVal}')
      console.log(res)
    }
  },
}
</script>

通过控制台可以看出res是 Promise 对象属性(异步),我们通过解构将data数据提取出来,并且使用 await 、async 修饰,async 是“异步”的简写,而 await 可以认为是 async wait 的简写。所以应该很好理解 async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。

image-20230625105621934

这部分服务器已经关闭了所以通过视屏讲解理解流程即可,最终效果类似是监听组件 username 的值,若为空则是用户名可用,若不为空存入第一次的值,此时用户名已被占用,再次修改用户名无效。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mzGV98M9-1687835106685)(null)]


4、默认情况下,组件在初次加载完毕后不会调用 watch 侦听器(如下图所示没有输出内容)。如果想让 watch 侦听器立即被调用,则需要使用 immediate 选项。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BHL9u654-1687835107388)(null)]

<script>
import axios from 'axios'

export default {
  name: 'MyWatch',
  data() {
    return {
      username: 'admin',
    }
  },
  watch: {
    async username(newVal, oldVal) {
      console.log("newVal:" + newVal, "oldVal" + oldVal)
      // 解构:重命名
      const {data:res} = axios.get("https://www.escook.cn/api/finduser/" + newVal)
      console.log(res)
    }
  },
  immediate:true // 组件加载完毕后立即调用一次当前的watch监听器
}
</script>

可以发现,程序一启动,控制台就输出了监听的信息:

image-20230625110713127


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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vIYuzzVp-1687835106961)(null)]

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

image-20230625111103234


6、计算属性 vs 侦听器

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

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

返回顶部


二、组件的生命周期

2.1 组件运行的过程

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

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Qe9ThXY-1687835094275)(C:%5CUsers%5C35192%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20230625184940054.png#pic_center)]

  • 官网解析

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dPVJbBG4-1687835106588)(null)]


2.2 监听组件的不同时刻

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bfBJBAQF-1687835094275)(C:%5CUsers%5C35192%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20230625185026743.png#pic_center)]

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

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

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

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

首先创建两个新的组件,并在 Vue 组件中将 LifeCycle 组件导入进去:

image-20230625190237556

当我们创建几个基础生命周期函数后,启动vite创建程序,在控制台会出现 created、mounted 的自动调用:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a3bZHF7C-1687835107088)(null)]

通过定义新的组件button,动态修改参数 flag 的值,从而动态的改变 lifr-cycle 组件的创建、渲染与销毁,可以看到默认组件显示,当我们点击按钮后,组件消失,即被销毁,调用对应的 unmounted 函数,控制台输出信息:

<template>
  <div>
    <h1>App 根组件</h1>
    <hr />
    <!-- 3. 以标签形式使用组件,v-if 当flag为true的时候显示该组件 -->
    <life-cycle v-if="flag"></life-cycle>
    <!-- 按钮点击事件动态改变组件的创建与销毁 -->
    <button @click="flag = !flag">Taggle</button>
  </div>
</template>

<script>
// 1. import 导入组件
import LifeCycle from './LifeCycle.vue'

export default {
  name: 'MyApp',
  data() {
    return {
      flag: true,
    }
  },
  // 2. components 注册组件
  components: {
    LifeCycle,
  },
}
</script>
<style lang="less" scoped></style>

在这里插入图片描述


2.3 监听组件的更新

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

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

<template>
  <div>
    <h3>LifeCycle 组件 --- {{ count }}</h3>
    <button class="btn btn-primary" type="button" @click="count+=1">Taggle</button>
  </div>
</template>

<script>
export default {
  name: 'LifeCycle',
  data() {
    return {
      count: 0,
    }
  },
  // 组件在内存中被创建完毕了
  created() {
    console.log('created: 组件在内存中被创建完毕了')
  },
  // 组件第一次被渲染到了页面上
  mounted() {
    console.log('mounted: 组件第一次被渲染到了页面上')
  },
  // 组件被重新渲染完毕了
  updated() {
    console.log('updated: 组件被重新渲染完毕了')
  },
  // 组件被销毁完毕了
  unmounted() {
    console.log('unmounted: 组件被销毁完毕了')
  },
}
</script>
<style lang="less" scoped></style>

在这里插入图片描述


2.4 主要生命周期函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lbymojkz-1687835106859)(null)]

注意:发起Ajax请求数据必须在created中,之所以不在 beforeCreate中是因为此时组件还未被创建,无法将数据挂载到data节点上(如下图所示,在控制台输出是count的值没有)!

image-20230625194128431

返回顶部


三、组件之间的数据共享

这部分内容与props内容基本一致,可以参考!

3.1 组件关系及数据共享

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

  • 父子关系

  • 兄弟关系

  • 后代关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CSBxtAfx-1687835107042)(null)]


3.2 父子组件数据共享

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

  • 父-> 子共享数据

    image-20230625205327555

  • 子-> 父共享数据

    image-20230625205422826

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

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxjV9LyE-1687835107136)(null)]


3.3 兄弟组件数据共享

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oyXFgpoq-1687835107265)(null)]

安装 mitt 依赖包:npm install mitt@2.1.0

新建组件:Vue 、Left 、Right ,在Vue中导入Left、Right组件:

image-20230626192610838

创建公共的 EventBus 模块:

// eventBus.js

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

在数据接收方自定义事件,调用 bus.on(‘事件名称’,事件处理函数) 方法注册一个自定义事件:

<template>
  <div>
    <h3>数据接收方 --- num 的值为:{{ num }}</h3>
  </div>
</template>

<script>
// 导入bus实例对象
import bus from './eventBus.js'

export default {
  name: 'MyRight',
  data() {
    return {
      num: 0,
    }
  },
  mounted(){
    // 接收发送方数据
    bus.on('countChange',(count)=>{
      this.num = count
    })
  }
}
</script>

<style lang="less" scoped></style>

在数据发送方,调用bus.emit(‘事件名称’, 要发送的数据) 方法触发自定义事件。

<template>
  <div>
    <h3>数据发送方 --- count 的值为:{{ count }}</h3>
    <button type="button" class="btn btn-primary" @click="add">+1</button>
  </div>
</template>

<script>
// 导入bus实例对象
import bus from './eventBus.js'

export default {
  name: 'MyLeft',
  data() {
    return {
      count: 0,
    }
  },
  methods: {
    add() {
      this.count++
      // 发送方发送数据
      bus.emit('countChange', this.count)
    },
  },
}
</script>

<style lang="less" scoped></style>

在这里插入图片描述


3.4 后代组件数据共享

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7rdvi26I-1687835106910)(null)]

创建新的组件:App、LevelTwo、LevelThree,并将三个组件连级引入(App中导入LevelTwo组件,LevelTwo中导入LevelThree组件):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lHDZbxeo-1687835107310)(null)]

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

<script>
import LevelTwo from './LevelTwo.vue'

export default {
  name: 'MyApp',
  data() {
    return {
      color: 'red',
    }
  },
  provide() {
    // 返回要共享的数据对象
    return {
      color: this.color,
    }
  },
  components: {
    LevelTwo,
  },
}
</script>

子孙节点可以使用inject数组,接收父级节点向下共享的数据:

<template>
  <div>
    <h5>Level Three 三级组件 - {{ color }}</h5>
  </div>
</template>

<script>
export default {
  name: 'LevelThree',
  inject: ['color'], // 接收数据
}
</script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Ctv1Dom-1687835106639)(null)]

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

  • 父节点使用 provide 向下共享数据时,可以结合 computed 函数向下共享响应式的数据。

    <template>
      <div>
        <h1>App 根组件 -- {{ color }}</h1>
        <hr />
        <level-two></level-two>
      </div>
    </template>
    
    <script>
    import LevelTwo from './LevelTwo.vue'
    import { computed } from 'vue'
    
    export default {
      name: 'MyApp',
      data() {
        return {
          color: 'red',
        }
      },
      provide() {
        // 返回要共享的数据对象
        return {
          color: computed(() => this.color),
          count: 1,
        }
      },
      components: {
        LevelTwo,
      },
    }
    </script>
    <style lang="less" scoped></style>
    
  • 如果父级节点共享的是响应式的数据,则子孙节点必须以 .value 的形式进行使用

    <template>
      <div>
        <h5>Level Three 三级组件 --- {{ color.value }} --- {{ count }}</h5>
      </div>
    </template>
    
    <script>
    export default {
      name: 'LevelThree',
      inject: ['color', 'count'],
    }
    </script>
    
    <style lang="less" scoped></style>
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iurnVE24-1687835106813)(null)]

**新增按钮,改变父组件中 color 的,可以观察到后代组件的 color 也跟着改变了: **

在这里插入图片描述


3.5 vuex

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jRUkAGfS-1687835106726)(null)]

从上图中我们可以看到,使用传统的组件之间的数据共享方式,在父与子、子与父、兄弟组件之间每有一个数据的传递就需要使用对应的方式进行传值,显得十分繁琐;而 vuex 方案则可以将这些所有类型的绑定事件进行统一的管理,简化了开发。

返回顶部


四、全局配置 axios

参考文章:【Vue】 Axios请求库

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

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0KHHTnBT-1687835107006)(null)]

main.js 入口文件中,通过 app.config.globalProperties 全局挂载 axios :

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ufvxl9vw-1687835107231)(null)]

创建三个新的组件:Vue、GetInfo、PostInfo,GetInfo、PostInfo组件中分别创建按钮,实现get、post的请求方法:

image-20230627105021177

在这里插入图片描述
在这里插入图片描述
返回顶部


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/690534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Thinkphp6框架全新UI的AI网址导航系统源码

✨ 源码介绍 2023全新UI的AI网址导航系统源码&#xff0c;基于thinkphp6框架开发的 AI 网址导航是一个非常实用的工具&#xff0c;它能够帮助用户方便地浏览和管理自己喜欢的网站。 相比于其他的 AI 网址导航&#xff0c;这个项目使用了更加友好和易用的 ThinkPHP 框架进行搭建…

基于3×3耦合器的干涉型光纤传感器信号解调技术研究-Matlab代码

一、引言 光纤耦合器是一种使光信号在特殊结构的耦合区内发生耦合&#xff0c;将功率再分配的无源器件。它在光纤传感和光通信等领域有着广泛的应用&#xff0c;在耦合过程中&#xff0c;光信号的频谱成分不变&#xff0c;只是信号的光功率发生变化。1980年&#xff0c;K&…

2023双态IT北京用户大会回顾(二) | 云内外一体化智能监控构建之路

文末附有本场专题演讲视频 2023第五届双态IT北京用户大会擎创科技专场演讲回顾&#xff08;二&#xff09;&#xff1a;《云内外一体化智能监控构建之路》演讲嘉宾&#xff1a;擎创科技产品线总监 殷传旺 一、前言&#xff1a;企业运维自然推进or独立发展&#xff1f; 我们从…

WebAssembly能否取代Docker?

“如果WebAssembly&#xff08;Wasm&#xff09;在几年前出现&#xff0c;Docker可能就不会出现了。因为它是一项非常强大的跨平台技术&#xff0c;可以让我们使用不同的编程语言来编写跨平台应用程序。Docker的原始动力之一就是提供一个跨平台部署和应用的方法。” -- Solomon…

lesson6 ZIgbee网络特性抓包分析

目录 ZIgbee网络特性抓包分析 理论部分&#xff1a; 实验部分&#xff1a; 入网前相关数据帧&#xff08;仅单个设备供电&#xff09;&#xff1a; 首先以路由器和协调器为例&#xff1a;&#xff08;帧的类别从头部的Type可以看到&#xff0c;在四大帧类别中根据不同作用也…

Vue 项目build打包发布到github pages ,刷新页面首页正常打开,子路由报错404的解决方法

一、问题效果如下&#xff1a; 二、解决方法 1、切换到gh-pages分支 2、在index.html同级新增404.html文件&#xff0c;其内容与index.html一样 三、解决后的效果如下&#xff1a; 相关文章 Vue3 Vite Ts开源后台管理系统模板 基于ElementUi或AntdUI再次封装基础组件文档 基…

Java版本spring cloud 电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展

营造全面规范安全的电子招投标环境&#xff0c;促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标…

VueX用法快速回顾(简洁纯干货)

vuex基础结构 代码结构 vuex的完整结构长这样&#xff0c;其包含了state、mutations、actions、modules及getters5个部分。 import Vue from vue import Vuex from vuexVue.use(Vuex)const store new Vuex.Store({state: {},mutations: {},actions:{},modules:{},getters:{…

mysql数据库 查询出的字段值是 科学计数法数字,数字转换为易于理解的形式

目录 1 问题2 实现 1 问题 数据库查询出来的可能是这种&#xff0c;如何将数字转换为易于理解的形式&#xff1b; 2 实现

ppt文件全部删除怎么恢复?别急,这些方法能挽救

PPT文件全部删除怎么恢复&#xff1f;如果您不小心将PPT文件删除&#xff0c;不要担心&#xff0c;您可能还有机会将其恢复。在下面的文章中&#xff0c;我们将介绍一些技巧来恢复已删除的PPT文件。 第一部分&#xff1a;关于PPT文件 PPT文件是指Microsoft PowerPoint软件创建…

互联网医院开发|互联网医院系统源码技术实现

健康医疗这几年一直成为人们比较关注的问题&#xff0c;互联网医院系统通过信息化技术精简了预约挂号&#xff0c;优化了医生的诊断流程&#xff0c;通过互联网医疗&#xff0c;患者复诊或医疗咨询需求都可以在线上进行&#xff0c;这种快捷的线上问诊方式缓解一线医务人员的压…

【成都】EFDC建模方法及在地表水环境评价、水源地划分、排污口论证中实践技术应用

为了定量地描述地表水环境质量与污染排放之间的动态关系&#xff0c;EFDC、MIKE、Delft3D、Qual2K等数值模型被广泛应用在环境、水务、海洋等多个领域。Environmental Fluid Dynamics Code&#xff08;EFDC&#xff09;是一款用于模拟江河&#xff0c;湖泊&#xff0c;河口&…

Linux 中利用设备树点灯

系列文章目录 第一章 Linux 中内核与驱动程序 第二章 Linux 设备驱动编写 &#xff08;misc&#xff09; 第三章 Linux 设备驱动编写及设备节点自动生成 &#xff08;cdev&#xff09; 第四章 Linux 平台总线platform与设备树 第五章 Linux 设备树中pinctrl与gpio&#xff08;…

通过一道题再了解一点Array原型上的every方法

一、例题 首先我们先来看这么一系列关于every使用的题&#xff1a; console.log(1, [].every(() > false)) console.log(2, [,,].every(() > false)) console.log(3, [undefined].every(() > false)) console.log(4, [false].every(() > false)) console.log(5, […

【深度学习】最全的十九种损失函数汇总

tensorflow和pytorch很多都是相似的&#xff0c;这里以pytorch为例。 文章目录 一、L1范数损失 L1Loss二、均方误差损失 MSELoss三、交叉熵损失 CrossEntropyLoss四、KL 散度损失 KLDivLoss五、二进制交叉熵损失 BCELoss六、BCEWithLogitsLoss七、MarginRankingLoss八、HingeEm…

git rebase和git merge在团队协作开发中的用法

git rebase和git merge是在日常开发中常用的用于分支合并的命令&#xff0c;也是非常容易误用的两个命令。本文将通过图文的方式去详解二者之间的区别。 git merge git merge会为本次的合并过程生成一条新的commit&#xff0c;并将该commit添加到目的分支上。通常用于将featu…

【Tensorflow object detection API + 微软NNI】图像分类问题完成自动调参,进一步提升模型准确率!

1. 背景&目标 利用Tensorflow object detection API开发并训练图像分类模型&#xff08;例如&#xff0c;Mobilenetv2等&#xff09;&#xff0c;自己直接手动调参&#xff0c;对于模型的准确率提不到极致&#xff0c;利用微软NNI自动调参工具进行调参&#xff0c;进一步提…

Keep通过IPO聆讯,3年烧掉16亿

“运动科技第一股”来了&#xff01; 6月21日&#xff0c;线上健身平台的运营方、北京卡路里科技有限公司&#xff08;下称“Keep”&#xff09;已正式通过聆讯&#xff0c;股票代码为810342.HK。 Keep是一家在线健身平台&#xff0c;主要产品包括在线健身内容、智能健身设备…

【python百炼成魔】python之内置函数range

前言 文章目录 前言内置函数 range()三种创建方式1. 只有一个参数的情况2. 给定两个参数的情况3. 三个参数都给定的时候 使用in和not in 来判断指定的整数是否存在1. 判断range生成的序列中是否存在指定的值2. in 和not in 不与range结合的情况 总结 内置函数 range() range()函…

第六章、Linux文件与目录管理

6.1 目录与路径 6.1.1 相对路径与绝对路径 绝对路径&#xff1a;路径的写法“一定由根目录 / 写起”&#xff0c;例如&#xff1a; /usr/share/doc 这个目录。 相对路径&#xff1a;路径的写法“不是由 / 写起”&#xff0c;例如由 /usr/share/doc 要到 /usr/share/man 下面…