vue2到vue3快速上手入门

作者:cz橙日期:2025/10/2

vue3

需要会vue2,该文档笔记基于黑马的课,进阶快速入门vue3
vue3 官方文档:https://v3.cn.vuejs.org/

main.js改变

1import { createApp } from 'vue'
2import App from './App.vue'
3
4const app = createApp(App)
5app.mount('#app') /* 挂载app到id为app的元素上 */
6

不需要new Vue(),直接createApp(App)

App.vue改变

  • script在前了,template在后,最后style
  • script中加入set up可以在script中直接编写组合式API
  • templat中允许多个元素,不再要求唯一根元素
  • style中加上scoped在当前组件起作用

组合式API

之前一直是选项式API,现在可以使用组合式API

setup

组合式API:一系列函数,组合起来实现功能
setup是入口函数,在组件创建之前调用
setup写法:

1<script>
2export default {
3  setup() {
4    
5    }
6  }
7</script>
8

该钩子执行时间比beforeCreate和created更早,setup中获取不到this

setup中提供的任何函数和变量,需要最后return{}才能使用.但多次return过于繁琐,于是有语法糖:

1<script setup>
2export default {
3  setup() {
4    const count = 0
5    function increment() {
6      count++
7    }
8  }
9}
10</script>
11

在script标签加上setup属性,就可以直接调用count和increment

reactive和ref

reactive: 响应式对象
ref: 响应式变量

  1. 从vue包中引入reactive
1import { reactive, ref } from 'vue'
2
  1. 使用reactive
1const state = reactive(对象类型数据)
2

接受一个对象类型数据,返回一个响应式对象,对象中的属性,属性值都会变成响应式
响应式对象: 当对象中的属性值发生改变时,会自动更新到视图中
reactive处理的是对象类型数据,不能处理简单类型数据

  1. 导入并使用ref
1import { ref } from 'vue'
2const count = ref(0)
3

接受一个简单/对象类型数据,返回一个响应式变量,变量的值会变成响应式
ref处理的是简单类型数据、对象类型数据
ref底层对简单类型数据进行了包装为对象再调用reactive,所以可以直接使用ref处理简单类型数据

注:

  • 脚本中访问数据需要通过.value来访问
  • 模板中访问数据不需要.value
  • 推荐统一使用ref处理数据
computed

步骤:

  1. 导入computed
1import { computed } from 'vue'
2
  1. 使用computed
1const doubleCount = computed(() => count.value * 2)
2
1const doubleCount = computed(() => {
2  get:() => count.value * 2
3  set:(val) => {
4    count.value = val / 2
5  }
6})
7
watch

步骤:

  1. 导入watch
1import { watch } from 'vue'
2
  1. 使用watch
1watch(count, (newVal, oldVal) => {
2  console.log(newVal, oldVal)
3})
4/*监听单个数据变化*/
5
1watch(
2  [count1, count2]
3  ([newVal1, newVal2]),[(oldVal1, oldVal2)] => {
4    函数体
5  }
6)
7/*监听多个数据变化*/
8
1/*额外配置对象写法*/
2const count = ref(0)
3watch (count, () => {
4  console.log('count:', count.value)
5}, {
6  immediate: true, /* 组件创建时立即调用 */
7  deep: true, /* 监听对象内部属性变化 */
8})
9
1/*精确侦听某个属性变化*/
2const info = ref({
3  name: '张三',
4  age: 18
5})
6
7watch(
8  () => info.value.age,
9  () => console.log('age:', info.value.age)
10)
11
生命周期钩子
  • setup: 组件创建之前调用
  • onBeforeMount: 组件挂载之前调用
  • onMounted: 组件挂载之后调用
  • onBeforeUpdate: 组件更新之前调用
  • onUpdated: 组件更新之后调用
  • onBeforeUnmount: 组件卸载之前调用
  • onUnmounted: 组件卸载之后调用
父子通信
父组件向子组件传递数据

语法:

1/* 父组件 */
2<script setup>
3  import sonComVue from './sonCom.vue'
4</script>
5
6<template>
7  <!-- 1.绑定属性 message-->
8  <sonComVue message="hello"></sonComVue>
9</template>
10

加冒号是变量绑定传递

1/* 子组件 */
2<script setup>
3  /* 通过defineProps编译器宏接受子组件传递的数据 */
4  const props = defineProps({
5    message: String
6  })
7<script>
8
9<template>
10  {{message}}
11</template>
12

props传过来的数据可以直接使用

defineProps原理:编译阶段的一个标识,实际编译器解析时,会进行编译转换为props选项

子组件向父组件传递数据
  • 父组件中给子组件标签通过@绑定事件
  • 子组件内部通过emit方法触发事件

语法:

1/* 子组件 */
2<script setup>
3  /* 通过defineEmits编译器宏定义子组件触发的事件 */
4  const emit = defineEmits(['get-message'])
5  const sendMsg = () => {
6    emit('get-message', 'hello')
7  }
8</script>
9
10<template>
11  <button @click="sendMsg">点击触发change事件</button>
12</template>
13

要触发的事件要放到defineEmits中

1/* 父组件 */
2<script setup>
3  import sonComVue from './sonCom.vue'
4  const handleGetMessage = (msg) => {
5    console.log(msg)
6  }
7</script>
8
9<template>
10  <!-- 1.绑定事件 get-message-->
11  <sonComVue @get-message="handleGetMessage"></sonComVue>
12</template>
13
模板引用

通过ref标识获取dom对象或组件实例对象
语法:

1/* 子组件 */
2<script setup>
3  const count = 999
4  const sayHi = () => {
5    console.log('hello')
6  }
7</script>
8
9<template>
10  <div ref="divRef">
11    测试组件 {{count}}
12  </div>
13</template>
14
1/* 父组件 */
2<script setup>
3  import { onMounted, ref } from 'vue'
4  import sonComVue from './sonCom.vue'
5  {/* 调用ref函数生成ref对象,通过ref标识绑定,通过ref对象.value访问绑定元素 */}
6  const input = ref(null)
7  onMounted(() => {
8    console.log(input.value)
9  })
10
11  const testRef = ref(null)
12  const getComponent = () => {
13    console.log(testRef.value)
14  }
15</script>
16
17<template>
18  <input ref="input" type="text">
19  <sonComVue ref="testRef"></sonComVue>
20  <button @click="getComponent">获取组件</button>
21</template>
22
defineExpose

默认下语法糖下组件内部属性和方法不开放给父组件访问,如果需要给父组件访问,需要通过defineExpose定义

语法:

1/* 子组件 */
2<script setup>
3  const count = 999
4  const sayHi = () => {
5    console.log('hello')
6  }
7  defineExpose({
8    count,
9    sayHi
10  })
11</script>
12
13<template>
14  <div ref="divRef">
15    测试组件 {{count}}
16  </div>
17</template>
18
1/* 父组件 */
2<script setup>
3  import { onMounted, ref } from 'vue'
4  import sonComVue from './sonCom.vue'
5  {/* 调用ref函数生成ref对象,通过ref标识绑定,通过ref对象.value访问绑定元素 */}
6  const input = ref(null)
7  onMounted(() => {
8    console.log(input.value)
9  })
10
11  const testRef = ref(null)
12  const getComponent = () => {
13    console.log(testRef.value.count)
14    testRef.value.sayHi()
15  }
16</script>
17
18<template>
19  <input ref="input" type="text">
20  <sonComVue ref="testRef"></sonComVue>
21  <button @click="getComponent">获取组件</button>
22</template>
23
provide和inject

顶层组件向任意底层组件传递数据和方法,实现跨层组件通信
语法:

1/* 顶层组件 */
2  /* provide ('key', 顶层组件的数据)*/
3<script setup>
4  import { provide } from 'vue'
5  provide('name', '张三')
6</script>
7
8<template>
9  <div>
10    <sonComVue></sonComVue>
11  </div>
12</template>
13
1/* 子组件 */
2  /* inject ('key') */
3<script setup>
4  import { inject } from 'vue'
5  const name = inject('name')
6</script>
7
8<template>
9  <div>
10    {{name}}
11  </div>
12</template>
13

vue3.3新特性

defineOptions

语法:

1defineOptions({
2  name: 'sonComVue'
3})
4

相当于替代组件的name属性

1export default {
2  name: 'sonComVue'
3}
4
defineModel

v-model语法糖相当于

1<child v-model="isVisiable">
2
3<child :modelValue="isVisiable" update:modelValue="isVisible=$event" >
4

而defineModel
语法:

1defineModel({
2  props: {
3    modelValue: {
4      type: String,
5      default: ''
6    }
7  },
8  emits: ['update:modelValue']
9})
10

语法:

1defineModel({
2  props: {
3    modelValue: String
4  },
5  emits: ['update:modelValue']
6})
7

pinia

pinia是vue的最新状态管理工具,是vuex替代品
优势:

  • API简单(去掉了mutation)
  • 去掉modules概念,每个store都是独立模块
  • 配合typescript更优化
  • 提供组合式风格API,与vue3统一

actions可以直接修改state了,且actions既支持异步又能修改一步。相当于把vuex的mutation好action合二为一

如何使用见官方文档
Pinia 官方文档

定义store

