从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 更加友好。




3. props

3.1 语法

使用defineProps宏函数声明


3.2 命名格式

在setup中推荐 camelCase。


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


3.3 props校验

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

4. emit

4.1 语法


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中,可以直接使用


5.3.2 从Store解构

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


你可能感兴趣的:(javascript,vue.js,前端)