普通二本软件工程薪水/网站关键词排名手机优化软件
基础点
reactive()
定义响应式变量(仅仅引用类型有效:对象数组map,set):reactive(),类似于data中return的数据
例子:
import { reactive } from 'vue'export default {setup() {const state = reactive({ count: 0 })function increment() {state.count++}// 变量和方法 都需要return出来return {state,increment}}
}
另外 使用setup() 繁琐,可以用 直接包裹 无需return
reactive 默认是深层响应式,即obj.nested.count 对象属性的属性也是可以监听到的。 如果不想被监听可以使用 浅层响应式对象shallowReactive()
https://cn.vuejs.org/api/reactivity-advanced.html#shallowreactive
局限:
仅对对象类型有效(对象、数组和 Map、Set 这样的集合类型),而对 string、number 和 boolean 这样的 原始类型 无效。
因为 Vue 的响应式系统是通过属性访问进行追踪的,因此我们必须始终保持对该响应式对象的相同引用。这意味着我们不可以随意地“替换”一个响应式对象,因为这将导致对初始引用的响应性连接丢失:
let state = reactive({ count: 0 })// 上面的引用 ({ count: 0 }) 将不再被追踪(响应性连接已丢失!)
state = reactive({ count: 1 })
同时这也意味着当我们将响应式对象的属性赋值或解构至本地变量时,或是将该属性传入一个函数时,我们会失去响应性:
const state = reactive({ count: 0 })// n 是一个局部变量,同 state.count
// 失去响应性连接
let n = state.count
// 不影响原始的 state
n++// count 也和 state.count 失去了响应性连接
let { count } = state
// 不会影响原始的 state
count++// 该函数接收一个普通数字,并且
// 将无法跟踪 state.count 的变化
callSomeFunction(state.count)
ref()
任何类型
ref() 将传入参数的值包装为一个带 .value 属性的 ref 对象,使用的时候 用.value取值。但是在template中会被自动解包,直接用就行.
但是若定义ref的时候不是定义在顶层,而是const object = { foo: ref(1) } 这种,在模版中{{ object.foo + 1 }}渲染出来的是ref对象[object Object].
const count = ref(0)console.log(count) // { value: 0 }
console.log(count.value) // 0count.value++
console.log(count.value) // 1
<script setup>
import { ref } from 'vue'const count = ref(0)function increment() {count.value++
}
</script><template><button @click="increment">{{ count }} <!-- 无需 .value --></button>
</template>
computed
当我们的模版逻辑复杂的时候,利用计算属性返回,computed()方法接受一个getter,返回一个ref,ref在模版中自动解包,无需使用.value
我们发现使用方法和computed的返回结果是一样的,差异是:
计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。这意味响应不更新时不会重复执行getter函数。而方法调用在重渲染时会再次执行函数
ps:若在computed中返回Date.new() 是永远不会更新的,因为Date.new()不是响应式依赖
解释:所谓响应式依赖 在vue3中可以理解为用reactive(),ref()定义的,在vue2中就是data中return出来的。而不是响应式的依赖,可以理解为在vue3中没有通过这两种定义出来的,vue2中就是在方法中直接定义在this上的,而没有在data中声明并return出来的。
为什么使用computed:
假如我们有大量的数组计算逻辑依赖于某个list,不用缓存的话,会多次执行getter,耗费性能
默认只读的:
若尝试修改computed需要同时提供getter和setter
<script setup>
import { ref, computed } from 'vue'const firstName = ref('John')
const lastName = ref('Doe')const fullName = computed({// getterget() {return firstName.value + ' ' + lastName.value},// setterset(newValue) {// 注意:我们这里使用的是解构赋值语法[firstName.value, lastName.value] = newValue.split(' ')}
})
</script>
ps:
在此getter中不应做异步请求或更改dom
避免直接修改计算属性值,可以将它看作一个“临时快照”,每当源状态发生变化的时候就会创建新的快照
事件处理
在内联事件处理器中访问事件参数:
可以向该处理器方法传入一个特殊的 $event 变量,或者使用内联箭头函数:
<!-- 使用特殊的 $event 变量 -->
<button @click="warn('Form cannot be submitted yet.', $event)">Submit
</button><!-- 使用内联箭头函数 -->
<button @click="(event) => warn('Form cannot be submitted yet.', event)">Submit
</button>
function warn(message, event) {// 这里可以访问原生事件if (event) {event.preventDefault()}alert(message)
}
v-on 事件修饰符
<!-- 单击事件将停止传递 -->
<a @click.stop="doThis"></a><!-- 提交事件将不再重新加载页面 -->
<form @submit.prevent="onSubmit"></form><!-- 修饰语可以使用链式书写 -->
<a @click.stop.prevent="doThat"></a><!-- 也可以只有修饰符 -->
<form @submit.prevent></form><!-- 仅当 event.target 是元素本身时才会触发事件处理器 -->
<!-- 例如:事件处理器不来自子元素 -->
<div @click.self="doThat">...</div><!-- 添加事件监听器时,使用 `capture` 捕获模式 -->
<!-- 例如:指向内部元素的事件,在被内部元素处理前,先被外部处理 -->
<div @click.capture="doThis">...</div><!-- 点击事件最多被触发一次 -->
<a @click.once="doThis"></a><!-- 滚动事件的默认行为 (scrolling) 将立即发生而非等待 `onScroll` 完成 -->
<!-- 以防其中包含 `event.preventDefault()` -->
<div @scroll.passive="onScroll">...</div>
ps:使用修饰符时需要注意调用顺序
请勿同时使用 .passive 和 .prevent,因为 .passive 已经向浏览器表明了你不想阻止事件的默认行为。如果你这么做了,则 .prevent 会被忽略,并且浏览器会抛出警告。
生命周期
使用方法:
<script setup>
import { onMounted } from 'vue'onMounted(() => {console.log(`the component is now mounted.`)
})
</script>
具体生命周期api:
https://cn.vuejs.org/api/composition-api-lifecycle.html#onserverprefetch
watch
const x = ref(0)
const y = ref(0)// 单个 ref
watch(x, (newX) => {console.log(`x is ${newX}`)
})// getter 函数
watch(() => x.value + y.value,(sum) => {console.log(`sum of x + y is: ${sum}`)}
)// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {console.log(`x is ${newX} and y is ${newY}`)
})
注意:
不能只监听响应式对象的属性值,而是用一个返回该属性的getter函数
const obj = reactive({ count: 0 })// 错误,因为 watch() 得到的参数是一个 number
watch(obj.count, (count) => {console.log(`count is: ${count}`)
})// 正确: 提供一个 getter 函数
watch(() => obj.count, (count) => {console.log(`count is: ${count}`)}
)
深层监听
监听响应式对象时,该回调函数在所有嵌套的变更时都会被触发,也就是对象上的属性变化都会被监听到,如果你只想监听某个对象当前层级的时候,可以用getter()函数的方式,此时只有整个对象被替换时才触发回调,属性变化时不会被监听,但是可以通过加deep:true监听到
const obj = reactive({ count: 0 })watch(obj, (newValue, oldValue) => {// 在嵌套的属性变更时触发// 注意:`newValue` 此处和 `oldValue` 是相等的// 因为它们是同一个对象!
})obj.count++watch(() => state.someObject,() => {// 仅当 state.someObject 被替换时触发}
)
watch(() => state.someObject,(newValue, oldValue) => {// 注意:`newValue` 此处和 `oldValue` 是相等的// *除非* state.someObject 被整个替换了},{ deep: true }
)
ps:深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能
watchEffect()
watchEffect会自动跟踪回调的响应式依赖。
todoId既作为源又在回调中,利用watchEffect,在执行期间,会自动追踪todoId.value作为依赖,todoId.value变化时,回调会再次执行,使用watchEffect我们不需要明确传递todoId作为源值,
好处:
不必手动维护依赖列表。
当需要监听一个嵌套数据结构中的多个属性时,它只跟踪回调中被使用的属性,而不是递归的跟踪所有属性
const todoId = ref(1)
const data = ref(null)watch(todoId, async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
}, { immediate: true })
//可以改写成如下
watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
})
触发时机
默认情况下,用户创建的侦听器回调,都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。
如果想在侦听器回调中能访问被 Vue 更新之后的 DOM,你需要指明 flush: ‘post’ 选项
后置刷新的 watchEffect() 有个更方便的别名 watchPostEffect():
watch(source, callback, {flush: 'post'
})watchEffect(callback, {flush: 'post'
})
注意:
尽量不要使用异步监听,需要手动停止,否则造成内存泄漏。如果需要等待异步数据,可以用条件判断监听
// 需要异步请求得到的数据
const data = ref(null)watchEffect(() => {if (data.value) {// 数据加载后执行某些操作...}
})
组件使用
props
在<script setup>
中 通过defineProps({})
<script setup>
defineProps(['title'])
</script><template><h4>{{ title }}</h4>
</template>
如果不使用<script setup>
通过props传入,并传给setup()
export default {props: ['title'],setup(props) {console.log(props.title)}
}
事件传递
defineEmits([‘xxx’])在<script setup>
和单独的setup中两种形态
<script setup>
const emit = defineEmits(['enlarge-text'])emit('enlarge-text')
</script>
export default {emits: ['enlarge-text'],setup(props, ctx) {ctx.emit('enlarge-text')}
}
动态组件 is
当使用 <component :is="...">
来在多个组件间作切换时,被切换掉的组件会被卸载。我们可以通过 <KeepAlive>
组件强制被切换掉的组件仍然保持“存活”的状态。
<!-- currentTab 改变时组件也改变 -->
<component :is="tabs[currentTab]"></component>
相关文章:

vue2过渡vue3技术差异点指南
基础点 reactive() 定义响应式变量(仅仅引用类型有效:对象数组map,set):reactive(),类似于data中return的数据 例子: import { reactive } from vueexport default {setup() {const state reactive({ count: 0 })function in…...

两个多选框(select)之间值的左右上下移动
<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>两个多选框(select)之间值的左右上下移动</title> </head> <script src"https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>&…...

【设计模式】——模板模式
什么是模板模式? 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行…...

工业机器视觉系统开发流程简介
需求分析和系统设计:与用户合作,明确系统的功能和性能需求,并设计系统的整体架构。 软、硬件选型:根据需求分析结果,选择适合的软、硬件设备,包括光学传感器、相机、光源、图像采集设备、处理器等。 软件…...

【Unity3D】Renderer Feature简介
1 3D 项目迁移到 URP 项目后出现的问题 3D 项目迁移至 URP 项目后,会出现很多渲染问题,如:材质显示异常、GL 渲染不显示、多 Pass 渲染异常、屏幕后处理异常等问题。下面将针对这些问题给出一些简单的解决方案。 URP 官方教程和 API 详见→Un…...

麻了!包含中科院TOP,共16本期刊被标记为“On Hold”状态!
近日,小编从科睿唯安旗下的“Master Journal List”官网查到,除了知名老牌期刊Chemosphere竟然被标记为“On Hold”状态,目前共有7本SCI期刊,1本SSCI期刊,8本ESCI期刊被标记为“On Hold”,究竟是怎么回事呢…...

2.Flink应用
2.1 数据流 DataStream:DataStream是Flink数据流的核心抽象,其上定义了对数据流的一系列操作DataStreamSource:DataStreamSource 是 DataStream 的 起 点 , DataStreamSource 在StreamExecutionEnvironment 中 创 建 ,…...

Matlab进阶绘图第25期—三维密度散点图
三维密度散点图本质上是一种特征渲染的三维散点图,其颜色表示某一点所在区域的密度信息。 除了作图,三维密度散点图绘制的关键还在于密度的计算。 当然,不管是作图还是密度的计算,这些在《Matlab论文插图绘制模板》和《Matlab点…...

C++设计模式之桥接设计模式
文章目录 C桥接设计模式什么是桥接设计模式该模式有什么优缺点优点缺点 如何使用 C桥接设计模式 什么是桥接设计模式 桥接设计模式是一种结构型设计模式,它可以将抽象接口和实现分离开来,以便它们可以独立地变化和扩展。 该模式有什么优缺点 优点 灵…...

论文笔记:SUPERVISED CONTRASTIVE REGRESSION
2022arxiv的论文,没有中,但一作是P大图班本MIT博,可信度应该还是可以的 0 摘要 深度回归模型通常以端到端的方式进行学习,不明确尝试学习具有回归意识的表示。 它们的表示往往是分散的,未能捕捉回归任务的连续性质。…...

Java 多线程并发 CAS 技术详解
一、CAS概念和应用背景 CAS的作用和用途 CAS(Compare and Swap)是一种并发编程中常用的技术,用于解决多线程环境下的并发访问问题。CAS操作是一种原子操作,它可以提供线程安全性,避免了使用传统锁机制所带来的性能开…...

如何压缩高清PDF文件大小?将PDF文件压缩到最小的三个方法
PDF格式是一种非常常用的文档格式,但是有时候我们需要将PDF文件压缩为更小的大小以便于传输和存储。在本文中,我们将介绍三种PDF压缩的方法,包括在线PDF压缩、利用软件PDF压缩以及使用WPS缩小pdf。 首先,在线PDF压缩是最常用的方…...

04 统计语言模型(n元语言模型)
博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https://github.com/nickchen121/Pre-training-language-model 配套博客链接:https://www.cnblogs.com/nickchen121/p/15105048.html 预训练 预先训练 我们…...

Linux各目录详解
Linux文件系统是一个树状结构,由多个目录(或文件夹)组成。以下是常见的Linux目录及其功能的详细解释: /(根目录):在Linux文件系统中,所有其他目录和文件都是从根目录派生的。所有的存…...

【css】属性选择器分类
属性选择器类型示例说明[attribute][target]选择带有 target 属性的所有元素[attributevalue][target_blank]选择带有 target“_blank” 属性的所有元素[attribute~value][title~flower]选择带有包含 “flower” 一词的 title 属性的所有元素[attribute|value][lang|en]选择带有…...

备份容灾哪家好怎么样
数字化时代,数据安全是我们不容忽视的问题。云呐容灾备份系统不仅提供了强大的数据保护功能,而且操作简单,使用方便。无论你是企业管理员,还是个人用户,都可以轻松上手。它还提供了丰富的报告和监控功能,让…...

【前端实习生备战秋招】—HTML 和 CSS面试题总结(三)
【前端实习生备战秋招】—HTML 和 CSS面试题总结(三) 1.行内元素有哪些?块级元素有哪些? 空(void)元素有那些? CSS 规范规定,每个元素都有 display 属性,确定该元素的类型,每个元素…...

Ansible Rsync 使用Ansible Rsync模块进行文件传输
在Ansible自动化工具中,Rsync模块(Rsync Module)是一个强大的组件,用于在Ansible控制节点和目标主机之间进行文件传输和同步。本文将深入探讨Ansible Rsync模块,了解它如何成为自动化任务中高效同步的自动化利器。 Ans…...

Eclipse如何自动添加作者、日期等注释
一、创建类时自动添加注释 1、Window->Preferences 2、Java->Code Syle->Code Templates->Code->New Java files->Edit->要添加的注释->Apply 二、选中要添加的类或者方法通过AltShiftJ快捷键添加 1、Window->Preferences 2、Java->Code Syle…...

uniapp返回
// 监听返回事件onNavigationBarButtonTap() {uni.showModal({title: 提示,content: 确定要返回吗?,success: (res) > {if (res.confirm) {uni.navigateBack({delta: 2})}}})},...

【Antd】antd form表单的rules文案无法跟随状态重渲染的原因及解决办法
问题背景 我有两个表单项,当我选择出库类型,调用onChange改变inOutType 状态,这时候发现这句代码不生效: rules{[{ required: true, message: 请选择${inOutType 1 ? 持有人 : 负责人} }]}示例代码 <TypographyForm.Group…...

Rocketmq Filter 消息过滤(TAGS、SQL92)原理详解 源码解析
1. 背景 1.1 Rocketmq 支持的过滤方式 Rocketmq 作为金融级的业务消息中间件,拥有强大的消息过滤能力。其支持多种消息过滤方式: 表达式过滤:通过设置过滤表达式的方式进行过滤 TAG:根据消息的 tag 进行过滤。SQL92:…...

Attacks in NLP
一、 Introduction NLP对抗攻击是人工智能对抗攻击的一个重要的组成部分,但是最近几年才逐渐开始兴起,究其原因在于NLP对抗攻击与传统computer vision或者audio对抗攻击有很大的不同,主要在于值空间的连续性(CV、audio࿰…...

04-7_Qt 5.9 C++开发指南_QTreeWidget和QDockWidget
文章目录 1. 实例功能简述2. 源码2.1 可视化UI设计2.2 mainwindow.h2.3 mainwindow.cpp 1. 实例功能简述 本节介绍 QTreeWidget、QDockWidget 的使用,以及用 QLabel 显示图片的方法。实例 samp4_8以QTreeWidget 为主要组件,创建一个照片管理器ÿ…...

Keburnetes YAML配置文件管理
Kubernetes 支持 YAML 和 JSON 格式管理资源对象JSON 格式:主要用于 api 接口之间消息的传递YAML 格式:用于配置和管理,YAML 是一种简洁的非标记性语言,内容格式人性化,较易读 YAML 语法格式 大小写敏感使用缩进表示层…...

opencv基础-33 图像平滑处理-中值滤波cv2.medianBlur()
中值滤波是一种常见的图像处理滤波技术,用于去除图像中的噪声。它的原理是用一个滑动窗口(也称为卷积核)在图像上移动,对窗口中的像素值进行排序,然后用窗口中像素值的中值来替换中心像素的值。这样,中值滤…...

后端进阶之路——深入理解Spring Security配置(二)
前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★前端炫酷代码分享 ★ ★ uniapp-从构建到提升★ ★ 从0到英雄,vue成神之路★ ★ 解决算法,一个专栏就够了★ ★ 架…...

怎么绘制汤姆索亚历险记思维导图?掌握这几个绘制步骤就可以
怎么绘制汤姆索亚历险记思维导图?如果你正在为学习汤姆索亚历险记而感到困惑,或者你想要更好地理解小说中的人物关系、情节和舞台背景,那么一个清晰的思维导图就可以帮助你梳理思路。那么下面就给大家介绍一下绘制步骤。 在进行思维导图绘制的…...

Redis和数据库更新先后顺序
在使用 Redis 和数据库时,更新的先后顺序可以根据具体场景来决定。一般来说,有以下两种典型的更新顺序: 先更新数据库,再更新 Redis: 这种更新顺序适用于需要保证数据的一致性和可靠性的场景。当有数据更新时,首先将数据更新到数据库中,确保数据持久化。然后再更新 Redi…...

JavaScript--AJAX
概述 传统的web交互是用户触发一个http请求服务器,然后服务器收到之后,在做出响应到用户,并且返回一个新的页面,每当服务器处理客户端提交的请求时,客户都只能空闲等待,并且哪怕只是一次很小的交互、只需从…...