vue3 鲜为人知的知识点

该篇文章是个人觉得在平常开发过程中没怎么注意到(新增加)的知识点,每个章节的内容在官网中不只文章提到的这些。

💕 模板语法

✔ 动态参数
<script setup>
import { ref } from 'vue'

const attributeName = ref('msg')
const eventName = ref('click')

const handle = () => {
  console.log('动态事件触发')
}
</script>
<template>
    <!-- 动态事件绑定 -->
    <button @[eventName] = "handle">动态事件绑定</button>
    <!-- 动态变量绑定 -->
    <HelloWorld :[attributeName] = "HelloWorld"/>
</template>

💕 列表渲染

v-for 与对象
<script setup>
import { reactive } from 'vue'
const myObject = reactive({
  title: 'How to do lists in Vue',
  author: 'Jane Doe',
  publishedAt: '2016-04-10'
})    
</script>
<template>
   <ul>
        <li v-for="(value, key, index) in myObject">
          {{ index }}. {{ key }}: {{ value }}
        </li> 
   </ul>
</template>

v-for 使用范围值

注意此处 n 的初值是从 1 开始而非 0

<template>
    <ul>
      <li v-for="n in 10">{{ n }}</li>
    </ul>
</template>

在这里插入图片描述


v-forv-if

当它们同时存在于一个节点上时,v-ifv-for 的优先级更高。

<script setup>
import { reactive } from 'vue'
const todos = reactive([
    { isComplete: true, name: 'work' },
    { isComplete: false, name: 'play' }
])    
</script>
<template>
    <ul>
        <li v-for="todo in todos" v-if="!todo.isComplete">{{ todo.name }}</li>
    </ul>
</template>

如果使用上述代码,这会抛出错误和警告

在这里插入图片描述

因为:v-if 的优先级高于 v-for,从而导致 v-for 作用域内定义的变量别名

如何解决:

<script setup>
import { reactive } from 'vue'
const todos = reactive([
    { isComplete: true, name: 'work' },
    { isComplete: false, name: 'play' }
])    
</script>
<template>
    <ul>
        <template v-for="todo in todos">
            <li v-if="!todo.isComplete">{{ todo.name }}</li>
        </template>
    </ul>
</template>

💕 侦听器

✔ 侦听多个数据源
<script setup>
import { watch, ref } from 'vue'
const x = ref(0)
const y = ref(1)

watch([x.value, y.value], ([newx, newY]) => {
     console.log(`x is ${newX} and y is ${newY}`)
})
</script>

✔ getter 函数

例子一:

<script setup>
import { watch, reactive } from 'vue'
const obj = reactive({ count: 0 })

watch(obj.count, (count) => {
  console.log(`count is: ${count}`)
})
</script>

上诉代码会报错:因为 watch() 得到的参数是一个 number

例子二:

<script setup>
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
import { watch, reactive } from 'vue'

const obj = reactive({
  count: 0 
})

watch(obj, (newValue, oldValue) => {
  console.log('新值', newValue)
  console.log('旧值', oldValue)
})
    
const handleAcc = () => {
  obj.count++
}
</script>
<template>
   <button @click="handleAcc">count++</button>
</template>

在这里插入图片描述

在嵌套的属性变更时触发,因为它们是同一个对象!故newValue 此处和 oldValue 是相等的

除非 obj 整个被替换掉,才能使 newValueoldValue 不一样


上诉俩个例子都需要将监听函数的第一个参数修改成 getters 函数

watch(() => obj.count, (count) => {
  console.log(`count is: ${count}`)
})

✔ watch 第三个参数
watch(() => obj.count, (newCount, oldCount) => {
    console.log('立即执行,并深度监听')
}, { deep: true, immediate: true })

注:深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能

上述俩个都比较经常使用的,下面这个配置是控制监听器的触发时机

watch(() => obj.count, (newCount, oldCount) => {
    console.log('在这里可以访问 被 vue 更新后的 DOM')
}, { flush: 'post' })

✔ watchEffect

自动跟踪回调的响应式依赖,不需要显性设置监听源。可以自动监听依赖项,并自动触发相关操作

watchEffect(async() => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)
    data.value = await response.json()
});

这个例子中,回调会立即执行,不需要指定 immediate: true。在执行期间,它会自动追踪 todoId.value 作为依赖(和计算属性类似)。每当 todoId.value 变化时,回调会再次执行。有了 watchEffect(),我们不再需要明确传递 todoId 作为源值。


✔ watchEffect vs watch

watchwatchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:

  • watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机
  • watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确

总结:

  • 对于这种只有一个依赖项的例子来说,watchEffect() 的好处相对较小。
  • 对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。
  • 如果你需要侦听一个嵌套数据结构中的几个属性,watchEffect() 可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性

✔ 停止监听

setup()<script setup> 中用同步语句创建的侦听器,会自动绑定到宿主组件实例上,并且会在宿主组件卸载时自动停止。

如下面这个例子:

<script setup>
import { watchEffect } from 'vue'

// 它会自动停止
watchEffect(() => {})

