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>

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Noisy DQN 跑 CartPole-v1

gym 0.26.1 CartPole-v1 NoisyNet DQN NoisyNet 就是把原来Linear里的w/b 换成 mu sigma * epsilon, 这是一种非常简单的方法&#xff0c;但是可以显著提升DQN的表现。 和之前最原始的DQN相比就是改了两个地方&#xff0c;一个是Linear改成了NoisyLinear,另外一个是在agent在t…

关于位运算

只出现一次的数字&#xff1a; 给你一个非空整数数组 nums&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现一次的元素。 class Solution { public:int singleNumber(vector<int>& nums) {int j0;for(auto i:nums){j^i…

62.网游逆向分析与插件开发-游戏增加自动化助手接口-游戏公告类的C++还原

内容来源于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;游戏红字公告功能的逆向分析-CSDN博客 码云地址&#xff08;master分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;0888e34878d9e7dd0acd08ef…

VMware Tools 启动脚本未能在虚拟机中成功运行。如果您在此虚拟机中配置了自定义启动脚本,请确保该脚本没有错误。您也可以提交支持请求,报告此问题。

问题描述&#xff1a;今天打开centos7虚拟机就是直接打不开了报了下面的错误&#xff0c;也没有动任何东西&#xff0c;点确定后&#xff0c;也是依然没有反应 问题原因&#xff1a;可能是虚拟机中的内存满了&#xff0c;需要清理内存 解决方法如下 首先cmd打开终端敲入如下命…

DNS主从服务器、转发(缓存)服务器

一、主从服务器 1、基本含义 DNS辅助服务器是一种容错设计&#xff0c;考虑的是一旦DNS主服务器出现故障或因负载太重无法及时响应客户机请求&#xff0c;辅助服务器将挺身而出为主服务器排忧解难。辅助服务器的区域数据都是从主服务器复制而来&#xff0c;因此辅助服务器的数…

pytest安装失败,报错Could not find a version that satisfies the requirement pytest

问题 安装pytest失败&#xff0c;尝试使用的命令有 pip install pytest pip3 install pytest pip install -U pytest pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple但是都会报同样的错&#xff1a; 解决方案 发现可能是挂了梯子的原因&#xff0c;关掉…

Android WiFi基础概览

Android WiFi 基础概览 1、WiFi协议2、Android WLAN 架构2.1 应用框架2.2 Wi-Fi 服务2.3 Wi-Fi HAL 3、相关编译 android13-release 1、WiFi协议 Wi-Fi&#xff08;无线通信技术&#xff09;_百度百科 2.4GHz 频段支持以下标准&#xff08;802.11b/g/n/ax&#xff09;&#xff…

根据MySql的表名,自动生成实体类,模仿ORM框架

ORM框架可以根据数据库的表自动生成实体类&#xff0c;以及相应CRUD操作 本文是一个自动生成实体类的工具&#xff0c;用于生成Mysql表对应的实体类。 新建Winform窗体应用程序AutoGenerateForm&#xff0c;框架(.net framework 4.5)&#xff0c; 添加对System.Configuration的…

java基于SSM的毕业生就业管理系统+vue论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本毕业生就业管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信…

更改ERPNEXT源

更改ERPNEXT源 一&#xff0c; 更改源 针对已经安装了erpnext的&#xff0c;需要更改源的情况&#xff1a; 1, 更改为官方默认源, 进入frapp-bench的目录&#xff0c; 然后执行: bench remote-reset-url frappe //重设frappe的源为官方github地址。 bench remote-reset-url…

java基于ssm框架的校园闲置物品交易平台论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本校园闲置物品交易平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

10分钟设置免费海外远程桌面使用Amazon Lightsail服务的免费套餐轻松搭建远程桌面

本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 目录 前言 使用教程 启动 Amazon Lightsail 实例 配置远程桌面 启动远程桌面 使…