当前位置: 首页 > article >正文

从vue2过渡到vue3

1. 响应式基础

1.1 基础语法

  1. ref()
import { ref } from 'vue'

// 基本类型
const count = ref(0)
// 对象类型
const obj = ref({ name: 'Vue' })

// 访问/修改
console.log(count.value) // 0
count.value++
  1. reactive()
import { reactive } from 'vue'

// 只能处理对象类型
const state = reactive({
  count: 0,
  user: { name: 'John' }
})

// 访问/修改
console.log(state.count) // 0
state.count++

1.2 特性

特性ref()reactive()
适用类型所有类型仅对象/数组
访问方式需要 .value直接访问属性
模板自动解包自动解包(无需 .value直接使用属性名
TypeScript 支持更好的类型推断复杂对象类型需要明确类型定义
响应式保持始终保持引用替换整个对象会丢失响应式

1.3 典型使用场景

1. ref() 更适合:
  • 基本类型数据(string/number/boolean)
  • 需要保持引用的响应式对象
  • 需要传递到组件外部的响应式值
  • 需要直接替换整个对象时
2. reactive() 更适合:
  • 复杂对象结构(嵌套对象/数组)
  • 局部状态管理(不需要暴露到组件外)
  • 需要直接操作属性的对象
  • 需要自动深度响应式的场景

2. 注册

2.1 全局注册

全局注册可以在当前Vue应用全局可用

// src/plugins/myPlugin.js
import MyComponentA from '../components/MyComponentA.vue';
import MyComponentB from '../components/MyComponentB.vue';

export const MyPlugin = {
  install(app, options = {}) {
    // 全局注册组件
    app.component('MyComponentA', MyComponentA);
    app.component('MyComponentB', MyComponentB);

    // 根据选项自定义行为
    if (options.customDirective !== false) {
      app.directive('focus', {
        mounted(el) {
          el.focus();
        }
      });
    }

    // 可以添加更多基于选项的功能
  }
}
// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import MyPlugin from './plugins/myPlugin';

const app = createApp(App);

// 使用插件并传入配置项
app.use(MyPlugin);

app.mount('#app');

2.2 局部注册

局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。它的优点是使组件之间的依赖关系更加明确,并且对 tree-shaking 更加友好。

<script setup>
import ComponentA from './ComponentA.vue'
</script>

<template>
  <component-a />
</template>

3. props

3.1 语法

使用defineProps宏函数声明

<script setup>
const props = defineProps({
 title: String,
 likes: Number
})

console.log(props.foo)
</script>

3.2 命名格式

在setup中推荐 camelCase。

<script setup>
const props = defineProps({
  greetingMessage: String
})
</script>

在模板中推荐使用kebab-case。

<template>
	<MyComponent :greeting-message />
</template>

3.3 props校验

defineProps({
	title: {
		type: String,
		default: '',
	},
  likes: {
		type: Number,
		required: true
	},
	interest: {
		type: Object,
		default: () => {}
	}
})

4. emit

4.1 语法

<script setup>
const emit = defineEmit(['submit', 'login'])
const submit = () => {
  emit('submit', 'hello')
}
</script>

5. pinia

5.1 安装pinia

pnpm install pinia

创建pinia实例,并且使用

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')

5.2 定义store

在setup下的store

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

useCounterStore是在其他组件引用的的名字

import { useCountStore } from '@/store/count.js'

useCounterStore这个返回函数的名称是通常是use开头Store结尾。

counter是这个仓库的唯一Id,Pinia 将用它来连接 store 和 devtools。

  • ref() 就是 state 属性
    const count = ref(0),count就是这个仓库存的数据
  • computed() 就是 getters
    就是计算属性,只完成计算逻辑
  • function() 就是 actions
    在这里完成同步或者异步的逻辑书写

5.3 使用store

5.3.1 直接使用

在setup中,可以直接使用

<script setup>
import { useCounterStore } from '@/stores/counter'
// 可以在组件中的任意位置访问 `countStore` 变量 ✨
const countStore = useCounterStore()
const addCount = computed(()=> countStore.doubleCount)
</script>

5.3.2 从Store解构

如果从Store中直接解构变量和计算属性,它们会失去响应式特性,为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上:

<script setup>
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// `name` 和 `doubleCount` 是响应式的 ref
// 同时通过插件添加的属性也会被提取为 ref
// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { name, doubleCount } = storeToRefs(store)
// 作为 action 的 increment 可以直接解构
const { increment } = store
</script>

http://www.kler.cn/a/613930.html

相关文章:

  • SQL server中的事务与锁
  • 【HCIA-网工探长】07:IP基础与ARP拓展笔记
  • Flutter环境搭建
  • MYTOOL-笔记
  • HTML应用指南:利用POST请求获取全国小鹏汽车的充电桩位置信息
  • 深度学习框架PyTorch——从入门到精通(9)PyTorch简介
  • 揭秘大数据 | 13、大数据的五大问题 之 数据科学
  • Python实现图片文字识别-OCR
  • cJSON- API 深度解析:设计理念与实现原理(二)
  • 前端 Overflow hidden与auto切换时页面右移的问题解决 Antd Drawer打开关闭时位置偏移的问题的解决
  • 【微服务架构】本地负载均衡的实现(基于权重算法)
  • Css环形旋转立体感动画
  • iOS自定义collection view的page size(width/height)分页效果
  • 软件需求未明确非功能性指标(如并发量)的后果
  • Docker 部署 Redis 集群学习记录
  • 26考研——树与二叉树_树、森林(5)
  • 怎么解决父元素高度塌陷
  • 从零到一:ESP32与豆包大模型的RTC连续对话实现指南
  • Java 开发中的 AI 黑科技:如何用 AI 工具自动生成 Spring Boot 项目脚手架?
  • scikit-learn 线性回归:函数、原理、优化与实例解析