// ...这个则不会!
setTimeout(() => {
  watchEffect(() => {})
}, 100)
</script>

要手动停止一个侦听器,请调用 watchwatchEffect 返回的函数:

const unwatch = watchEffect(() => {})

// ...当该侦听器不再需要时
unwatch()

💕 模板引用

✔ 函数模板引用

下诉代码是模板引用的写法:

<script setup>
import { ref, onMounted } from 'vue'
const inputRef = ref(null)

onMounted(() => {
    inputRef.value.focus()
    console.log(inputRef.value)
})
</script>
<template>
   <input ref="inputRef" />
</template>

ref 除了可以绑定一个对象外,还能绑定一个函数(函数模板应用):

<script setup>
import { ref, onMounted } from 'vue'
const inputRef = ref(null)
</script>
<template>
   <input :ref="(el) => { console.log('input 值', el) /* 将 el 赋值给一个数据属性或 ref 变量 */ }" />
</template>

注:当绑定的元素被卸载时,函数也会被调用一次,此时的 el 参数会是 null


✔ 组件实例引用

也可以通过模板引用来获取到子组件的实例。但这里需要分情况:

  • 如果一个子组件使用的是选项式 API 或没有使用 <script setup>。则父组件对子组件的每一个属性和方法都有完全的访问权。
  • 如果使用了 <script setup> 的组件是默认私有的:一个父组件无法访问到一个使用了 <script setup> 的子组件中的任何东西。

针对第二种情况:子组件在其中通过 defineExpose 宏显式暴露属性或方法

<script setup>
import { ref, defineExpose } from 'vue'

const a = 1
const b = ref(2)

// 像 defineExpose 这样的编译器宏不需要导入
defineExpose({
  a,
  b
})
</script>

💕 Props

✔ 如何单向修改 Props

总所周知:Props 是单向数据流,且在子组件不能进行修改。要想修改,只能通知父组件修改,或者使用双向数据绑定。

const props = defineProps(['foo'])

// 修改值
props.foo = 'bar' // 报错

可以通过下述几个方法,在不通知父组件的前提下进行修改:

const props = defineProps(['initialCounter'])
// 将 props 赋值给 counter,则prop 和后续更新无关了
const counter = ref(props.initialCounter)

但有一个缺点:如果上层数据发生改变时,下层是不能实时更新的。可以在做修改:

const props = defineProps(['initialCounter'])
// 将 props 赋值给 counter,则prop 和后续更新无关了
const counter = computed(() => props.initialCounter)

这样就可以保证:

  • 如果上层数据发生改变时,下层能够实时更新的
  • 下层数据修改时,不会影响到上层数据

💕 事件

✔ 事件校验
<script setup>
const emit = defineEmits({
  // 没有校验
  click: null,

  // 校验 submit 事件
  submit: ({ email, password }) => {
    if (email && password) {
      return true
    } else {
      console.warn('Invalid submit event payload!')
      return false
    }
  }
})

function submitForm(email, password) {
  emit('submit', { email, password })
}
</script>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[JavaWeb玩耍日记] 数据库

mysql版本&#xff1a;5.7.24 使用Navicat for MySQL辅助学习(2015年版)&#xff0c;这个在粘贴本博客的块引用内容时会有额外的不可见内容导致sql运行出问题&#xff0c;不过有影响的地方笔者已排除 目录 一.数据库创建 二.使用数据库与创建表 三.表内列的数据类型 四.修…

解决Android Studio The path ‘X:\XXX‘ does not belong to a directory.

目录 前言 一、问题描述 二、解决方法 前言 在移动应用开发领域&#xff0c;Android Studio作为一款功能强大的集成开发环境&#xff0c;为开发人员提供了丰富的工具和功能。然而&#xff0c;在使用Android Studio的过程中&#xff0c;有时也会遇到各种各样的问题和错误。 &…

SpringCloud微服务

微服务技术对比 DubboSpringCloudSpringCloudAlibaba注册中心zookeeper,RedisEureka、ConsulNacos、Eureka服务远程调用Dubbo协议Feign(http协议)Dubbo、Feign配置中心无SpringCloudConfigSpringCloudConfig,Nacos服务网关无SpringCloudGateway、ZuulSpringCloudGateway、Zuul…

西门子PLC联网数据采集:借助HiWoo Box实现高效监控与管理

在工业自动化领域&#xff0c;西门子PLC作为一种广泛应用的控制器&#xff0c;对于工厂的生产线具有至关重要的作用。如何实现西门子PLC的联网数据采集&#xff0c;提高生产效率和管理水平&#xff0c;成为了许多企业的关注焦点。而HiWoo Box作为一款功能强大的工业网关&#x…

STM32-03-STM32HAL库

文章目录 STM32HAL库1. HAL库介绍2. STM32Cube固件包3. HAL库框架结构4. 新建HAL版本MDK工程 STM32HAL库 1. HAL库介绍 HAL库 HAL&#xff0c;英文全称 Hardware Abstraction Layer&#xff0c;即硬件抽象层。HAL库是ST公司提供的外设驱动代码的驱动库&#xff0c;用户只需要调…

