关于VUE3的一些基础知识点笔记

news/2025/3/26 1:31:18/

关于VUE3的一些基础知识点笔记

VUE3

vue2与vue3的一个重要区别是vue2是选项式API(composition API)而vue3是组合式API(option API)。

组合式API就是所有逻辑都在setup函数中,使用ref、watch等函数来组织代码,而不像vue2中分别写在data、methods、watch等配置选项中。有可复用、易于维护等优点。

vue3的生命周期

与vue2对比:created钩子变成setup函数了,其他的都加了on

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qv5xKhAR-1685463643360)(C:\Users\28132\AppData\Roaming\Typora\typora-user-images\1685460357487.png)]

用的时候需要先导入函数

如:

<template><div>生命周期函数</div>
</template>
<script setup>import { onMounted } from "vue";// 生命周期函数:组件渲染完毕onMounted(()=>{console.log('onMounted触发了')})onMounted(()=>{console.log('onMounted也触发了')})
</script>

1.setup函数

  • setup 函数是 Vue3 特有的选项,作为组合式API的起点
  • 从组件生命周期看,它在 beforeCreate 之前执行
  • 函数中 this 不是组件实例,是 undefined,所有的vue3项目中几乎没有this,都是通过函数来获取
  • 下面的例子可以先只看setup部分,15行的setup函数里面写的所有逻辑都需要用return来返回出来才可以在模板中使用
