You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue 3是否支持实现类似Angular-Services的服务机制?

Vue3 原生支持实现这类跨组件共享的响应式服务,不需要额外hack手段,核心是利用独立于组件树的响应式单例实现状态共享,任意组件修改状态后,所有引用该状态的组件视图都会自动同步更新。

实现方案

轻量场景:独立响应式单例(零依赖)

你只需要把要共享的对象/数组用reactive包裹,在单独的文件中导出为单例,所有组件引入同一份实例即可,修改时所有引用的组件视图会自动同步,和AngularJS服务的行为完全一致。

  1. 先创建独立的服务文件,比如src/services/todoService.ts:
import { reactive } from 'vue'

// 全局单例响应式数组,所有引入的组件共享同一份状态
export const todoList = reactive<Array<{id: number, content: string, done: boolean}>>([
  {id: 1, content: '迁移AngularJS旧服务', done: false}
])

// 封装状态操作方法,和AngularJS服务的方法逻辑完全对齐
export function addTodo(content: string) {
  todoList.push({
    id: Date.now(),
    content,
    done: false
  })
}

export function toggleTodo(id: number) {
  const target = todoList.find(item => item.id === id)
  if (target) target.done = !target.done
}

export function deleteTodo(id: number) {
  const idx = todoList.findIndex(item => item.id === id)
  if (idx > -1) todoList.splice(idx, 1)
}
  1. 任意组件直接引入使用即可,比如组件A负责新增数据:
<!-- 组件A:新增待办 -->
<script setup lang="ts">
import { ref } from 'vue'
import { addTodo } from '@/services/todoService'
const inputVal = ref('')
const handleAdd = () => {
  if (!inputVal.value.trim()) return
  addTodo(inputVal.value)
  inputVal.value = ''
}
</script>

<template>
  <div>
    <input v-model="inputVal" placeholder="输入待办内容" />
    <button @click="handleAdd">添加</button>
  </div>
</template>

组件B负责展示、操作列表:

<!-- 组件B:展示待办列表 -->
<script setup lang="ts">
import { todoList, toggleTodo, deleteTodo } from '@/services/todoService'
</script>

<template>
  <ul>
    <li v-for="item in todoList" :key="item.id">
      <input type="checkbox" :checked="item.done" @change="toggleTodo(item.id)" />
      <span :style="{textDecoration: item.done ? 'line-through' : 'none'}">{{ item.content }}</span>
      <button @click="deleteTodo(item.id)">删除</button>
    </li>
  </ul>
</template>

这种方案的特点:

  • 零额外依赖,代码量极小
  • 支持所有响应式操作:数组的push/splice等变更方法、数组内对象的属性修改、深层嵌套属性修改都能自动触发视图更新
  • 逻辑可以完全按照你之前AngularJS服务的组织方式编写,迁移成本极低

中大型项目:Pinia状态管理

如果你的共享状态逻辑复杂,需要状态变更追踪、持久化、模块化拆分、权限控制等能力,直接用Vue官方推荐的Pinia即可,它本质就是基于Vue响应式系统封装的全局状态方案,完全匹配你的需求。

  1. 安装依赖后在入口文件注册:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
app.use(createPinia())
app.mount('#app')
  1. 创建对应服务的状态模块:
// src/stores/todo.ts
import { defineStore } from 'pinia'
export const useTodoStore = defineStore('todo', {
  state: () => ({
    list: [] as Array<{id: number, content: string, done: boolean}>
  }),
  actions: {
    addTodo(content: string) {
      this.list.push({id: Date.now(), content, done: false})
    },
    toggleTodo(id: number) {
      const target = this.list.find(item => item.id === id)
      if (target) target.done = !target.done
    },
    deleteTodo(id: number) {
      this.list = this.list.filter(item => item.id !== id)
    }
  }
})

组件中引入调用即可,所有状态修改会全局同步,同时支持在Vue Devtools中追踪每一次状态变更,调试效率更高。

注意:如果需要在组件中解构共享的响应式状态,请用toRefs包裹后再解构,否则会丢失响应性。

AngularJs中的组件与对象

内容的提问来源于stack exchange,提问作者mmyta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:15:34