Vue3笔记——(一)

001.教程简介
1.采用方式ts+组合式API+setup语法糖
2.核心内容:ref、reactive、computed、watch、生命周期…
3.常用内容:hooks、自定义ref、路由、pinia、mitt…
4.面试:组件通信、响应式相关API…

002.Vue3
2020.9.18发布3.0(性能好、速度快、打包小)
003.创建Vue3工程
1.基于webpack vue-cli创建

vue --version
npm install -g @vue/cli
Vue create vue_test

2.基于vite创建
优点:轻量快速、对ts、jsx、css开箱即用不用配置
创建:(1)npm create vue@latest (2)npm i
*注意:安装node
项目名称:不能出现中文和特殊字符,最好纯小写英文字母+数字+下划线
文件路径.vscode==>extensions.json配置着插件[eg:]

{ “recommendations”: [“Vue.volar”] }

env.d.ts 声明各种类型文件让ts认识.jpg、.txt等文件
index.html 入口文件
vite.config.ts配置插件配置代理
3.插件名称:TypeScript Vue Plugin (Volar) 极简插件
004编写App组件
1.Vue3支持多个根标签
2.Vue3不支持this
3.setup函数比beforeCreate还要早
4.setup语法糖写法

<script setup lang='ts'></script>

5.重命名组件名称

安装插件
npm i vite-plugin-vue-setup-extend -D vite config.ts
配置插件
1)import VueSetupExtend from “vite-plugin-vue-setup-extend”;
2)追加调用VueSetupExtend( )
3)script标签中添加name

005 ref创建基本类型响应式数据
ref创建:基本类型的响应式数据
作用:定义响应式变量。
语法:let xxx= ref(初始值)
返回值:一个RefImpl的实例对象,简称ref对象或ref,ref对象的value属性是响应式的。
注意点:
js中操作数据需要:xxx.value,但模版中不需要.value,直接使用即可
对于let name = ref(‘张三’)来说,name 不是响应式的,name.value是响应式的
006 reactive创建对象类型响应式数据
reactive只能定义创建对象类型的响应式数据
简单对象、数组对象、
注意点:可以深层次对象进行响应式

007 ref对比reactive
ref ======>基本 对象
reactive ======>对象
区别:
1.ref创建的变量必须使用.value【使用volar插件可以自动添加value,设置中Volar勾选Auto Insert:Dot Value】
2.reactive重新分配一个新的对象,会失去响应式,可以使用Object.assign去整体替换
使用原则:
1.若需要一个基本类型的响应式数据,必须使用ref
2.若需要一个响应式对象,层级不深,ref、reactive都可以
3.若需要一个响应式对象,且层级较深,推荐使用reactive

008 toRefs与toRef
toRefs,toRef将解构数据进行响应式

let person = reactive({name: "zhangsan",age: 18,className: "3年2班",favarate: "爱踢足球",family: {mother: "大美丽",father: "大英俊"}
})let { name, age, className, favarate, family } = toRefs(person);
const {mother,father} = toRefs(family.value)
let nl = toRef(person,'age')

009 computed计算属性

<template><div><input v-model="xing"/><br/><input v-model="ming"/><br/>姓名:<span>{{xingMing}}</span><button @click="changFullName">修改全名</button></div>
</template>
<script setup lang='ts'>
import { ref, reactive, toRefs, computed } from 'vue'
let xing = ref("")
let ming = ref("")
// 这么定义的xingming不可修改
let xingMing = computed({get(){return xing.value+ming.value},set(val){let [val1,val2] = val.split("-");xing.value = val1;ming.value = val2;}
})
function changFullName(){xingMing.value  = "张-三"
}
</script>

010 computed计算属性
特点:vue3中的watch只能监视以下4种数据:

1.ref定义的数据
2.reactive定义的数据
3.函数返回一个值(getter函数)
4.一个包含上述内容的数组

五种情况

1.监视ref定义的【基本类型】数据,直接写数据名即可,监视的是其value值的改变

写法:函数返回的是一个停止监听的函数
watch(谁,回调函数(新的值,旧的值)=>{})
代码示例<div class="person">·<h2>情况一:监视ref定义的基本类型</h2>当前求和为{{ sum }}<button @click="changeSum">点我sum+1</button></div>
<script>// 监视,情况一:监视ref定义的基本类型
// 数据
let sum = ref(0);
// 方法
function changeSum() {sum.value++;
}
// 监视,情况一:监视ref定义的基本类型 两个参数【监视对象,回调函数】
// *注意sum不用写value
const stopwatch = watch(sum, (newVal, oldVal) => {console.log("求和数据发生了变化", newVal, oldVal);if (newVal > 10) stopwatch()
})
console.log('监视方法返回值', stopwatch);
</script >