1import { defineStore } from 'pinia'
2
3//  `defineStore()` 的返回值的命名是自由的
4// 但最好含有 store 的名字,且以 `use` 开头,以 `Store` 结尾。
5// (比如 `useUserStore`,`useCartStore`,`useProductStore`)
6// 第一个参数是你的应用中 Store 的唯一 ID。
7export const useAlertsStore = defineStore('alerts', {
8  // 其他配置...
9})
10
  • 组合式写法中,getters用computed语法
1import { defineStore} from 'pinia'
2export const useAlertsStore = defineStore('alerts', {
3  doubleCount: computed(() => state.count * 2)
4  return {
5    doubleCount
6  }
7})
8
storeToRefs

直接解构pinia的store的数据会丢失响应式,因此用storeToRefs解决问题

1import { defineStore} from 'pinia'
2import { storeToRefs } from 'pinia'
3export const useAlertsStore = defineStore('alerts', {
4  doubleCount: computed(() => state.count * 2)
5  return {
6    doubleCount
7  }
8})
9
1const { doubleCount } = storeToRefs(useAlertsStore())
2console.log(doubleCount.value)
3doubleCount.value = 10
4

在useStore()之前,store实例不会创建,因此storeToRefs()会报错
解构方法一般不要用,因为是调用而不需要响应修改

持久化

pinia默认是不持久化的,需要安装插件pinia-plugin-persistedstate

1/* main.js */
2import { createPinia } from 'pinia'
3import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
4
5const pinia = createPinia()
6pinia.use(piniaPluginPersistedstate)
7

创建store时,将persist选项设置为true即可

选项式:

1import { defineStore } from 'pinia'
2
3export const useAlertsStore = defineStore('alerts', {
4  // 其他配置...
5  persist: true
6})
7

组合式加第三个参数:

1import { defineStore} from 'pinia'
2import { storeToRefs } from 'pinia'
3export const useAlertsStore = defineStore('alerts', {
4  doubleCount: computed(() => state.count * 2)
5  return {
6    doubleCount
7  }
8}, {
9  persist: true
10})
11

当然persist里面也可以配置更多参数,如:

1import { defineStore} from 'pinia'
2import { storeToRefs } from 'pinia'
3export const useAlertsStore = defineStore('alerts', {
4  doubleCount: computed(() => state.count * 2)
5  return {
6    doubleCount
7  }
8}, {
9  persist: {
10    enabled: true,          // 默认为true
11    key: 'pinia-key',      // 自定义key
12    strategies: [{
13      storage: window.sessionStorage  //切换localstorage为sessionStorage
14    }],
15    paths: ['count']  // 只持久化count属性
16  }
17})
18

具体看官方文档


vue2到vue3快速上手入门》 是转载文章,点击查看原文


相关推荐


Mock数据与真实API的无缝切换:联调阶段的核心技术
_5792025/10/2

在现代软件开发中,尤其是在多系统、多平台的应用环境下,如何高效地进行数据集成和接口联调一直是一个挑战。随着开发流程的不断优化,Mock数据和真实API的无缝切换成为了开发和测试过程中的一个关键环节。本文将详细探讨如何实现Mock数据与真实API的无缝切换,并分享在联调阶段的核心技术及最佳实践。??Mock数据与真实API的背景概述在开发初期,API的设计和实现往往会滞后于前端界面的开发。此时,为了保证前端开发能够顺利进行,开发人员通常会使用Mock数据来模拟真实API的响应。这种方法可以帮助开发


没电脑=不能写代码?为什么我一个高中生能在手机上码 1万多行 C++,造了一个 GUI 库和一款肉鸽游戏?
Gamexyrs10/2/2025

当所有人都在说手机编程不可能,当别人在电脑上用 VS 欻欻欻敲代码时,我用 MT 管理器敲屏幕编代码,用 C4Droid编译打包程序。做了自己的界面库,做了自己的游戏。这篇文章主要介绍了我是怎么单凭手机一步步走过来的,也想为跟我相似的人提供一些方法。支持开源:所有代码已在 Github 开源,可在文章末尾链接查看。


Redis 内存淘汰策略 LRU 和传统 LRU 差异
程序员小29/30/2025

最近没被用过的,下次也大概率用不上。举个例子:你电脑桌面上放着常用的软件图标(微信、IDE),这些是最近常用的;而几个月没打开过的压缩工具,会被你拖到文件夹里。这就是 LRU 的思路:保留最近使用的,淘汰最近最少使用的。❝假设缓存容量只有 3,依次存入 A、B、C,此时缓存是 [A,B,C];若此时访问 A(A 变成最近使用),缓存顺序变为 [B,C,A]若再存入D(缓存满了),需要淘汰最近最少使用的 B,最终缓存是 [C,A,D]LFU的全称是。


