Vue11 Vue3完结撒花

shallowRef和shallowReactive

shallowRef

  1. 作用:创建一个响应式数据,但只对顶层属性进行响应式处理

  2. 用法

    let myVar = shallowRef(initialValue)
    
  3. 特点:只跟踪引用值变化,不关心值内部的属性变化

案例

<template><div class="app"><h2>求和为:{{ sum }}</h2><h2>名字为:{{ person.name }}</h2><h2>年龄为:{{ person.age }}</h2><h2>汽车为:{{ car }}</h2><button @click="changeSum">sum+1</button><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改整个人</button><span>|||||</span><button @click="changeBrand">修改品牌</button><button @click="changeColor">修改颜色</button><button @click="changeEngine">修改发动机</button><!-- <button @click="changeCar">修改整个车</button> --></div>
</template><script setup lang="ts" name="App">import { ref,reactive,shallowRef,shallowReactive } from 'vue'let sum = shallowRef(0)let person = shallowRef({name: '小黑',age:2})let car = shallowReactive({brand: '特斯拉',options: {color: '黑色',engine:'v8'}})function changeSum (){sum.value += 1;}// 不会改变function changeName (){person.value.name = '大狗';}function changeAge (){person.value.age = 5;}//只能改变第一层function changePerson (){person.value = {name:'乐乐',age:3}}/* ********** */function changeBrand () {car.brand = '宝马'}function changeColor () {car.options.color = '红色'}function changeEngine () {car.options.engine = 'v12'}// function changeCar () {// 	Object.assign(car,{})// }
</script><style scoped>.app{background-color: #ddd;border-radius: 10px;box-shadow: 0 0 10px;padding: 10px;}button{margin:0 5px;}
</style>

总结

通过使用shallowRef()和shallowReactive()来绕开深度响应。浅层式API创建的状态只在其顶层是响应式的,对所有深层的对象不会做任何处理,避免了对每一个内部属性做响应式所带来的性能成本,这使得属性的访问控制变得更快、可提升性能。

readonly与shallowReadonly

readonly

  1. 作用:用于创建一个对象的深只读副本

  2. 用法

    <template><div class="app"><h2>当前求和为:{{ sum }}</h2><h2>当前sum2求和为:{{ sum2 }}</h2><h2>当前car1为:{{ car }}</h2><h2>当前car2为:{{ car2 }}</h2><button @click="changeSum">点我sum+1</button><button @click="changeSum2">点我sum2+1</button></div>
    </template><script setup lang="ts" name="App">import { ref, readonly, reactive,shallowReadonly } from 'vue';let sum = ref(0)let sum2 = readonly(sum)function changeSum() {sum.value += 1}function changeSum2() {sum2.value += 1  //sum2不可修改}
    </script><style scoped>.app{background-color: #ddd;border-radius: 10px;box-shadow: 0 0 10px;padding: 10px;}button{margin:0 5px;}
    </style>
    
  3. 特点:

    • 对象的所有嵌套属性变成只读
    • 任何尝试修改这个对象的操作都会被组织(在开发模式下,还会再控制台中发出警告)
  4. 应用场景:

    • 创建不可变的状态快照
    • 保护全局状态或配置不被修改

shallowReadonly

  1. 作用:与readonly类似,但只作用于对象的顶层属性,其他地方仍然可以修改

  2. 用法

    <template><div class="app"><h2>当前car1为:{{ car }}</h2><h2>当前car2为:{{ car2 }}</h2><button @click="changeBrand1">修改car1品牌</button><button @click="changeColor1">修改car1颜色</button><button @click="changePrice1">修改car1价格</button><button @click="changeBrand2">修改car2品牌</button><button @click="changeColor2">修改car2颜色</button><button @click="changePrice2">修改car2价格</button></div>
    </template><script setup lang="ts" name="App">import { reactive,shallowReadonly } from 'vue';let car = reactive({brand:'奔驰',options: {color:'黑色',price:100}})let car2 = shallowReadonly(car)function changeBrand1() {car.brand = '宝马'}function changeColor1() {car.options.color = '红色'}function changePrice1() {car.options.price += 10}function changeBrand2() {car2.brand = '宝马'}function changeColor2() {car2.options.color = '红色'}function changePrice2() {car2.options.price += 10}
    </script><style scoped>.app{background-color: #ddd;border-radius: 10px;box-shadow: 0 0 10px;padding: 10px;}button{margin:0 5px;}
    </style>
    

toRaw与markrow

toRaw

  1. 作用:用于获取一个响应式对象的原始对象,toRaw返回的对象不再是响应式,不会触发视图更新。

    • 何时使用

      在需要将响应式对象传递给非Vue的库或外部系统时,使用toRaw可以确保他们收到的是普通对象

  2. 用法:使用toRaw之后 年龄不再改变

    <template><div class="app"><h2>姓名:{{ person.name }}</h2><h2>年龄:{{ person2.age }}</h2><button @click="person.age += 1">修改年龄</button></div>
    </template><script setup lang="ts" name="App">
    import { reactive,toRaw } from 'vue';let person = reactive({name: '小黑',age:2
    })
    let person2 = toRaw(person)console.log('响应式数据', person)
    console.log('原始数据',person2)
    </script><style scoped>.app{background-color: #ddd;border-radius: 10px;box-shadow: 0 0 10px;padding: 10px;}button{margin:0 5px;}
    </style>
    

markRaw

  1. 作用:标记一个对象,使其永远都不会变成响应式

    • 何时使用

      使用第三方库的时候,防止错误把第三库对象变成响应式对象,就可以使用markRaw

  2. 用法

    <template><div class="app"><h2>汽车:{{ car2 }}</h2><button @click="car2.price += 10">修改价格</button></div>
    </template><script setup lang="ts" name="App">
    import { reactive,toRaw,markRaw } from 'vue';/* markRaw */
    //添加markRaw 28行就失去作用,无法改变成响应式
    let car = markRaw({ brand: '奔驰', price: 100 })
    let car2 = reactive(car)console.log(car);
    console.log(car2);</script><style scoped>.app{background-color: #ddd;border-radius: 10px;box-shadow: 0 0 10px;padding: 10px;}button{margin:0 5px;}
    </style>
    

customRef的使用

作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行逻辑控制

实现防抖效果(useSumRef.ts)

<template><div class="app"><h2>{{ msg }}</h2><input type="text" v-model="msg"></div>
</template><script setup lang="ts" name="App">import { ref,customRef } from 'vue'//使用vue提供的默认ref定义响应式数据,数据一变,页面视图也更新// let msg = ref('你好')//使用vue提供的customRef定义响应式数据let initValue = '你好'let timer:number//track(跟踪)、trigger(触发) 不加上页面效果不会改变let msg = customRef((track,trigger) => {return {//get何时调用?——msg被读取时get() { track() //告诉vue数据很重要,需要对msg进行持续关注,一旦msg变化就去更新return initValue},//set何时调用?——msg被修改时set(value) {clearTimeout(timer)timer = setTimeout(() => {// console.log('set',value);initValue = valuetrigger() //通知vue数据变化了}, 1000);}}})
</script><style scoped>.app{background-color: #ddd;border-radius: 10px;box-shadow: 0 0 10px;padding: 10px;}button{margin:0 5px;}
</style>

采用hooks封装

定义hooks——useMsgRef.ts

import { customRef } from 'vue';export default function (initValue: string, delay: number) {//使用vue提供的customRef定义响应式数据// let initValue = '你好'let timer: number//track(跟踪)、trigger(触发) 不加上页面效果不会改变let msg = customRef((track, trigger) => {return {//get何时调用?——msg被读取时get() {track() //告诉vue数据很重要,需要对msg进行持续关注,一旦msg变化就去更新return initValue},//set何时调用?——msg被修改时set(value) {clearTimeout(timer)timer = setTimeout(() => {// console.log('set',value);initValue = valuetrigger() //通知vue数据变化了}, delay); //延迟时间不要写死}}})//hooks必须要有返回值return { msg }
}

App.vue

<template><div class="app"><h2>{{ msg }}</h2><input type="text" v-model="msg"></div>
</template><script setup lang="ts" name="App">import useMsgRef from './useMsgRef';//使用useMsgRef来定义一个响应式数据且有延迟效果let { msg } = useMsgRef('小黑', 2000)</script><style scoped>.app{background-color: #ddd;border-radius: 10px;box-shadow: 0 0 10px;padding: 10px;}button{margin:0 5px;}
</style>

Teleport

定义:Teleport是一种能够将我们的组件html结构移动到指定位置的技术

App.vue

<template><div class="outer"><h2>我是App组件</h2><img src="https://img.zcool.cn/community/014b275d0a1c95a801213ec257bb95.jpg@2o.jpg" alt=""><br><Modal/></div>
</template><script setup lang="ts" name="App">import Modal from './Modal.vue';
</script><style  scoped>
.outer{background-color: #ddd;border-radius: 10px;padding:5px;box-shadow: 0 0 10px;width: 500px;height: 500px;/* 添加滤镜后,模块定位不再参考视口,参考的是父容器了 */filter:saturate(150%);
}
img{height: 180px;object-fit: cover;
}
</style>

modal.vue

<template><button @click="isshow = true">展示弹窗</button><!-- teleport解决添加滤镜后fix定位问题 --><teleport to='body'><div class="modal" v-show="isshow"><h2>我是弹窗标题</h2><p>我是弹窗内容</p><button @click="isshow = false">关闭弹窗</button></div></teleport>
</template><script setup lang="ts" name="Modal">
import { ref } from 'vue'
let isshow = ref(false)
</script><style  scoped>
.modal{width: 200px;height: 150px;background-color: skyblue;border-radius: 10px;padding: 5px;box-shadow: 0 0 5px;text-align: center;position:fixed;left:50%;top: 20px;margin-left: -100px;
}
</style>

Suspense

  • 等待异步组件时渲染一些额外内容,让应用有更好的用户体验
  • 使用步骤:
    • 异步引入组件
    • 使用Suspense包裹组件,并配置好default和fallback

App.vue

<template><div class="app"><h2>我是App组件</h2><!-- 解决异步事件,如果不加下面,那么Child组件不显示 --><Suspense><template v-slot:default><Child/></template></Suspense></div>
</template><script setup lang="ts" name="App">import { Suspense } from 'vue'import Child from './Child.vue'
</script><style scoped>
.app{border-color: #ddd;border-radius:10px;padding:10px;box-shadow: 0 0 10px;
}
</style>

Child.vue

<template><div class="child"><h2>我是Child组件</h2><h3>当前sum求和为:{{ sum }}</h3></div>
</template><script setup lang="ts">
import { ref } from 'vue'
import axios from 'axios'let sum = ref(0)
let xxx = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
console.log(xxx);
//如果要看到数据,可以解构 xxx 替换成 {data{content}} log直接打印content即可</script><style scoped>
.child{background-color: skyblue;border-radius:10px;padding:10px;box-shadow: 0 0 10px;
}
</style>

全局API转移到应用对象

  • app.component

App.vue

<template><div class="app"><h2>我是App组件</h2><Hello/><Child/></div>
</template><script setup lang="ts" name="App">import Child from './Child.vue'
</script><style scoped>
.app{border-color: #ddd;border-radius:10px;padding:10px;box-shadow: 0 0 10px;
}
</style>

Child.vue

<template><div class="child"><h2>我是Child组件</h2><h3>当前sum求和为:{{ sum }}</h3><Hello/></div>
</template><script setup lang="ts">
import { ref } from 'vue'let sum = ref(0)</script><style scoped>
.child{background-color: skyblue;border-radius:10px;padding:10px;box-shadow: 0 0 10px;
}
</style>

Hello.vue

<template><h2 style="color:red">你好</h2>
</template><script setup lang="ts" ></script><style scoped></style>

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import Hello from './Hello.vue'// 创建应用
const app = createApp(App)app.component('Hello', Hello)// 挂载应用
app.mount('#app')
  • app.config

main.ts

app.config.globalProperties 添加 那么全局都可以使用

import { createApp } from 'vue'
import App from './App.vue'
import Hello from './Hello.vue'// 创建应用
const app = createApp(App)app.component('Hello', Hello)
app.config.globalProperties.x = 99//这样下面x就不会爆红
declare module 'vue' {interface ComponentCustomProperties {// $http: typeof axios// $translate: (key: string) => stringx: number}
}// 挂载应用
app.mount('#app')

比如:Child.vue 页面就会呈现 我是Child组件99 这里x会爆红 在main.ts添加定义部分

<template><div class="child"><h3>当前sum求和为:{{ sum }}</h3><Hello/></div>
</template><script setup lang="ts">
import { ref } from 'vue'let sum = ref(0)</script><style scoped>
.child{background-color: skyblue;border-radius:10px;padding:10px;box-shadow: 0 0 10px;
}
</style>
  • app.directive

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import Hello from './Hello.vue'// 创建应用
const app = createApp(App)app.directive('beauty', (element, { value }) => {element.innerText += valueelement.style.color = 'green'element.style.backgroundColor = 'yellow'
})// 挂载应用
app.mount('#app')

比如:Child.vue 页面就会呈现 不高兴0——黄色背景,绿色文字

<template><div class="child"><h2>我是Child组件{{ x }}</h2><h3>当前sum求和为:{{ sum }}</h3><h4 v-beauty="sum">不高兴</h4><Hello/></div>
</template><script setup lang="ts">
import { ref } from 'vue'let sum = ref(0)</script><style scoped>
.child{background-color: skyblue;border-radius:10px;padding:10px;box-shadow: 0 0 10px;
}
</style>
  • app.mount

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import Hello from './Hello.vue'
import type axios from 'axios'// 创建应用
const app = createApp(App)// 挂载应用
app.mount('#app')
  • app.unmount

main.ts 2秒钟之后 app消失在页面上

import { createApp } from 'vue'
import App from './App.vue'
import Hello from './Hello.vue'
import type axios from 'axios'// 创建应用
const app = createApp(App)// 挂载应用
app.mount('#app')setTimeout(() => {app.unmount()
}, 2000);
  • app.use

见router那一节 安装插件

//使用路由器
app.use(router)

Vue3的非兼容性改变

Vue2和Vue3区别

看vue官网:Breaking Changes | Vue 3 Migration Guide (vuejs.org)

  • 过渡类名v-enter 修改为 v-enter-from、过渡类名 v-leave 修改为 v-leave-from 。
  • keyCode 作为 v-on 修饰符的支持。
  • v-model 指令在组件上的使用已经被重新设计,替换掉了v-bind.sync。
  • v-if 和 v-for 在同一个元素身上使用时的优先级发生了变化。
  • 移除了 Son、 Soff 和 Sonce 实例方法。
  • 移除了过滤器 filter。
  • 移除了 $children 实例 propert。

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

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

相关文章

Springboot集成Netflix-ribbon、Enreka实现负载均衡-12

Netflix Ribbon简介 Netflix Ribbon是Netflix发布的云中间层服务开源项目&#xff0c;主要功能是提供客户端的软件负载均衡算法&#xff0c;将Netflix的中间层服务连接在一起。 具体来说&#xff0c;Ribbon是一个客户端负载均衡器&#xff0c;可以在配置文件中列出所有的服务…

ORACLE数据库一主多备DG环境(一对多)主备切换

本文主要分享一对多(一主多备)的DG环境主备切换的案例,我们的一套生产环境,一主四备,其中3个备库承载着查询业务,还有一个DG没有任务业务,由于主库的存储性能不给力,公司采购了新的存储,这个DG就是为了切换到新存储而搭建的,数据量1.5TB。 本文是在测试环境操作,之前…

【信息系统项目管理师】复习~第十五章

15.项目风险管理 每个项目都存在两个层面上的风险&#xff1a;①每个项目都有会影响项目达成目标的单个风险&#xff1b;②由单个风险和不确定性的其他来源联合导致的整体项目风险。项目风险会对项目目标产生负面或正面的影响&#xff0c;也就是风险与机会。项目风险管理旨在利…

PostgreSQL的学习心得和知识总结(一百四十三)|深入理解PostgreSQL数据库之Support event trigger for logoff

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

VirtualBox7安装ubantu server 22.04通过NAT+Only-Host双网卡实现宿主机与虚拟机互通

目录 背景环境安装虚拟机配置网卡修改ssh端口遇到的坑参考文章 背景 时间长没用docker了&#xff0c;有些命令都快忘了&#xff0c;心血来潮想着搞个docker玩一玩&#xff0c;所以需要先搞一个虚拟机&#xff0c;因为之前CentOS用的比较多&#xff0c;所以这次想试一试ubantu。…

『大模型笔记』AI教母李飞飞谈人工智能的前景与危险!

AI教母李飞飞谈人工智能的前景与危险! 文章目录 一. AI教母李飞飞谈人工智能的前景与危险!1. 总结2. 全文内容二. 参考文献油管原视频:https://www.youtube.com/watch?v=FW5CypL1XOY一. AI教母李飞飞谈人工智能的前景与危险! 1. 总结 以下是整理后的中文内容: 李飞飞博…

openlayers实现绘制图标,并实现图标的聚合功能

点聚合说明 点聚合功能是指将地图上密集的点数据聚合成一个更大的点或者其他形状&#xff0c;以改善地图的可视化效果和性能。点聚合功能通常用于在地图上显示大量的点标记&#xff0c;例如地图上的POI&#xff08;兴趣点&#xff09;、传感器数据等。通过点聚合功能&#xff…

Vue3 - 修改浏览器标题 htmlWebpackPlugin.options.title 的值

在 Vue CLI 4.x 中&#xff0c;htmlWebpackPlugin.options.title 是 HtmlWebpackPlugin 的一个选项&#xff0c;用于设置生成的 HTML 文件的标题。 你可以通过修改 vue.config.js 文件来修改这个选项。 以下是一个示例&#xff1a; module.exports {chainWebpack: config &…

[单机]成吉思汗3_GM工具_VM虚拟机

稀有端游成吉思汗1,2,3单机版虚拟机一键端完整版 本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#x…

[算法][数组][leetcode]2391. 收集垃圾的最少总时间

题目地址: https://leetcode.cn/problems/minimum-amount-of-time-to-collect-garbage/description/ 题解&#xff1a; class Solution {public int garbageCollection(String[] garbage, int[] travel) {int ans 0;//先计算收所有的垃圾需要多少时间for(String s :garbage){…

D - Another Sigma Problem(ABC)

思路&#xff1a;我们可以处理一个后缀来记录当前数a[i]需要乘上多少&#xff08;类似于1110这样的&#xff09;&#xff0c;然后对于当前位来说&#xff0c;对答案的贡献还要加上(i - 1) * a[i]&#xff0c;因为a[i]还要做前(i - 1)个数的后缀。 代码&#xff1a; #include &…

目标检测YOLO实战应用案例100讲-无监督领域自适应目标检测方法研究与应用(五)

目录 多源无监督领域自适应目标检测方法 4.1研究现状及问题形成 4.2相关工作详述

在Chisel中,`+%`运算符 模运算加法的妙用

在Chisel中&#xff0c;%是一个特殊的运算符&#xff0c;用于执行加法操作并且处理可能的溢出。这个运算符在硬件设计中很有用&#xff0c;因为它允许开发者明确控制当数值超出其表示范围时的行为。 加法和模运算加法 普通加法&#xff1a;在大多数编程语言和硬件描述语言中&…

【详细介绍下Visual Studio】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

vue3文件上传

样式&#xff1a; 可随意&#xff0c;通过获取组件toWake()方法即可 实现功能&#xff1a; 限制上传文件类型 限制上传文件大小 组件名称&#xff1a; autoUpload 实现代码: <!-- 通用文件上传按钮&#xff0c;解决原生样式无法修改问题 --> <!-- 参数介绍(可拓展…

Ubuntu24安装搜狗输入法,修复闪屏问题

下载deb安装包&#xff1a;搜狗输入法linux-首页 安装&#xff1a;sudo dpkg -i 1.deb 搜狗输入法linux-安装指导 重启&#xff0c;但是完成后闪烁。按以下步骤更改桌面配置。 sudo gedit /etc/gdm3/custom.conf 取消WaylandEnable的注释即可

Mysql中表的创建以及数据类型

DDL 在表结构的操作 表的创建 creat table 表名&#xff08; 字段1 字段类型 [约束] &#xff0c; 字段2 字段类型 [约束] &#xff09;[comment 标注释]; create table tb_user(id int comment ID,一行字段的唯一标识,username varchar(20) comment 用户名,name varchar(…

618洗地机推荐,市面上各式各样的洗地机怎么选?这里有答案

洗地机的出现极大地改变了清洁方式&#xff0c;通过结合扫地、拖地、吸尘等多种功能&#xff0c;实现了一机多用的便捷清洁体验。而且洗地机不需要弯腰&#xff0c;每次也不用清洁很长时间&#xff0c;节省出来的时间可以更好的休息&#xff0c;但是市面上各式各样的洗地机怎么…

iOS 提交项目到github(本地没有该项目)

流程简介 申请github账号&#xff08;如果有请跳过&#xff09; add repository创建项目开心的提交就好 具体过程 1. 申请账号&#xff08;本部分不做介绍&#xff0c;请自行研究&#xff09; 2. 如果有账号&#xff0c;按照下面图片依次操作就好 点击该图中的New reposito…

2024数维杯数学建模竞赛C题思路代码和论文分析

2024数维杯数学建模C题完整代码和成品论文已更新&#xff0c;获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/bgic2nbxs2h41pvt?singleDoc# 2024数维杯数学建模C题思路分析如下&#xff1a; 问题分析 整体题目分析: 这是一个关于评价天然气水合物资源量的建模问题…