2.监视ref定义的【对象类型】数据,监视的是对象的地址值,若想监视对象内容属性的变化,需要手动开启深度模式;
*immediate:true 立即修改,开发时避免参数中写"新的值"、“旧的值”,直接写value

写法:
watch(谁,回调函数(新的值,旧的值)=>{},{deep:true})
代码示例:
// 监视,情况二:监视ref定义的对象类型
let person = ref({name: "张三",age: 18
})
function changeName() {person.value.name += '@'
}
function changeAge() {person.value.age++;
}
function changePerson() {person.value = {name: "zhangsan",age: 0}
}
//监视的是对象的地址值,若想 监视对象内部属性的值需要开启深度监视
watch(person, (newVal, oldVal) => {console.log("person变化", newVal, oldVal);
}, { deep: true, immediate: true })

3.监视reactive定义的对象类型,数据,且默认开启了深度监视,不可以关闭

    <div class="person"><h2>情况三:监视reactive定义的对象类型</h2>姓名{{ reactivePerson.name }}<br />年龄{{ reactivePerson.age }}<button @click="reactivechangeName">reActive修改名字</button><button @click="reactivechangeAge">reActive修改年龄</button><button @click="reactivechangePerson">reActive修改整个人</button><h2>测试数据{{ testData.a.b.c.d }}</h2><button @click="changeTest">修改测试数据</button></div>
// 监视,情况三:监视reactive定义的对象类型
let reactivePerson = reactive({name: "张三",age: 18
})
let testData = reactive({a: {b: {c: {d: "测试数据"}}}
})
function reactivechangeName() {reactivePerson.name += '@'
}
function reactivechangeAge() {reactivePerson.age++;
}
function reactivechangePerson() {Object.assign(reactivePerson, {name: "zhangsan",age: 0})
}
// 监视reactive定义的对象类型,数据,且默认开启了深度监视,不可以关闭
watch(reactivePerson, (newVal, oldVal) => {console.log("reactivePerson", newVal, oldVal);
})
function changeTest() {testData.a.b.c.d = "修改了test数据"
}
watch(testData, () => {console.log("监听到了修改的测试数据");
})

4.监视ref或reactive定义的【对象类型】数据中的某个属性,注意点如下:

(1).若该属性值不是【对象类型】(基本类型),需要写成函数形式
(2).若该属性值是依然是【对象类型】,可直接编,也可写成函数,注意:直接写整体改变不能监听到,建议写成:函数式需要深度监听
结论:监视的要是对象里的属性,最好是函数形式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视

    <div class="person"><h2>情况四对象属性</h2>姓名{{ qingkuang4.name }}<br />年龄{{ qingkuang4.age }}<br />汽车{{ qingkuang4.car.c1 }}、{{ qingkuang4.car.c2 }}<br /><button @click="qingkuang4changename">reActive修改名字</button><br /><button @click="qingkuang4changeage">reActive修改年龄</button><br /><button @click="qingkuang4changeonecar">修改第一台车</button><br /><button @click="qingkuang4changetwocar">修改第二台车</button><br /><button @click="qingkuang4changeallcar">修改整个车</button></div>
// 监视,情况四:监视reactive定义的对象类型属性
// 数据
let qingkuang4 = reactive({name: "张三",age: 18,car: {c1: '奔驰',c2: '宝马'}
})
function qingkuang4changename() {qingkuang4.name += "#";
}
function qingkuang4changeage() {qingkuang4.age++;
}
function qingkuang4changeonecar() {qingkuang4.car.c1 = "奥迪"
}
function qingkuang4changetwocar() {qingkuang4.car.c2 = "大众"
}
function qingkuang4changeallcar() {qingkuang4.car = {c1: '雅迪',c2: '艾玛'}
}
// 若该属性值不是【对象类型】(基本类型),需要写成函数形式
watch(() => qingkuang4.name, (newVal,oldVal) => {console.log("改变了对象属性name",newVal,oldVal);
})
// 若该属性值是依然是【对象类型】,可直接编,也可写成函数
// 注意:直接写整体改变不能监听到,建议写成:函数式需要深度监听
// watch(qingkuang4.car,()=>{
//     console.log("改变了对象属性car直接写");
// })
watch(() => qingkuang4.car, () => {console.log("改变了对象属性car函数式");
}, { deep: true })

5.监视上述的多个数据