<template><div>{{ name }}num: {{ obj.num }}<br>ref: {{ refNum }}<br>refObj:{{ refObj.name }}<button @click="btn">按钮</button></div>
</template><script >
import { reactive, ref } from 'vue'
export default {setup () {// 普通对象不是双向绑定let name = "嘻嘻嘻"// reactive将里面的数据变成响应式数据 ,注意要导入,一般解决复杂数据类型转换响应式数据const obj = reactive({num: 1})// ref 定义简单数据类型和复杂数据类型为响应式数据//  ref简单数据类型const refNum = ref(1)//  ref复杂数据类型const refObj = ref({ name: 'jack' })/*** 是对象建议用reactive 其他用ref*/const btn = function () {obj.num++refNum.value++}return { name, obj, btn, refNum, refObj }},}
</script><style></style>

setup语法糖的使用来简化代码

  • 下面的写法是在script标签中写,定义的num可以直接使用
  • script setup 中的顶层变量都可以在模板使用,数据,函数,组件。
<template><div>{{ num }}</div>
</template><script lang="ts" setup>
let num = 1</script><style></style>

2. reactive函数

  • reactive 函数通常定义复杂类型的响应式数据,参数必须是对象或者数组,如果要让对象的某个元素实现响应式时比较麻烦。需要使用toRefs(后面会说)
  • reactive的响应式是深层次的,reactive方法内部是利用ES6的Proxy API来实现的,底层本质是将传入的数据转换为Proxy对象

使用步骤:

  • vue 中导出 reactive 函数
  • setup 函数中,使用 reactive 函数,传入一个普通对象,返回一个响应式数据对象
  • 最后 setup 函数返回一个对象,包含该响应式对象即可,模板中可使用
<template><div><p>姓名:{{state.name}}</p><p>年龄:{{state.age}}</p></div>
</template><script>
// 1. 导入函数
import { reactive } from "vue"; 
export default {setup() {// 2. 创建响应式数据对象const state = reactive({ name: 'sunny', age: 24 })// 3. 返回数据return { state }}
};
</script>

toRefs函数 保持响应式

  • 在使用reactive创建的响应式数据被展开或解构的时候使用toRefs保持响应式
<template><div>这是vue3的框架!<br> obj: {{ name }}{{ age }}<br> <button @click="btn"></button></div>
</template>
<script setup>
import { reactive, toRefs } from "vue";
let obj = reactive({name: 'jack',age: 1
})
// obj是reactive的响应式数据,
// 使用了解构后就不是响应式的了
// 用toRefs转换成响应式数据
const { name, age } = toRefs(obj)const btn = function () {name.value = 'rose',age.value++
}
</script>
<style></style>

3.ref 函数

3.1 ref定义数据

  • ref通常用来定义响应式数据,不限类型
  • ref响应式原理是依赖于Object.defineProperty()get()set()的。
  • ref参数一般接收简单数据类型,若ref接收对象为参数,本质上会转变为reactive方法,系统会自动根据我们给ref传入的值转换成ref(1)->reactive({value:1}) ,ref函数只能操作浅层次的数据,把基本数据类型当作自己的属性值;深层次依赖于reactive

使用步骤:

  • vue 中导出 ref 函数
  • setup 函数中,使用 ref 函数,传入普通数据(简单or复杂),返回一个响应式数据
  • 最后 setup 函数返回一个对象,包含该响应式数据即可
  • 注意:在template中访问,系统会自动添加.value;在js中需要手动.value
<template><div><p>计数器:{{ count }}<button @click="count++">累加1</button><!-- template中使用可省略.value --><button @click="increment">累加10</button></p></div>
</template><script>
// 1. 导入函数
import { ref } from "vue";
export default {setup() {// 2. 创建响应式数据对象const count = ref(0);const increment = () => {// js中使用需要.valuecount.value += 10;};// 3. 返回数据return { count, increment };},
};
</script>
  • reactive与ref该如何选择?

如果能确定数据是对象且字段名称也确定,可使用 reactive 转成响应式数据,其他一概使用 ref

ref使用起来有点麻烦呀,需要.value 增加代码量,所以确认是复杂数据类型咱就用reactive

3.2 ref 获取DOM元素

  • 元素上使用 ref属性关联响应式数据,获取DOM元素
<script setup>
import { ref } from 'vue'
const hRef = ref(null) 
//在onMounted钩子中来获取dom元素
onMounted(()=>{console.log(dom)
})</script><template><div><h1 ref="dom">我是盒子</h1></div>
</template>

3.3 ref操作组件-defineExpose

  • 组件上使用 ref属性关联响应式数据,获取组件实例
  • 使用 <script setup> 的组件是默认关闭的,组件实例使用不到顶层的数据和函数。
  • 需要配合 defineExpose 暴露给组件实例使用,暴露的响应式数据会自动解除响应式。

子组件:将数据与方法暴露出去

<template><div><h1>son</h1></div>
</template>
<script setup>// 子向父传数据
let num = 1
let str = 'son'
const handle = function () {return '123son321'
}
// 要让父组件获取数据与方法,需要用defineExpose({})将数据暴露出去,参数是对象
defineExpose({ num, str, handle })
</script>
<style></style>

父组件:使用子组件暴露出来的方法与数据

<template><div>这是父组件<Son ref="sonDom"></Son></div>
</template>
<script setup>
import Son from './components/son.vue'
import { ref, onMounted } from "vue";
// 获取子组件的数据与方法
const sonDom = ref()
onMounted(() => {console.log(sonDom.value);console.log('Son的num值:', sonDom.value.num); //1console.log('Son的str值:', sonDom.value.str); //sonconsole.log('Son的handle方法:', sonDom.value.handle()); //123son321
})
</script>
<style></style>

4. computed函数

  • 定义计算属性

大致步骤:

  • vue 中导出 computed 函数
  • setup 函数中,使用 computed 函数,传入一个函数,函数返回计算好的数据
  • 最后 setup 函数返回一个对象,包含该计算属性数据即可,然后模板内使用
<template><div>{{ total }}4111</div>
</template>
<script setup>
import { computed } from 'vue'
// 计算属性
let arr = [12, 45, 65, 32, 12]
const total = computed(() => {return arr.reduce((sum, item) => sum + item, 0)
})
console.log(total);
</script>
<style></style>

小例子:动态求和:

<template><div>{{ arr }}:{{ total }}<input v-model="num" type="text" @change="handle" placeholder="请输入数字" /></div>
</template>
<script setup>
import { computed, ref } from 'vue'
// 计算属性
let arr = ref([12, 45, 65, 32, 12])
const total = computed(() => {return arr.value.reduce((sum, item) => (sum += Number(item)), 0)
})let num = ref(0)
const handle = () => {arr.value.push(num.value)
}
// console.log(total);
</script>
<style></style>

5.watch函数

  • 使用watch函数监听数据的变化
  • watch(需要监听的数据,数据改变执行函数,配置对象) 来进行数据的侦听
  • 数据:单个数据,多个数据,函数返回对象属性,属性复杂需要开启深度监听
  • 配置对象:deep 深度监听 immediate 默认执行

见代码中的注释:

<template><div>num:{{ num }} <br>obj:{{ obj }} <br><button @click="btn">点我加1</button></div>
</template>
<script setup>
import { ref, reactive, watch } from 'vue'
let num = ref(0)
const btn = function () {return num.value++, obj.id++
}
let obj = reactive({ id: 1, name: 'jack' })
// watch监听数据 watch(基本数据类型 || 数组 || 回调函数, 回调函数 , 配置项)// 1. 监听基本数据类型
// watch(num, (newVal, oldVal) => {
//   console.log('newVal:', newVal, '===oldVal', oldVal);
// })// 2.监听整个复杂数据类型 只能监听到新值,旧值无法显示
// watch(obj, (newVal, oldVal) => {
//   console.log('newVal:', newVal, '===oldVal', oldVal);
// })// 3.监听复杂数据类型的某一项数据,第一项改为函数
// watch(() => obj.id, (newVal, oldVal) => {
//   console.log('newVal:', newVal, '===oldVal', oldVal);
// })// 4.同时监听简单数据类型和复杂数据类型,第一项改为数组
watch([() => obj.id, num], (newVal, oldVal) => {console.log('newVal:', newVal, '===oldVal', oldVal);
})
/**i* * newVal: (2) [2, 1] ===oldVal (2) [1, 0]newVal: (2) [3, 2] ===oldVal (2) [2, 1]newVal: (2) [4, 3] ===oldVal (2) [3, 2]newVal: (2) [5, 4] ===oldVal (2) [4, 3]*/
</script>
<style></style>
  • 使用 watch 监听,配置默认执行:

  •   {// 开启深度监听deep: true,// 默认执行一次immediate: true
    }
    

6. 父传子与子传父(defineProps与defineEmits)

  • 实现组件通讯中的父子组件通讯

子组件:

<template><div><h1>son</h1><button @click="toFather">子向父传值</button></div>
</template>
<script setup>
// 父传子---子接收:
const props = defineProps({name: String,num: String
})
console.log(props);
console.log(props.name, props.num);
//--------------------
// 子向父传值
const emit = defineEmits(['sonHandle'])
const toFather = function () {emit('sonHandle', '我是子组件son')
}</script>
<style></style>

父组件:

<template><div><Son name="sunny" :num="num" @sonHandle="sonHandle($event)"></Son>===</div>
</template>
<script setup>
import Son from './components/son.vue'
import { ref } from "vue";
const num = ref('123')
const sonHandle = (e) => {console.log(e);
}
</script>
<style></style>

在这里插入图片描述


http://www.ppmy.cn/news/109896.html

相关文章

Flask-RESTful的使用

Flask-RESTful的使用 Flask-RESTful基本使用安装定义资源Resources创建API实例添加资源到API运行Flask应用 请求处理请求解析参数校验 响应处理数据序列化定制返回格式 其他功能蓝图装饰器集合路由命名规范路由名称 Flask-RESTful Flask-RESTful是一个用于构建RESTful API的扩展…

jvisualvm ssl远程连接JVM

jvisualvm 远程ssl连接 一、没认证的 JMX连接 (不安全) 这种方式&#xff0c;仅限于测试环境&#xff0c;可以这样操作。生产环境为了安全起见&#xff0c;还是要使用带认证的方式连接。 远程jar包服务 启动时 java -jar [jvm参数] xx.jar添加JVM参数 java -jar -Xmx512M -Xms2…

一图看懂 tqdm 模块:一个可在循环和命令行中使用的快速、可扩展的进度条,资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 tqdm 模块&#xff1a;一个可在循环和命令行中使用的快速、可扩展的进度条&#xff0c;资料整理笔记&#xff08;大全&#xff09; &#x1f9ca;摘要&#x1f9ca;模块图&…

代码随想录算法训练营第三十九天|62.不同路径 63. 不同路径 II

目录 LeeCode 62.不同路径 深度搜索法 动态规划法 数论方法 LeeCode 63. 不同路径 II LeeCode 62.不同路径 62. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 深度搜索法 思路&#xff1a;机器人走过的路径可以抽象为一棵二叉树&#xff0c;而叶子节点就是终点…

20230530----重返学习-redux工程化-react-redux-高阶组件

day-081-eighty-one-20230530-redux工程化-react-redux-高阶组件 redux工程化 redux工程化就是模块化开发。 工程化步骤 redux工程化的第一种方式&#xff1a;拆分和合并reducer。 把各个可以状态集群reducer独立放到单个js文件中。使用combineReducers合并拆分出去的reduce…

【Leetcode -746.使用最小花费爬楼梯 -747.至少是其他数字两倍的最大数】

Leetcode Leetcode -746.使用最小花费爬楼梯Leetcode -747.至少是其他数字两倍的最大数 Leetcode -746.使用最小花费爬楼梯 题目&#xff1a;给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择…

黑马Redis视频教程实战篇(三)

目录 一、优惠券秒杀 1.1 全局唯一ID 1.2 Redis实现全局唯一ID 1.3 添加优惠卷 1.4 实现秒杀下单 1.5 库存超卖问题分析 1.6 代码实现乐观锁解决超卖问题 1.7 优惠券秒杀-一人一单 1.8 集群环境下的并发问题 二、分布式锁 2.1 基本原理和实现方式对比 2.2 Redis分布…

gradle的例子

以下是一个详细的Gradle示例代码&#xff0c;用于构建和管理Java项目&#xff1a; build.gradle文件&#xff1a; plugins {id java }group com.example version 1.0-SNAPSHOTsourceCompatibility 1.8repositories {mavenCentral() }dependencies {implementation org.apach…