【大数据毕设项目】基于大数据的茅台股票市场风险评估与可视化分析平台毕设源码\Hadoop+Spark茅台股票数据分析与预测平台
大数据毕设指导师9/30/2025

本文介绍了基于大数据的贵州茅台股票数据分析系统开发项目。项目利用Python、Spark、Hadoop等技术,构建了一个集成化的股票分析平台,包含价格趋势分析、技术指标分析、成交量分析等功能模块。系统通过数据挖掘和机器学习技术,为投资者提供全面、实时的市场分析,支持可视化展示。文章详细说明了项目背景、技术方案、核心内容及关键代码实现,展示了成交量趋势分析和价格区间分布的可视化效果。该项目为金融投资决策提供了科学依据,具有重要的实践价值。


介绍一种新的向量存储格式:DiskBBQ
Elastic 中国社区官方博客2025/10/3

作者:来自 Elastic Benjamin Trent, John Wagster 及 Ignacio Vera Sequeiros 介绍 DiskBBQ,一种 HNSW 的替代方案,并探讨何时以及为何使用它。 测试 Elastic 的领先开箱即用能力。深入我们的示例笔记本,开始免费的云试用,或立即在本地机器上尝试 Elastic。 DiskBBQ 是 Inverted Vector File (IVF) 索引的进化版。它是 Hierarchical Navigable Sm


UNIX下C语言编程与实践5-C 语言编译器 cc(gcc/xlc)核心参数解析:-I、-L、-D 的使用场景与实例
迎風吹頭髮2025/10/4

一、引言:为什么需要关注 cc 编译器参数? 在 UNIX 环境下,C 语言编译器(如 gcc、xlc,统一简称 cc)是开发的核心工具。当项目规模超过单个文件、依赖第三方库或需要条件编译时,仅靠默认编译命令(如 cc main.c -o main)会频繁遇到「头文件找不到」「库链接失败」「宏定义未生效」等问题。 本文聚焦 cc 编译器中最核心的三个参数:-I(加载头文件路径)、-L(加载库文件路径)、-D(宏定义),结合实际项目案例解析其作用、使用场景及常见问题,同时拓展其他实用参数,帮助


DrissionPage爬取汽车之家:(车名 + 颜色 + 车辆型号/续航里程)
python全栈蛇行者2025/10/5

DrissionPage爬取汽车之家 效果展示 项目概述与背景 在当今大数据时代,网络数据采集已成为获取信息的重要手段。本教程将全面详细介绍如何使用Python的DrissionPage库结合其他工具爬取汽车之家网站(https://www.autohome.com.cn/price/levelid_1)的汽车数据。汽车之家作为国内领先的汽车资讯平台,包含了丰富的汽车信息数据,这些数据对于汽车市场分析、竞品研究、价格监控等具有重要价值。 本项目旨在通过自动化技术手段,高效地采集汽


【玩泰山派】4、制作ubuntu镜像-(5)总结制作ubuntu22.04镜像+5.10内核流程
风为你而吹2025/10/7

文章目录 前言rk镜像概念rk镜像构成生成sd卡镜像 制作根文件系统流程概述文件概述执行流程执行./mk-base-debian.sh执行mk-buster-rootfs.sh执行./mk-image.sh 总结 使用docker容器基于鲁班猫的仓库制作泰山派的ubuntu22.04根文件系统前言流程制作docker镜像启动docker容器进入容器进入容器后执行step1.准备step2.构建基础 Ubuntu 系统。step3.添加 rk overlay 层,并打包ubuntu


前端必看!12个JS神级简写技巧,代码效率直接飙升80%,告别加班!
刘大华2025/10/8

前言 哈喽大家好,我是大华。 在日常开发中,我们经常会遇到一些重复、冗长的代码。写起来费劲,读起来费神,维护起来更是头疼。而且代码越复杂,性能可能越受影响。 那有没有办法让代码更简洁、清晰又高效呢? JavaScript提供了许多现代语法特性,合理使用这些简写技巧,不仅能大幅减少代码量,还能提升可读性和执行效率。 很多资深前端都在用,这篇文章整理了 12 个最实用的 JS 简写技巧,并结合实际场景进行优化和补充,帮助你写出更优雅的代码。 1. 短路运算符:替代简单的 if 判断 以前我们这样写


AI辅助制作宣传视频
Enabler_Rx2025/10/10

首先写好文字稿子,然后用google gemini模型生成音频。可以选择很多种人声,我选择了language English(US)和callirrhoe的发声,模型文生音频链接: https://cloud.google.com/text-to-speech?hl=zh-CN 然后下载音频文件 使用Microsoft Clipchamp打开音频文件,插入图像内容,可以调节音频速度,加入字幕等 然后导出生成文件 完成!

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0