watch([xxx,xxx,xxxx],(newVal,oldVal)=>{console.log("改变了######",newVal,oldVal);
},{deep:true})
xxx是直接写还是函数取决于xxx的类型
    <div class="person"><h2>情况五:监视上述多个数据数组</h2>姓名{{ zonghe.name }}<br />年龄{{ zonghe.age }}<br />汽车{{ zonghe.car.c1 }}、{{ zonghe.car.c2 }}<br /><button @click="zonghechangename">reActive修改名字</button><br /><button @click="zonghechangeage">reActive修改年龄</button><br /><button @click="zonghechangeonecar">修改第一台车</button><br /><button @click="zonghechangetwocar">修改第二台车</button><br /><button @click="zonghechangeallcar">修改整个车</button></div>
let zonghe = reactive({name: "张三",age: 18,car: {c1: '奔驰',c2: '宝马'}
})
function zonghechangename() {zonghe.name += "#";
}
function zonghechangeage() {zonghe.age++;
}
function zonghechangeonecar() {zonghe.car.c1 = "奥迪"
}
function zonghechangetwocar() {zonghe.car.c2 = "大众"
}
function zonghechangeallcar() {zonghe.car = {c1: '雅迪',c2: '艾玛'}
}
watch([() => zonghe.name, () => zonghe.car.c1], (newVal, oldVal) => {console.log("改变了######", newVal, oldVal);
},{deep:true})

011 watchEffect
立即运行一个函数,同时响应式地追踪依赖,并在依赖更改时重新执行该函数
watch对比watchEffect
1.都能监听响应式数据变化,不同的是监听数据变化的方式不同
2.watch要明确指出监视的数据
3.watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些数据)

<template><div>温度:{{ temp }}<br />湿度:{{ shidu }}<br /><button @click="changeVal1">改变温度</button><button @click="changeVal2">改变湿度</button></div>
</template>
<script setup lang='ts'>
import { ref, reactive, toRefs, watchEffect } from "vue";
let temp = ref(0);
let shidu = ref(0);
function changeVal1() {temp.value++;
}
function changeVal2() {shidu.value++;
}
watchEffect(() => {if (temp.value > 10) {console.log("温度过高了");}if (shidu.value > 10) {console.log("湿度过高了");}
})
</script>

012 标签的ref属性

挂在普通标签输入当前元素

<template><div><h3 ref="h3tag">我是h3标签</h3><button @click="outputContent">输出</button></div>
</template>
<script setup lang='ts'>
import { ref, reactive, toRefs } from 'vue'
let h3tag = ref();
function outputContent(){console.log(h3tag.value);//<h3>我是h3标签</h3>
}
</script>

挂在组件上输入组件实例,需要在子组件上导出父组件才可看见

Parent.vue

<template><Child ref="haizi"/><button @click="outputContent">输入</button>
</template>
<script setup lang='ts'>
import {ref} from 'vue'
import Child from './Child.vue'
let haizi = ref();
function outputContent(){let refTemp = haizi.value;console.log(refTemp.b);
}
</script>

Child.vue

<template><div>子组件</div>
</template>
<script setup lang='ts'>
import { ref} from 'vue'
let a = ref(0)
let b = ref(1)
let c = ref(2)
defineExpose({a,b,c})
</script>

013TS自定义类型

// 定义一个接口用于限制Person的具体属性
export interface PersonInter {id: string;name: string;age: number;
}
// 自定义类型写法1
// export type Personns = Array<PersonInter>;
// 自定义类型写法2
export type Personns = PersonInter[];
<script setup lang="ts" name="person">
import { type PersonInter,type Personns } from '@/types'
let person: PersonInter = {id: "xxxx",name: '张三',age: 1
}
console.log(person);
// 自定义类型写法1
let demoList:Personns = [{ id: "xxxx", name: '张三', age: 18 },{ id: "xxxx", name: '李四', age: 5 },{ id: "xxxx", name: '王五', age: 1 },
]

014 props父传子数据
App.vue

<template><Person a="哈哈" b="嘿嘿" :list="personList"/>
</template>
<script lang="ts" setup name="APP">
import Person from './components/preson.vue'
import { reactive } from 'vue'
import { type Personns } from '@/types'
let personList = reactive<Personns>([{ id: 'xxxx', name: '张三', age: 18 },{ id: 'xxxx', name: '李四', age: 20 },{ id: 'xxxx', name: '王五', age: 22, x: 9 },
])
// let personList = 5
</script>

types/index.js