数字孪生在增强现实(AR)中的应用

数字孪生在增强现实&#xff08;Augmented Reality&#xff0c;AR&#xff09;中的应用可以提供更丰富、交互性更强的现实世界增强体验。以下是数字孪生在AR中的一些应用&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff…

性能优化-OpenMP概述(一)-宏观全面理解OpenMP

本文旨在从宏观角度来介绍OpenMP的原理、编程模型、以及在各个领域的应用、使用、希望读者能够从本文整体上了解OpenMP。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&#xff09;开发基础…

添加jdk 11到环境变量的一种方法

添加jdk 11到环境变量的一种方法 1.jdk11可以直接在android studio 中下载&#xff0c; File --> Settings --> Build, Execution, Deployment --> Build Tools --> Gradle 下载jdk 11 &#xff0c;确认好下载路径 2.jdk11 添加到环境变量添加到环境变量 多个…

【AI视野·今日NLP 自然语言处理论文速览 第六十六期】Tue, 31 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Tue, 31 Oct 2023 (showing first 100 of 141 entries) Totally 100 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers The Eval4NLP 2023 Shared Task on Prompting Large Language Models a…

日程安排小程序实战教程

日常中我们经常有一些事情需要提醒自己&#xff0c;使用日历的形式比较符合实际的使用习惯。本篇我们就利用微搭低代码工具带着大家开发一款日程安排的小程序。 1 创建数据源 登录微搭低代码控制台&#xff0c;打开数据模型&#xff0c;点击创建 输入数据源的名称日程安排 …

Erupt即开即用的后台管理系统【告别前端代码】

一、引子 【零前端代码&#xff0c;几行Java注解&#xff0c;搞定后台管理系统】 如果只是自己内部公司使用的话&#xff0c;大多数功能都可以满足&#xff0c;剩下的就是自己添砖加瓦了。 我用这个主要是简单快捷&#xff0c;10分钟搭建一个简易的后台管理系统。 二、基本…

【精通C语言】:深入解析C语言中的while循环

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; C语言详解 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、while循环1.1语法1.2 执行过程解析1.3 break1.4 continue &#x1f324;️全篇总结 &…

ssm基于vue.js的购物商场的设计与实现论文

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装购物商场软件来发挥其高效地信息处理的作用&#xff0c;可以…

Notepad++ v7.7.1 安装及添加插件

1、notepad_v7.7.1.zip npp.7.7.1.Installer.x64.exe npp.7.7.1.Installer.x86.exe notepad_v7.7.1.ziphttps://www.123pan.com/s/VTMXjv-X6H6v.html 2、notepad插件包_64bit_4.zip ComparePlugin ---->文件对比插件 ComparePlugin.dllNppFTP ---->FTP、FTPES和SFTP …

软件测试/测试开发丨Selenium 高级控件交互方法

一、使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件&#xff08;了解即可&#xff09; www.selenium.dev/documentati… 二、ActionChains解析 实例化类ActionChains&#xff0c;参…

bootstrap5实现宠物商店网站 Cat-Master

一、需求分析 宠物商店网站是指专门为宠物商店或宠物用品商家而建立的在线平台。这种网站的功能通常旨在提供以下服务&#xff1a; 产品展示&#xff1a;宠物商店网站通常会展示宠物食品、玩具、床上用品、健康护理产品等各种宠物用品的图片和详细信息。这样&#xff0c;潜在的…

IP2312U_VSET 5V 2A 单节锂电池同步开关降压充电IC

IP2312U是一款5V输入&#xff0c;支持单节锂电池同步开关降压充电管理的IC。 IP2312U集成功率MOS&#xff0c;采用同步开关架构&#xff0c; 使其在应用时仅需极少的外围器件&#xff0c;并有效减小整体方案的尺寸&#xff0c;降低BOM 成本。 IP2312U的升压开关充电转换器工作频…

PromptCast:基于提示学习的时序预测模型!

目前时序预测的SOTA模型大多基于Transformer架构&#xff0c;以数值序列为输入&#xff0c;如下图的上半部分所示&#xff0c;通过多重编码融合历史数据信息&#xff0c;预测未来一定窗口内的序列数值。 受到大语言模型提示工程技术的启发&#xff0c;文章提出了一种时序预测新…

未来人工智能技术发展趋势

近年来&#xff0c;人工智能技术在全球范围内得到了快速的发展和广泛的应用。随着技术的不断进步和创新&#xff0c;未来人工智能技术将会呈现出哪些发展趋势呢&#xff1f;本文将会从以下几个方面进行分析。 1. 多模态融合 未来的人工智能技术将会更加注重多模态数据的融合&…

如何正确安装Axure插件?详细步骤分享

产品经理在使用Axure导出html文件时&#xff0c;如果选择“完成后打开浏览器”&#xff0c;浏览器往往无法识别。此时&#xff0c;我们需要使用Axure官方谷歌浏览器插件直接访问浏览器中的本地html项目&#xff0c;否则我们需要上传到AxureCloud或使用软件本身的预览功能。接下…