diff --git a/backend/app/db/models.py b/backend/app/db/models.py
index b841b7a..0e6812b 100644
--- a/backend/app/db/models.py
+++ b/backend/app/db/models.py
@@ -27,5 +27,5 @@ class Kintone(Base):
id = Column(Integer, primary_key=True, index=True)
type = Column(Integer, index=True, nullable=False)
name = Column(String(100), nullable=False)
- desc = Column(String(500))
- content = Column(String(2000))
\ No newline at end of file
+ desc = Column(String)
+ content = Column(String)
\ No newline at end of file
diff --git a/backend/app/main.py b/backend/app/main.py
index b792b7f..0175c69 100644
--- a/backend/app/main.py
+++ b/backend/app/main.py
@@ -10,7 +10,7 @@ from app.db import Base,engine
from app.core.auth import get_current_active_user
from app.core.celery_app import celery_app
from app import tasks
-
+from fastapi.middleware.cors import CORSMiddleware
Base.metadata.create_all(bind=engine)
@@ -18,6 +18,19 @@ app = FastAPI(
title=config.PROJECT_NAME, docs_url="/api/docs", openapi_url="/api"
)
+origins = [
+ "http://localhost:9000",
+ "http://localhost",
+ "http://localhost:8080",
+]
+
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=origins,
+ allow_credentials=True,
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
# @app.middleware("http")
# async def db_session_middleware(request: Request, call_next):
diff --git a/document/Kinton APIイベント一覧.xlsx b/document/Kinton APIイベント一覧.xlsx
new file mode 100644
index 0000000..190e95e
Binary files /dev/null and b/document/Kinton APIイベント一覧.xlsx differ
diff --git a/document/Kintone機能整理.drawio b/document/Kintone機能整理.drawio
new file mode 100644
index 0000000..e69de29
diff --git a/document/Kintone自動化ツール設計図.drawio b/document/Kintone自動化ツール設計図.drawio
new file mode 100644
index 0000000..5c5b1ae
--- /dev/null
+++ b/document/Kintone自動化ツール設計図.drawio
@@ -0,0 +1,1000 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/document/kintone開発自動化 MVP開発内容 SEサービスデザイングループ 2023.pptx b/document/kintone開発自動化 MVP開発内容 SEサービスデザイングループ 2023.pptx
new file mode 100644
index 0000000..e512497
Binary files /dev/null and b/document/kintone開発自動化 MVP開発内容 SEサービスデザイングループ 2023.pptx differ
diff --git a/frontend/README.md b/frontend/README.md
index 6d6096c..4dea4d1 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -47,3 +47,7 @@ quasar build
### Customize the configuration
See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js).
+
+## VUE3.0编程规范
+1. [VUE3.0编程概要](./VUE3.0概要.md)
+2. [VUE3.0编程规范](./VUE3.0-coding-rule.md)
diff --git a/frontend/VUE3.0-coding-rule.md b/frontend/VUE3.0-coding-rule.md
new file mode 100644
index 0000000..2bf920a
--- /dev/null
+++ b/frontend/VUE3.0-coding-rule.md
@@ -0,0 +1,241 @@
+以下是一份 Vue 3 和 TypeScript 的编程规范:
+
+**1. 组件定义**
+
+- 推荐使用 `defineComponent` 来定义组件,以获取 TypeScript 的类型支持。
+
+```typescript
+import { defineComponent } from 'vue'
+
+export default defineComponent({
+ // 组件选项
+})
+```
+
+**2. 数据定义**
+
+- 使用 `reactive` 定义响应式对象。
+- 使用 `ref` 定义响应式单值。
+- 使用 `computed` 定义计算属性。
+
+```typescript
+import { reactive, ref, computed } from 'vue'
+
+const state = reactive({
+ count: 0,
+ message: 'Hello Vue 3'
+})
+
+const count = ref(0)
+
+const doubledCount = computed(() => state.count * 2)
+```
+
+**3. 生命周期钩子**
+
+- 使用 `onMounted`、`onUpdated` 等生命周期钩子,而不是 `beforeCreate`、`created`、`beforeMount`、`mounted`、`beforeUpdate`、`updated`、`beforeUnmount`、`unmounted`。
+
+```typescript
+import { onMounted } from 'vue'
+
+onMounted(() => {
+ console.log('Component is mounted.')
+})
+```
+
+**4. 组件通信**
+
+- 使用 `props` 和 `emit` 实现父子组件通信。
+- 使用 `provide` 和 `inject` 实现祖先和后代组件通信。
+- 不再推荐使用 `event bus` 进行任意组件间的通信,可以使用 Vuex 或者全局 `provide`/`inject` 替代。
+
+```typescript
+// 父组件
+
+
+// 子组件
+this.$emit('my-event', eventData)
+```
+
+**5. 异步处理**
+
+- 使用 `async/await` 进行异步处理。
+- 使用 `Suspense` 和 `async setup()` 处理异步依赖。
+
+```typescript
+import { ref, onMounted } from 'vue'
+import axios from 'axios'
+
+onMounted(async () => {
+ const response = await axios.get('https://api.example.com/data')
+ data.value = response.data
+})
+```
+
+**6. Vue Router 和 Vuex**
+
+- 使用 Vue Router 4 和 Vuex 4,它们是为 Vue 3 重新设计的。
+- 使用 `useRouter` 和 `useRoute` 钩子函数在组件中使用 router。
+- 使用 `useStore` 钩子函数在组件中使用 Vuex store。
+
+```typescript
+import { useStore } from 'vuex'
+import { useRouter } from 'vue-router'
+
+const store = useStore()
+const router = useRouter()
+```
+
+**7. 组件模板**
+
+- 使用 `v-model` 代替 `.sync` 修饰符进行双向绑定。
+- 使用 `v-for` 和 `:key` 渲染列表。
+- 使用 `v-if` 和 `v-else`、`v-else-if` 进行条件渲染。
+- 使用 `v-on` 或者 `@` 监听事件。
+- 使用 `v-bind` 或者 `:` 绑定属性。
+
+```html
+
+ If block
+ Else block
+
+
+
+
+
+```
+
+8. **使用类型注解和接口**
+
+ 在 TypeScript 中,尽可能使用类型注解和接口来提供更完善的类型信息和类型检查。这将有助于发现和预防错误。
+
+ ```typescript
+ interface User {
+ name: string;
+ age: number;
+ }
+
+ const user: User = {
+ name: 'John',
+ age: 30
+ }
+ ```
+
+9. **模块化和组件化**
+
+ 尽可能将功能和逻辑模块化和组件化,使得代码更易于理解和维护。特别是使用 Composition API 时,可以将公共的逻辑封装成 composable 函数。
+
+ 下面是一个使用 `Suspense` 和 `axios` 的示例,这个示例将会从一个 JSON Placeholder API 获取数据:
+
+ 首先,我们创建一个 composable 函数,用于获取数据:
+
+ ```typescript
+ import { ref } from 'vue'
+ import axios from 'axios'
+
+ export function useAsyncData(url: string) {
+ const data = ref(null)
+ const error = ref(null)
+
+ const fetchData = async () => {
+ try {
+ const response = await axios.get(url)
+ data.value = response.data
+ } catch (e) {
+ error.value = e
+ }
+ }
+
+ return { data, error, fetchData }
+ }
+ ```
+
+ 然后,我们创建一个 Vue 组件来使用这个函数:
+
+ ```js
+
+
+
+ {{ error.message }}
+ {{ data }}
+
+
+ Loading...
+
+
+
+
+
+
+
+ ```
+
+ 在这个示例中,我们在 `useAsyncData` 函数中获取数据。当 `onMounted` 钩子函数被调用时(也就是当组件挂载完成后),我们开始获取数据。这个过程是异步的,因此我们在 `Suspense` 组件的 `#fallback` 插槽中显示一个 "Loading..." 的提示。一旦数据加载完成,`Suspense` 组件的 `#default` 插槽就会被渲染,并显示获取到的数据。
+
+10. **良好的代码风格**
+
+ 遵循一致的代码风格和代码质量规则,例如使用 ESLint 和 Prettier 来检查和格式化代码。
+
+11. **单元测试和端到端测试**
+
+ 对关键的组件和函数编写单元测试,对用户的主要操作路径编写端到端测试,确保功能的正确性。
+
+12. **注释和文档**
+
+ 对复杂的逻辑和函数编写注释,提供必要的项目文档,帮助其他开发者理解和使用你的代码。
+
+13. **以下是 Vue 2 中被废弃或改变的部分API,以及在 Vue 3 中的替代方案:**
+
+| Vue 2.x | Vue 3.0 | 说明 |
+| --- | --- | --- |
+| `Vue.set` / `this.$set` | 响应式数据现在是默认的,无需使用这些方法 | Vue 3 的响应式系统是从头开始构建的,所有的对象和数组都是响应式的 |
+| `Vue.delete` / `this.$delete` | 无需使用这些方法 | 在 Vue 3 中,你只需要使用 `delete` 操作符即可 |
+| `filters` | 无对应项 | Vue 3 不再支持过滤器,建议使用计算属性或方法替代 |
+| `Vue.observable` | `reactive` | 用 `reactive` 替代 `Vue.observable`,实现数据的响应式 |
+| `Vue.prototype` | `app.config.globalProperties` | 在 Vue 3 中,全局 API 已经改变,`Vue.prototype` 被 `app.config.globalProperties` 替代 |
+| `Vue.component`, `Vue.directive`, `Vue.mixin`, `Vue.use` | `app.component`, `app.directive`, `app.mixin`, `app.use` | 全局注册的 API 改变,如 `Vue.component` 变为 `app.component` |
+| `beforeDestroy` 和 `destroyed` 生命周期钩子 | `beforeUnmount` 和 `unmounted` | 生命周期钩子名字变化,`beforeDestroy` 和 `destroyed` 分别改为 `beforeUnmount` 和 `unmounted` |
+| `$on`, `$off`, `$once` | 无对应项 | Event Bus方法被移除,需要用户自行实现或者使用第三方库 |
+| `v-model` 在自定义组件上使用 | 需要明确的 `modelValue` 和 `update:modelValue` | Vue 3 对 `v-model` 的改动使其在自定义组件上更具灵活性 |
+| `functional` 选项 | 无对应项 | Vue 3 不再支持函数式组件的写法,而是推荐使用 `render` 函数或 `setup` 函数 |
+| 异步组件的 `functional` 写法 | `defineAsyncComponent` | 异步组件的创建方式更改,通过 `defineAsyncComponent` 方法创建 |
+| `destroyed` 和 `beforeDestroy` 钩子函数 | `unmounted` 和 `beforeUnmount` | 生命周期钩子的名称已改为更直观的名称,以更好地表示其在组件实例生命周期中的角色 |
+| `Vue.extend` | `defineComponent` | Vue 3 使用 `defineComponent` 方法定义组件,有更好的类型推断 |
+
+注意:Vue 3 对于 Options API 和 Composition API 提供了完全的支持,你可以在一个组件中混合使用这两种 API。不过,为了代码的一致性和可读性,建议在一个项目中选择一种 API 并坚持使用。
+
+
+- **以下是 Vue 3.0 中的 Composition API 函数的基本说明,以及与 Options API 的对比**
+
+| Composition API | 说明 | 对应的 Options API |
+| --------------- | ---- | ------------------ |
+| `setup` | `setup` 是一个新引入的组件选项,用于使用 Composition API。它是组件内部使用 Composition API 的入口。| 无 |
+| `ref` | `ref` 函数用于创建一个响应式的数据。它接收一个参数,返回一个响应式的 Ref 对象。| `data` |
+| `reactive` | `reactive` 函数用于创建一个响应式的对象。它接收一个普通对象,返回一个响应式的对象。| `data` |
+| `computed` | `computed` 函数用于创建一个计算属性。它接收一个 getter 函数或者一个具有 getter 和 setter 的对象,返回一个响应式的 Ref 对象。| `computed` |
+| `watch` | `watch` 函数用于响应式地跟踪和触发副作用。它接收一个响应式的源和一个执行副作用的回调函数。| `watch` |
+| `watchEffect` | `watchEffect` 函数用于立即执行传入的一个函数,并响应式地追踪其依赖,并在其依赖变更时重新运行该函数。 | 无 |
+| `onMounted` | `onMounted` 函数在组件被挂载时调用。它接收一个在组件挂载后执行的回调函数。 | `mounted` |
+| `onUnmounted` | `onUnmounted` 函数在组件被卸载时调用。它接收一个在组件卸载后执行的回调函数。 | `beforeDestroy`/`unmounted` |
+| `onUpdated` | `onUpdated` 在组件更新后调用。它接收一个在组件更新后执行的回调函数。| `updated` |
+| `provide` | `provide` 函数用于在组件上定义一个可以被后代组件注入的值。它接收一个提供的键和值。 | 有,与 `provide/inject` 相似但是属性而不是函数 |
+| `inject` | `inject` 函数用于在组件中注入一个由祖先组件提供的值。它接收一个注入的键。 | 有,但与 `provide/inject` 相似但是属性而不是函数 |
+
+值得注意的是,虽然一些 Composition API 函数与 Options API 的某些选项有相似之处,但它们的工作方式和使用方式可能有所不同。在实际使用中,你需要根据具体的使用场景和需求选择合适的 API。
diff --git a/frontend/src/components/ActionList.vue b/frontend/src/components/ActionList.vue
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/src/components/ActionSelect.vue b/frontend/src/components/ActionSelect.vue
new file mode 100644
index 0000000..9bf184a
--- /dev/null
+++ b/frontend/src/components/ActionSelect.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+
diff --git a/frontend/src/components/ActionSetting.vue b/frontend/src/components/ActionSetting.vue
new file mode 100644
index 0000000..c1af22e
--- /dev/null
+++ b/frontend/src/components/ActionSetting.vue
@@ -0,0 +1,83 @@
+
+
+
+
+ Our Changing Planet
+ by John Doe
+
+
+
+ 設定
+ 削除
+
+
+
{if(!showMenu) showAdd = false;}">
+
+
+
+
+
+
+
+ New tab
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/AppSelect.vue b/frontend/src/components/AppSelect.vue
new file mode 100644
index 0000000..1bd5e92
--- /dev/null
+++ b/frontend/src/components/AppSelect.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
diff --git a/frontend/src/components/FieldSelect.vue b/frontend/src/components/FieldSelect.vue
new file mode 100644
index 0000000..a1dd443
--- /dev/null
+++ b/frontend/src/components/FieldSelect.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
diff --git a/frontend/src/components/ShowDialog.vue b/frontend/src/components/ShowDialog.vue
new file mode 100644
index 0000000..b8a6560
--- /dev/null
+++ b/frontend/src/components/ShowDialog.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+ {{ name }}選択
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/pages/RuleEditor.vue b/frontend/src/pages/RuleEditor.vue
index c274ec9..2d515d0 100644
--- a/frontend/src/pages/RuleEditor.vue
+++ b/frontend/src/pages/RuleEditor.vue
@@ -9,41 +9,67 @@
-
-
-
-
- {{ action }}
-
-
-
-
+
+
+
+
+ {{ action }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/pages/testQursar.vue b/frontend/src/pages/testQursar.vue
index 80ca0fc..d475877 100644
--- a/frontend/src/pages/testQursar.vue
+++ b/frontend/src/pages/testQursar.vue
@@ -1,13 +1,88 @@
-
+
-
+
+
-
-
diff --git a/frontend/src/router/routes.ts b/frontend/src/router/routes.ts
index 6d5fc12..dedc963 100644
--- a/frontend/src/router/routes.ts
+++ b/frontend/src/router/routes.ts
@@ -9,16 +9,13 @@ const routes: RouteRecordRaw[] = [
{ path: 'ruleEditor', component: () => import('pages/RuleEditor.vue') },
{ path: 'flowEditor', component: () => import('pages/FlowEditorPage.vue') }
],
+ children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
+ },
+ {
+ path: '/test/',
+ children: [{ path: '', component: () => import('pages/testQursar.vue') }],
+ component: () => import('layouts/MainLayout.vue'),
},
- // {
- // path: '/ruleEditor/',
- // component: () => import('layouts/MainLayout.vue'),
- // children: [{ path: '', component: () => import('pages/RuleEditor.vue') }],
- // },
- // {
- // path: '/flowEditor/',
- // component: () => import('layouts/FlowEditorPage.vue'),
- // },
// Always leave this as last one,
// but you can also remove it
diff --git a/frontend/vue3.0概要.md b/frontend/vue3.0概要.md
new file mode 100644
index 0000000..972d895
--- /dev/null
+++ b/frontend/vue3.0概要.md
@@ -0,0 +1,1075 @@
+Vue 3.0 引入了很多新的 API 和功能,同时也保留了 Vue 2.x 的很多特性。以下是一个关于 Vue 3.0 常用功能的编程标准指南纲要:
+1. **项目和组件结构**
+ - 项目目录和文件命名
+ - 单文件组件的结构:template, script, style
+
+2. **组件数据**
+ - 定义和使用 props
+ - 定义和使用组件内部数据:`ref` 和 `reactive`
+ - 使用 `computed` 属性
+ - 使用 `watch` 和 `watchEffect` 监听数据变化
+
+3. **模板语法**
+ - 插值:文本,HTML
+ - 指令:v-model, v-if/v-else-if/v-else, v-show, v-for, v-bind, v-on
+ - 过滤器和全局混入(虽然 Vue 3.0 推荐尽量避免使用,但在一些场景仍有用)
+
+4. **组件通信**
+ - 使用 props 和自定义事件实现父子组件通信
+ - 使用 `provide`/`inject` 实现祖先和后代组件通信
+ - 使用 event bus 进行任意组件间的通信(Vue 3.0 不再内置,但可以自行实现)
+ - 使用 Vue 3.0 的新功能 `teleport` 进行组件内容的传输
+
+5. **Composition API**
+ - 使用 `setup` 函数
+ - 使用 `ref`, `reactive`, `computed`, `watch`, `watchEffect`
+ - 创建和使用 composable 函数
+
+6. **路由和状态管理**
+ - 使用 Vue Router:定义和使用路由,导航守卫,路由元信息
+ - 使用 Vuex:状态定义,Getter,Mutation,Action,模块化状态
+
+7. **与外部交互**
+ - 使用 `axios` 或者 `fetch` 进行 HTTP 请求
+ - 使用 Vue 3.0 的新功能 `Suspense` 进行异步依赖处理
+
+8. **测试和部署**
+ - 单元测试:使用 Jest 编写和运行测试
+ - E2E 测试:使用 Cypress 编写和运行测试
+ - 部署:编译,打包,发布
+
+1. **项目和组件结构**
+ - 项目目录和文件命名
+ Vue 项目和组件的结构可以因项目需求和开发团队偏好而有所不同,但这里提供一种推荐的目录结构:
+
+ ```
+ /my-app
+ ├── /node_modules
+ ├── /public
+ │ ├── index.html
+ │ └── favicon.ico
+ ├── /src
+ │ ├── /assets // 静态资源如图片、样式等
+ │ ├── /components // Vue 组件
+ │ ├── /router // Vue Router 配置
+ │ ├── /store // Vuex 状态管理配置
+ │ ├── /views // 页面级 Vue 组件
+ │ ├── App.vue // 根组件
+ │ ├── main.ts // 应用入口文件
+ │ ├── shims-vue.d.ts
+ │ └── ...
+ ├── package.json
+ ├── babel.config.js
+ └── ...
+ ```
+
+ - 文件命名:对于组件文件,推荐使用 'PascalCase' 的方式命名。例如:`MyComponent.vue`。而对于其它的 .js 或 .ts 文件,推荐使用 'kebab-case' 的方式命名。例如:`my-script.ts`。
+- 单文件组件的结构:template, script, style
+ 对于单文件组件(`.vue` 文件),其内部结构通常包含三部分:``, `
+
+
+ ```
+
+2. **组件数据**
+
+ 在 Vue 3.0 中,组件数据可以通过两种方式进行管理:
+
+ 1. **Props**: Props 是父组件向子组件传递数据的一种方式。Props 可以是任何类型的数据,如字符串,数字,对象,数组,布尔值等。在子组件中,我们需要定义接受的 props。
+
+ 2. **组件内部数据**: 使用 `ref` 和 `reactive` 可以创建组件的响应式数据。`ref` 用于创建响应式的基本类型数据(如字符串、数字等),`reactive` 用于创建响应式的复杂类型数据(如对象和数组)。
+
+ 以下是 props 和响应式数据的用法示例:
+
+```vue
+
+
+
{{ title }}
+
{{ message }}
+
+
+
+
+
+```
+
+在这个示例中,`title` 是一个从父组件传递过来的 prop,`count` 和 `message` 是组件内部的响应式数据。我们在 `setup` 函数中定义了一个方法 `increment`,这个方法会使 `count` 的值增加。
+
+注意:在 Vue 3.0 中,使用 `ref` 创建的响应式数据在模板中访问时不需要 `.value`,但在 `setup` 函数或其他 JavaScript 代码中访问时需要 `.value`。例如,在上述例子中,我们在模板中使用 `{{ count }}`,但在 `increment` 函数中使用 `count.value++`。
+
+3. **模板语法**
+
+Vue.js 使用基于 HTML 的模板语法,允许你声明式地将 DOM 和 Vue 实例的数据绑定在一起。在 Vue 3.0 中,所有 Vue 2.x 的模板语法都得到了支持,包括插值、指令等。
+
+以下是一些常用的模板语法:
+
+- **插值**: 使用双大括号(`{{ }}`)进行文本插值。
+
+```vue
+
+ {{ message }}
+
+```
+
+- **指令**: Vue 指令是带有 `v-` 前缀的特殊属性。指令属性的值预期是单一 JavaScript 表达式。例如 `v-model`、`v-if`/`v-else-if`/`v-else`、`v-show`、`v-for`、`v-bind`、`v-on` 等。
+
+```vue
+
+
+ Hello Vue!
+
+
+ {{ item }}
+
+
+```
+
+- **过滤器**: Vue 2.x 支持过滤器,但在 Vue 3.0 中过滤器被移除了。如果你需要使用过滤器功能,你可以使用计算属性或者方法来替代。
+
+注意:在 Vue 3.0 中,你应该尽量使用 `setup` 函数和 Composition API 来组织你的代码,尽管 `data`、`methods`、`computed` 和 `watch` 等选项在 Vue 3.0 中仍然可用。
+
+- **V3.0中不再支持或者不推荐的方法一览**
+好的,这是一些在 Vue 3.0 中不再支持或不再建议使用的功能和相应的替代方法:
+
+| Vue 2.x | Vue 3.0 替代方法 |
+|----------------------------------|-----------------|
+| Filters | 使用计算属性或者方法 |
+| `Vue.set` 和 `Vue.delete` | 直接使用 `delete` 或 `=` 操作符来添加或删除响应式属性 |
+| `Vue.observable` | 使用 `reactive` 或 `ref` |
+| `Vue.prototype` 自定义属性或方法 | 使用 provide/inject 机制来共享全局数据或方法 |
+| 异步组件的 `component` 工厂函数 | 使用 `defineAsyncComponent` |
+| Inline-template attribute | 使用 JSX 或者 Vue 单文件组件(SFC) |
+| `$on`, `$off` 和 `$once` 方法 | 使用新的事件处理方法,或者使用第三方库 |
+| Functional components | 使用普通的组件或者带有 `setup` 函数的组件 |
+
+需要注意的是,Vue 3.0 为我们提供了一种新的组件编写格式——Composition API,它提供了更好的 TypeScript 类型推断支持,并允许我们在大型组件中更好地组织我们的代码。虽然 Vue 2.x 的 Options API 在 Vue 3.0 中仍然可用,但建议新的项目尽可能地使用 Composition API。
+
+- 以下是 Vue 2.0 和 Vue 3.0 在不同功能和写法上的对比:
+
+1. **声明响应式数据**
+
+- Vue 2.0
+
+```vue
+
+```
+
+- Vue 3.0
+
+```vue
+
+```
+
+2. **计算属性**
+
+- Vue 2.0
+
+```vue
+
+```
+
+- Vue 3.0
+
+```vue
+
+```
+
+3. **侦听属性**
+
+- Vue 2.0
+
+```vue
+
+```
+
+- Vue 3.0
+
+```vue
+
+```
+
+4. **生命周期钩子**
+
+- Vue 2.0
+
+```vue
+
+```
+
+- Vue 3.0
+
+```vue
+
+```
+
+以上例子说明了 Vue 3.0 中 Composition API 的基本使用方法。你会注意到,Vue 3.0 提供的新的 API 允许我们在 `setup` 方法中更自由、更直观地组织代码,更容易进行类型推断,从而提高代码的可读性和可维护性。
+**4. 组件和指令**
+
+1. **组件定义**
+
+- Vue 3.0 中的组件定义方式如下:
+
+```vue
+
+
+ {{ message }}
+
+
+
+
+```
+
+2. **使用组件**
+
+在 Vue 3.0 中,组件的使用方式和 Vue 2.x 基本相同。可以在父组件中引入子组件,并通过标签形式进行使用。
+
+- Vue 3.0 中的使用方式如下:
+
+```vue
+
+
+
+
+
+```
+
+3. **指令**
+
+Vue 3.0 中的指令和 Vue 2.x 在使用方式上也是相似的,包括内置指令如 `v-model`, `v-if`, `v-for`, `v-on`, `v-bind` 等,以及自定义指令。
+
+以下是 Vue 3.0 中自定义指令的一个例子:
+
+```vue
+
+ Focus me!
+
+
+
+```
+
+在上述例子中,我们创建了一个自定义指令 `v-focus`,当元素被插入到 DOM 中时,这个指令会使元素自动获取焦点。
+
+**使用 props 和自定义事件实现父子组件通信**
+
+在 Vue.js 中,props 和自定义事件是实现父子组件通信的主要方式。父组件通过 props 向子组件传递数据,子组件通过发射 (emit) 自定义事件向父组件传递数据或者通知父组件某个事件已经发生。
+
+- 以下是一个使用 props 和自定义事件实现父子组件通信的例子:
+
+1. **父组件 (ParentComponent.vue)**
+
+```vue
+
+
+
+
+
+```
+
+在上述父组件中,我们使用了 `:propData="parentData"` 来向子组件传递 prop,以及使用了 `@childEvent="handleChildEvent"` 来监听子组件发射的 `childEvent` 事件。
+
+2. **子组件 (ChildComponent.vue)**
+
+```vue
+
+
+
+
+
+```
+
+在上述子组件中,我们定义了一个 prop `propData` 来接收父组件传递的数据,以及一个方法 `emitEvent` 来发射 `childEvent` 事件。
+
+注意,在 TypeScript 中,我们需要使用 `PropType` 来显式地指定 prop 的类型。
+
+**使用 `provide`/`inject` 实现祖先和后代组件通信**
+
+在 Vue.js 中,`provide` 和 `inject` 是实现祖先和后代组件之间通信的一种方式,主要用于避免 prop drilling(也就是多层级的组件传递 prop)。祖先组件使用 `provide` 选项来提供某些数据,后代组件使用 `inject` 选项来注入这些数据。
+
+以下是一个使用 `provide` 和 `inject` 实现祖先和后代组件通信的例子:
+
+1. **祖先组件 (AncestorComponent.vue)**
+
+```vue
+
+
+
+
+
+```
+
+在上述祖先组件中,我们使用了 `provide` 函数来提供一个名为 `ancestorData` 的数据。
+
+2. **后代组件 (DescendantComponent.vue)**
+
+```vue
+
+ {{ injectedData }}
+
+
+
+```
+
+在上述后代组件中,我们使用了 `inject` 函数来注入名为 `ancestorData` 的数据。请注意,在 TypeScript 中,我们需要使用类型断言 `[>` 来指定注入数据的类型。
+
+这种方式特别适用于一些跨级别的状态共享,例如主题颜色、语言偏好等全局性的配置。
+
+**使用 event bus 进行任意组件间的通信(Vue 3.0 不再内置,但可以自行实现)**
+
+Vue 3.0 不再内置 event bus,但你可以使用一个简单的 EventEmitter 实现自己的 event bus。在这种情况下,任何组件都可以通过 event bus 发送和接收事件,实现跨组件通信。
+
+以下是一个使用 event bus 进行任意组件间通信的例子:
+
+首先,我们需要创建一个 Event Bus:
+
+```ts
+// EventBus.ts
+import { EventEmitter } from 'events'
+
+export const EventBus = new EventEmitter()
+```
+
+然后,组件可以通过 Event Bus 发送和接收事件:
+
+1. **发送事件的组件 (EmitterComponent.vue)**
+
+```vue
+
+
+
+
+
+```
+
+在上述组件中,我们定义了一个方法 `emitEvent`,用于在 `customEvent` 事件上发送数据。
+
+2. **接收事件的组件 (ReceiverComponent.vue)**
+
+```vue
+
+ ]{{ receivedData }}
+
+
+
+```
+
+在上述组件中,我们使用了 `EventBus.on` 来监听 `customEvent` 事件,并在事件处理器 `handleCustomEvent` 中更新 `receivedData`。同时,我们也使用了 `EventBus.off` 来在组件卸载前移除事件监听器,以避免内存泄漏。
+
+请注意,使用 event bus 进行跨组件通信应该谨慎使用,因为它使得数据流难以追踪,增加了代码的复杂性。在大型项目中,你可能会更倾向于使用专门的状态管理库,如 Vuex。
+
+**使用 Vue 3.0 的新功能 `teleport` 进行组件内容的传输**
+
+在 Vue 3.0 中,新增了 `teleport` 功能,也被称为 "传送门"。`teleport` 能将子组件渲染到 DOM 中的任意位置,而不仅仅是局限于父组件的范围内。它特别适用于需要“破坏性”的 UI 特性,例如全屏覆盖的模态框、通知、对话框等。
+
+以下是一个使用 `teleport` 进行组件内容的传输的例子:
+
+1. 在 HTML 文件中,添加一个目标元素:
+
+```html
+
+ ...
+
+
+```
+
+2. 创建一个使用 `teleport` 的组件 (ModalComponent.vue):
+
+```vue
+
+
+
+
This is a modal
+
+
+
+
+
+
+
+
+
+```
+
+在上述组件中,我们定义了一个名为 `modal-root` 的目标元素,这就是我们要将模态框渲染的地方。注意,`teleport` 的 `to` 属性用于指定目标元素。
+
+然后,在其他任何需要使用这个模态框的组件中,只需如下使用:
+
+```vue
+
+
+ This is some content inside the modal
+
+
+
+
+```
+
+在使用 `teleport` 的过程中,父组件和被 teleport 的子组件之间的通信仍然保持原样。也就是说,你可以像平常一样使用 props、事件、插槽等。
+
+**5. Vue 3.0 中的 Composition API**
+
+Vue 3.0 引入了一种新的组件编写方式,名为 Composition API。它是一个基于函数的 API,让你能更灵活地组织和重用逻辑代码。对比于 Vue 2 中的 Options API,Composition API 更容易处理复杂的组件和逻辑,使代码组织更加清晰。
+
+以下是一个基本的 Composition API 组件示例:
+
+```vue
+
+
+
+
+
+```
+
+在上述示例中,我们在 `setup` 函数中定义了 `count` 数据和 `increment` 方法。请注意,`ref` 是一个函数,用于创建响应式的数据。在模板中,我们可以像平常一样使用 `count` 和 `increment`。
+
+Composition API 还提供了一系列其它的函数,如 `reactive`、`computed`、`watch`、`onMounted`、`onUnmounted` 等,可以帮助我们更好地编写组件逻辑。
+
+值得注意的是,使用 Composition API 不意味着必须放弃 Options API。实际上,两者可以在同一个组件中并用。你可以根据项目的具体需求和团队的编程习惯,选择最适合你的 API 风格。
+
+- **以下是 Vue 3.0 中的 Composition API 函数的基本说明,以及与 Options API 的对比**
+
+| Composition API | 说明 | 对应的 Options API |
+| --------------- | ---- | ------------------ |
+| `setup` | `setup` 是一个新引入的组件选项,用于使用 Composition API。它是组件内部使用 Composition API 的入口。| 无 |
+| `ref` | `ref` 函数用于创建一个响应式的数据。它接收一个参数,返回一个响应式的 Ref 对象。| `data` |
+| `reactive` | `reactive` 函数用于创建一个响应式的对象。它接收一个普通对象,返回一个响应式的对象。| `data` |
+| `computed` | `computed` 函数用于创建一个计算属性。它接收一个 getter 函数或者一个具有 getter 和 setter 的对象,返回一个响应式的 Ref 对象。| `computed` |
+| `watch` | `watch` 函数用于响应式地跟踪和触发副作用。它接收一个响应式的源和一个执行副作用的回调函数。| `watch` |
+| `watchEffect` | `watchEffect` 函数用于立即执行传入的一个函数,并响应式地追踪其依赖,并在其依赖变更时重新运行该函数。 | 无 |
+| `onMounted` | `onMounted` 函数在组件被挂载时调用。它接收一个在组件挂载后执行的回调函数。 | `mounted` |
+| `onUnmounted` | `onUnmounted` 函数在组件被卸载时调用。它接收一个在组件卸载后执行的回调函数。 | `beforeDestroy`/`unmounted` |
+| `onUpdated` | `onUpdated` 在组件更新后调用。它接收一个在组件更新后执行的回调函数。| `updated` |
+| `provide` | `provide` 函数用于在组件上定义一个可以被后代组件注入的值。它接收一个提供的键和值。 | 有,与 `provide/inject` 相似但是属性而不是函数 |
+| `inject` | `inject` 函数用于在组件中注入一个由祖先组件提供的值。它接收一个注入的键。 | 有,但与 `provide/inject` 相似但是属性而不是函数 |
+
+值得注意的是,虽然一些 Composition API 函数与 Options API 的某些选项有相似之处,但它们的工作方式和使用方式可能有所不同。在实际使用中,你需要根据具体的使用场景和需求选择合适的 API。
+
+- ** 使用 `ref`, `reactive`, `computed`, `watch`, `watchEffect`**
+
+这些函数是 Vue 3.0 Composition API 的一部分,使得我们可以更加灵活和高效地编写组件逻辑。
+
+以下是这些函数的使用示例:
+
+```vue
+
+
+
{{ count }}
+
{{ double }}
+
+
+
+
+
+
+```
+
+在上述示例中,我们使用 `ref` 和 `reactive` 创建了响应式数据,使用 `computed` 创建了计算属性,使用 `watch` 和 `watchEffect` 监听了数据的变化。并且在数据变化时更新了相关数据,并打印了日志信息。
+
+- ** 创建和使用 composable 函数**
+
+在 Vue 3.0 的 Composition API 中,我们可以将复用的逻辑提取出来,创建一个 composable 函数。composable 函数就是一个普通的 JavaScript 函数,这个函数内部使用了 Composition API 的功能,并返回一些响应式数据或函数。
+
+以下是一个创建和使用 composable 函数的示例:
+
+首先,我们创建一个名为 `useCounter` 的 composable 函数,这个函数提供了计数器的功能:
+
+```javascript
+import { ref } from 'vue'
+
+export function useCounter() {
+ const count = ref(0)
+
+ const increment = () => {
+ count.value++
+ }
+
+ const decrement = () => {
+ count.value--
+ }
+
+ return {
+ count,
+ increment,
+ decrement
+ }
+}
+```
+
+然后,在组件中使用 `useCounter` 函数:
+
+```vue
+
+
+
{{ count }}
+
+
+
+
+
+
+```
+
+在上述示例中,我们首先创建了一个 `useCounter` composable 函数,这个函数提供了计数器的功能。然后,在组件中使用了 `useCounter` 函数,从而复用了计数器的功能。通过这种方式,我们可以将复杂的逻辑提取出来,创建 composable 函数,然后在多个组件中复用这些函数。
+
+7. **与外部交互**
+
+与外部系统(如服务器端 API、本地存储或其他 JavaScript 库)交互是常见的需求。下面介绍一些 Vue 3 和 TypeScript 中的常用方法。
+
+**使用 Axios 进行 HTTP 请求**
+在处理与外部交互时,我们通常会遇到异步操作。以下是使用 Vue 3 和 TypeScript 进行异步处理的例子。
+
+**使用 Axios 进行 HTTP 请求**
+
+首先,我们可以使用 `async/await` 语法改写 Axios 的 HTTP 请求:
+
+```typescript
+import axios from 'axios'
+import { ref, onMounted } from 'vue'
+
+export default {
+ setup() {
+ const data = ref(null)
+
+ onMounted(async () => {
+ const response = await axios.get('https://api.example.com/data')
+ data.value = response.data
+ })
+
+ return {
+ data
+ }
+ }
+}
+```
+
+在这个例子中,我们使用 `async/await` 语法来处理异步的 HTTP 请求。注意,因为 `await` 只能在 `async` 函数中使用,所以我们需要在 `onMounted` 钩子中使用 `async`。
+
+**使用 LocalStorage 进行本地存储**
+
+虽然 LocalStorage 的操作是同步的,但如果你需要模拟异步操作,可以使用 Promise:
+
+```typescript
+import { ref, onMounted } from 'vue'
+
+export default {
+ setup() {
+ const count = ref(0)
+
+ onMounted(async () => {
+ const savedCount = await new Promise(resolve => {
+ setTimeout(() => {
+ resolve(localStorage.getItem('count'))
+ }, 1000)
+ })
+
+ count.value = savedCount || 0
+ })
+
+ return {
+ count
+ }
+ }
+}
+```
+
+在这个例子中,我们使用 `setTimeout` 模拟异步操作,并使用 `Promise` 来处理这个异步操作。在异步操作完成后,我们更新 `count` 的值。
+
+**使用 LocalStorage 进行本地存储**
+
+在浏览器中,我们可以使用 LocalStorage 对象进行本地存储。以下是一个简单的例子:
+
+```javascript
+import { ref, watch } from 'vue'
+
+export default {
+ setup() {
+ const count = ref(localStorage.getItem('count') || 0)
+
+ watch(count, newValue => {
+ localStorage.setItem('count', newValue)
+ })
+
+ return {
+ count
+ }
+ }
+}
+```
+
+在这个例子中,我们首先从 LocalStorage 中获取 `count` 的值。然后,我们使用 `watch()` 函数监听 `count` 的变化,并在 `count` 变化时更新 LocalStorage 中的值。
+
+**使用 Vue 3 提供的生命周期钩子**
+
+Vue 3 提供了一些生命周期钩子,如 `onMounted()`、`onUpdated()` 和 `onUnmounted()`,可以在组件的生命周期的不同阶段进行特定的操作。以下是一个简单的例子:
+
+```javascript
+import { onMounted, ref } from 'vue'
+
+export default {
+ setup() {
+ const data = ref(null)
+
+ onMounted(() => {
+ data.value = 'Hello, Vue 3'
+ })
+
+ return {
+ data
+ }
+ }
+}
+```
+
+在这个例子中,我们在组件挂载后更新 `data` 的值。
+
+**7. 使用 Vue 3.0 的新功能 `Suspense` 进行异步依赖处理**
+
+Vue 3.0 引入了一个新的内置组件 `Suspense`,它可以帮助我们处理组件中的异步依赖。
+
+当一个组件的 `setup` 函数返回一个 Promise 时(这通常意味着该组件有异步操作),我们可以用 `Suspense` 组件包裹这个组件。`Suspense` 组件有两个插槽:`default` 插槽和 `fallback` 插槽。当异步组件处于等待状态时,`fallback` 插槽的内容会被渲染;当异步组件的 Promise 解析完成时,`default` 插槽的内容会被渲染。
+
+下面是一个使用 `Suspense` 处理异步组件的例子:
+
+```html
+
+
+
+
+
+
+ Loading...
+
+
+
+
+
+```
+
+在这个例子中,我们创建了一个异步组件 `AsyncComponent`,它的 `setup` 函数返回一个 Promise。我们使用 `Suspense` 组件包裹 `AsyncComponent`,并提供了 `fallback` 插槽,当 `AsyncComponent` 的数据正在加载时,`fallback` 插槽的内容会被渲染。