// 定义一个接口用于限制Person的具体属性
export interface PersonInter {id: string;name: string;age: number;x?: number;
}
// 自定义类型第1种写法
// export type Personns = Array<PersonInter>;
// 自定义类型第2种写法
export type Personns = PersonInter[];

preson.vue

<template><div><ul><li v-for="item in list" :key="item.id">{{ item.name }}</li></ul></div>
</template>
<script setup lang="ts" name="person">
import {withDefaults } from 'vue';
import { type Personns } from '@/types'
// 1.只接收list,不能输出
// defineProps(['list'])// 2.接收list,可以输出
/* let x = defineProps(['a', 'b', 'list'])
console.log(x.a) */// 2.接收list + 类型限制
/* defineProps<{ list: Personns,xxx:yyy }>() */// 3.接收list + 限制类型+限制必要性 + withDefaults指定默认值
// defineProps宏函数可以不用引用
withDefaults(defineProps<{ list?: Personns }>(), {list: () => [{ id: '默认id', name: '默认名字', age: 19 }]
})
</script>

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

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

相关文章

设计模式的艺术-代理模式

结构性模式的名称、定义、学习难度和使用频率如下表所示&#xff1a; 1.如何理解代理模式 代理模式&#xff08;Proxy Pattern&#xff09;&#xff1a;给某一个对象提供一个代理&#xff0c;并由代理对象控制对原对象的引用。代理模式是一种对象结构型模式。 代理模式类型较多…

计算机网络 (54)系统安全:防火墙与入侵检测

前言 计算机网络系统安全是确保网络通信和数据不受未经授权访问、泄露、破坏或篡改的关键。防火墙和入侵检测系统&#xff08;IDS&#xff09;是维护网络系统安全的两大核心组件。 一、防火墙 定义与功能 防火墙是一种用来加强网络之间访问控制的特殊网络互联设备&#xff0c;它…

three.js+WebGL踩坑经验合集(3):THREE.Line的射线检测问题(不是阈值方面的,也不是难选中的问题)

笔者之所以要在标题里强调不是阈值方面&#xff0c;是因为网上的大多数文章提到线的射线检测问题&#xff0c;90%以上的文章都说是因为线太细所以难选中&#xff0c;然后让大家把线的阈值调大。 而本文所要探讨的问题则恰好相反&#xff0c;不是难选中&#xff0c;而是在某些角…

省市区三级联动

引言 在网页中&#xff0c;经常会遇到需要用户选择地区的场景&#xff0c;如注册表单、地址填写等。为了提供更好的用户体验&#xff0c;我们可以实现一个三级联动的地区选择器&#xff0c;让用户依次选择省份、城市和地区。 效果展示&#xff1a; 只有先选择省份后才可以选择…

Mono里运行C#脚本36—加载C#类定义的成员变量和方法的数量

前面分析了加载类和基类的基本过程, 接着来分析一下加载成员变量和方法的数量。 因为我们知道C#语言定义一个类,主要就是定义成员变量,以及那些对此成员变量进行操作的方法, 所以需要使用一种方法来描述C#语言定义类的能力。 一般情况下,主要有两种类型: 普通的类,比如前…

快速搭建深度学习环境(Linux:miniconda+pytorch+jupyter notebook)

本文基于服务器端环境展开&#xff0c;使用的虚拟终端为Xshell。 miniconda miniconda是Anaconda的轻量版&#xff0c;仅包含Conda和Python&#xff0c;如果只做深度学习&#xff0c;可使用miniconda。 [注]&#xff1a;Anaconda、Conda与Miniconda Conda&#xff1a;创建和管…

BGP分解实验·11——路由聚合与条件性通告(3)

续接上&#xff08;2&#xff09;的实验。其拓扑如下&#xff1a; 路由聚合的负向也就是拆分&#xff0c;在有双出口的情况下&#xff0c;在多出口做流量分担是优选方法之一。 BGP可以根据指定来源而聚合路由&#xff0c;在产生该聚合路由的范围内的条目注入到本地BGP表后再向…

ray.rllib-入门实践-11: 自定义模型/网络

在ray.rllib中定义和使用自己的模型&#xff0c; 分为以下三个步骤&#xff1a; 1. 定义自己的模型。 2. 向ray注册自定义的模型 3. 在config中配置使用自定义的模型 环境配置&#xff1a; torch2.5.1 ray2.10.0 ray[rllib]2.10.0 ray[tune]2.10.0 ray[serve]2.10.0 numpy1.23.…

攻防世界easyRSA

解密脚本&#xff1a; p473398607161 q4511491 e17def extended_euclidean(a, b):if b 0:return a, 1, 0gcd, x1, y1 extended_euclidean(b, a % b)x y1y x1 - (a // b) * y1return gcd, x, ydef calculate_private_key(p, q, e):phi (p - 1) * (q - 1)gcd, x, y extend…

常见的多媒体框架(FFmpeg GStreamer DirectShow AVFoundation OpenMax)

1.FFmpeg FFmpeg是一个非常强大的开源多媒体处理框架&#xff0c;它提供了一系列用于处理音频、视频和多媒体流的工具和库。它也是最流行且应用最广泛的框架&#xff01; 官方网址&#xff1a;https://ffmpeg.org/ FFmpeg 的主要特点和功能&#xff1a; 编解码器支持: FFmpe…

.NET MAUI进行UDP通信(二)

上篇文章有写过一个简单的demo&#xff0c;本次对项目进行进一步的扩展&#xff0c;添加tabbar功能。 1.修改AppShell.xaml文件&#xff0c;如下所示&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <Shellx:Class"mauiDemo.AppShel…

selenium xpath定位一组元素中的某一个

(//div[starts-with(class,‘abcolumn-light__listCell‘)])[4] 注意&#xff1a;一定要加小括号&#xff0c;然后再加索引号

linux系统中的 scp的使用方法

SCP&#xff08;Secure Copy Protocol&#xff09;是一种通过加密的方式在本地主机和远程主机之间安全地传输文件的协议。 它是基于SSH协议的扩展&#xff0c;允许用户在不同主机之间进行文件复制和传输&#xff0c;是Linux和Unix系统中常用的工具之一。 在嵌入式Linux软件的…

计算机网络之链路层

本文章目录结构出自于《王道计算机考研 计算机网络_哔哩哔哩_bilibili》 02 数据链路层 在网上看到其他人做了详细的笔记&#xff0c;就不再多余写了&#xff0c;直接参考着学习吧。 1 详解数据链路层-数据链路层的功能【王道计算机网络笔记】_wx63088f6683f8f的技术博客_51C…

YOLOv11改进,YOLOv11检测头融合DSConv(动态蛇形卷积),并添加小目标检测层(四头检测),适合目标检测、分割等任务

前言 精确分割拓扑管状结构例如血管和道路,对各个领域至关重要,可确保下游任务的准确性和效率。然而,许多因素使任务变得复杂,包括细小脆弱的局部结构和复杂多变的全局形态。在这项工作中,注意到管状结构的特殊特征,并利用这一知识来引导 DSCNet 在三个阶段同时增强感知…

SQL 指南

SQL 指南 引言 SQL(Structured Query Language,结构化查询语言)是一种用于管理关系数据库系统的标准计算机语言。自1970年代问世以来,SQL已经成为了数据库管理和数据操作的事实标准。本文旨在为初学者和有经验的数据库用户提供一个全面的SQL指南,涵盖SQL的基础知识、高级…

Lucene常用的字段类型lucene检索打分原理

在 Apache Lucene 中&#xff0c;Field 类是文档中存储数据的基础。不同类型的 Field 用于存储不同类型的数据&#xff08;如文本、数字、二进制数据等&#xff09;。以下是一些常用的 Field 类型及其底层存储结构&#xff1a; TextField&#xff1a; 用途&#xff1a;用于存储…

Node.js的解释

1. Node.js 入门教程 1.1 什么是 Node.js&#xff1f; 1.1.1 Node.js 是什么&#xff1f; Node.js 是一个基于 JavaScript 的开源服务器端运行时环境&#xff0c;允许开发者用 JavaScript 编写服务器端代码。与传统的前端 JavaScript 主要运行在浏览器端不同&#xff0c;Nod…

Flutter android debug 编译报错问题。插件编译报错

下面相关内容 都以 Mac 电脑为例子。 一、问题 起因&#xff1a;&#xff08;更新 Android studio 2024.2.2.13、 Flutter SDK 3.27.2&#xff09; 最近 2025年 1 月 左右&#xff0c;我更新了 Android studio 和 Flutter SDK 再运行就会出现下面的问题。当然 下面的提示只是其…

TDengine 做为 FLINK 数据源技术参考手册

Apache Flink 是一款由 Apache 软件基金会支持的开源分布式流批一体化处理框架&#xff0c;可用于流处理、批处理、复杂事件处理、实时数据仓库构建及为机器学习提供实时数据支持等诸多大数据处理场景。与此同时&#xff0c;Flink 拥有丰富的连接器与各类工具&#xff0c;可对接…