diff --git "a/\347\216\213\345\256\235sen/20240509_\350\267\257\347\224\261.md" "b/\347\216\213\345\256\235sen/20240509_\350\267\257\347\224\261.md" new file mode 100644 index 0000000000000000000000000000000000000000..92bb5ad3a867b763b38168bfd528b1f09c4f7776 --- /dev/null +++ "b/\347\216\213\345\256\235sen/20240509_\350\267\257\347\224\261.md" @@ -0,0 +1,47 @@ +## Vue 3 路由 + +### 1. 基本概念 + +- Vue 3 中的路由管理依赖于 Vue Router,用于实现单页面应用(SPA)中的页面导航和管理。 +- 路由允许根据 URL 的变化加载不同的组件,实现页面间的无刷新切换。 + +### 2. 安装 Vue Router + +- 使用 Vue CLI 创建的项目已经集成了 Vue Router,无需额外安装。 +- 如果是手动配置项目,则需要通过 npm 或 yarn 安装 Vue Router: + +``` +bashCopy Codenpm install vue-router@next +``` + +### 3. 创建路由实例 + +- 使用 `createRouter` 函数创建路由实例,并配置路由信息和路由模式: + +``` +javascriptCopy Code解释import { createRouter, createWebHistory } from 'vue-router'; +import Home from '@/views/Home.vue'; + +const routes = [ + { + path: '/', + name: 'Home', + component: Home + }, + // 其他路由配置 +]; + +const router = createRouter({ + history: createWebHistory(), + routes +}); + +export default router; +``` + +### 4. 配置路由 + +- 路由配置对象中包含 `path`、`name`、`component` 等属性。 +- `path`:URL 中的路径。 +- `name`:路由名称,用于编程式导航。 +- `component`:对应的 Vue 组件。 \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/20240510-\345\212\250\346\200\201\350\267\257\347\224\261\345\214\271\351\205\215.md" "b/\347\216\213\345\256\235sen/20240510-\345\212\250\346\200\201\350\267\257\347\224\261\345\214\271\351\205\215.md" new file mode 100644 index 0000000000000000000000000000000000000000..e1295e930254a240e70540050b3307720ea7092f --- /dev/null +++ "b/\347\216\213\345\256\235sen/20240510-\345\212\250\346\200\201\350\267\257\347\224\261\345\214\271\351\205\215.md" @@ -0,0 +1,89 @@ +### 动态路由匹配 + +我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果: +``` +const User = { + template: '
User
' +} + +const router = new VueRouter({ + routes: [ + // 动态路径参数 以冒号开头 + { path: '/user/:id', component: User } + ] +}) +``` +现在呢,像 /user/foo 和 /user/bar 都将映射到相同的路由。 + +一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。于是,我们可以更新 User 的模板,输出当前用户的 ID: +``` +const User = { + template: '
User {{ $route.params.id }}
' +} +``` +你可以看看这个在线例子 (opens new window)。 + +你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如: +``` +模式 匹配路径 $route.params +/user/:username /user/evan { username: 'evan' } +/user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: '123' } +``` +除了 $route.params 外,$route 对象还提供了其它有用的信息,例如,$route.query (如果 URL 中有查询参数)、$route.hash 等等。你可以查看 API 文档 的详细说明。 + +### 响应路由参数的变化 + +提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。 + +复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象: +``` +const User = { + template: '...', + watch: { + $route(to, from) { + // 对路由变化作出响应... + } + } +} +``` +或者使用 2.2 中引入的 beforeRouteUpdate 导航守卫: +``` +const User = { + template: '...', + beforeRouteUpdate(to, from, next) { + // react to route changes... + // don't forget to call next() + } +} +``` +### 捕获所有路由或 404 Not found 路由 + +常规参数只会匹配被 / 分隔的 URL 片段中的字符。如果想匹配任意路径,我们可以使用通配符 (*): +``` +{ + // 会匹配所有路径 + path: '*' +} +{ + // 会匹配以 `/user-` 开头的任意路径 + path: '/user-*' +} +``` +当使用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后。路由 { path: '*' } 通常用于客户端 404 错误。如果你使用了History 模式,请确保正确配置你的服务器。 + +当使用一个通配符时,$route.params 内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分: +``` +// 给出一个路由 { path: '/user-*' } +this.$router.push('/user-admin') +this.$route.params.pathMatch // 'admin' +// 给出一个路由 { path: '*' } +this.$router.push('/non-existing') +this.$route.params.pathMatch // '/non-existing' +``` +### 高级匹配模式 + +vue-router 使用 path-to-regexp (opens new window)作为路径匹配引擎,所以支持很多高级的匹配模式,例如:可选的动态路径参数、匹配零个或多个、一个或多个,甚至是自定义正则匹配。查看它的文档 (opens new window)学习高阶的路径匹配,还有这个例子 (opens new window)展示 vue-router 怎么使用这类匹配。 + +### 匹配优先级 + +有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:路由定义得越早,优先级就越高。 \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/20240511-\347\274\226\347\250\213\345\274\217\345\257\274\350\210\252.md" "b/\347\216\213\345\256\235sen/20240511-\347\274\226\347\250\213\345\274\217\345\257\274\350\210\252.md" new file mode 100644 index 0000000000000000000000000000000000000000..cc169e9737c5c822b283123326fa312950961f4b --- /dev/null +++ "b/\347\216\213\345\256\235sen/20240511-\347\274\226\347\250\213\345\274\217\345\257\274\350\210\252.md" @@ -0,0 +1,175 @@ +### 1.编程式导航 + +在之前的代码中曾使用过this.$route.params获取路由的参数,this.$route为当前的路由对象,在实现路由切换时,如果使用编程式导航,需要使用this.$router.push方法,this.$router获取的是设置在根实例中的一个Vue Router的实例,push方法是由实例对象提供的 + +router.push方法的第一个参数可以是一个字符串路径,也可以是描述地址的对象,在这个对象中可以设置传递到下一个路由的参数,onComplete和onAbort作为第二个和第三个参数分别接收一个回调函数,它们分别表示当导航成功时触发和导航失败时触发(导航到相同的路由或在当前导航完成之前就导航到另一个不同的路由),不过这两个参数不是必须要传入的 + +在main.js中写: + +``` +import { createApp } from 'vue'; +import './style.css'; +import App from './App.vue'; +import { createRouter, createWebHashHistory } from 'vue-router'; +import PlanA from './components/planA.vue'; +import PlanB from './components/planB.vue'; +let router=createRouter +({ + history:createWebHashHistory(), + routes: + [ + { + path:'/PlanA', + component:PlanA + }, + { + path:'/PlanB', + component:PlanB + } + ] +}) +let app=createApp(App); +app.use(router); +app.mount('#app'); +``` + +在App.vue中写: + +``` + + + +``` + +关于命名的路由的写法: + +在main.js中写: + +``` +import { createApp } from 'vue'; +import './style.css'; +import App from './App.vue'; +import { createRouter, createWebHashHistory } from 'vue-router'; +import PlanA from './components/planA.vue'; +import PlanB from './components/planB.vue'; +let router=createRouter +({ + history:createWebHashHistory(), + routes: + [ + { + path:'/PlanA/:username?', + name:'PlanA', + component:PlanA + }, + { + path:'/PlanB/:username?', + name:'PlanB', + component:PlanB + }, + { + path:'/', + component:PlanA + }, + ] +}) +let app=createApp(App); +app.use(router); +app.mount('#app'); +``` + +在App.vue中写: + +``` + + + +``` + +### 2.路由元数据 + +在设置路由信息时,每个路由都有一个元数据字段,可以在这里设置一些自定义信息,供页面组件、导航守卫和路由钩子函数使用 + +在main.js中写: + +``` +import { createApp } from 'vue'; +import './style.css'; +import App from './App.vue'; +import { createRouter, createWebHashHistory } from 'vue-router'; +import PlanA from './components/planA.vue'; +let router=createRouter +({ + history:createWebHashHistory(), + routes: + [ + { + path:'/', + component:PlanA, + meta: + { + title:'首页PlanA~' + } + }, + ] +}) +let app=createApp(App); +app.use(router); +app.mount('#app'); +``` + +在App.vue中写: + +``` + + + +``` \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/20240513-Pinia.md" "b/\347\216\213\345\256\235sen/20240513-Pinia.md" new file mode 100644 index 0000000000000000000000000000000000000000..0b53573080215a49f9893d42f76f474d70bb7892 --- /dev/null +++ "b/\347\216\213\345\256\235sen/20240513-Pinia.md" @@ -0,0 +1,96 @@ +``` +安装:pinia: yarn add pinia +``` + +#### 简介 + +``` +通过 Mastering Pinia 的免费视频掌握更多内容 +Pinia 起始于 2019 年 11 月左右的一次实验,其目的是设计一个拥有组合式 API 的 Vue 状态管理库。从那时起,我们就倾向于同时支持 Vue 2 和 Vue 3,并且不强制要求开发者使用组合式 API,我们的初心至今没有改变。除了安装和 SSR 两章之外,其余章节中提到的 API 均支持 Vue 2 和 Vue 3。虽然本文档主要是面向 Vue 3 的用户,但在必要时会标注出 Vue 2 的内容,因此 Vue 2 和 Vue 3 的用户都可以阅读本文档。 +``` + +#### 基础示例 +``` +下面就是 pinia API 的基本用法 (为继续阅读本简介请确保你已阅读过了开始章节)。你可以先创建一个 Store: + +js +// stores/counter.js +import { defineStore } from 'pinia' + +export const useCounterStore = defineStore('counter', { + state: () => { + return { count: 0 } + }, + // 也可以这样定义 + // state: () => ({ count: 0 }) + actions: { + increment() { + this.count++ + }, + }, +}) + +然后你就可以在一个组件中使用该 store 了: + +vue + + +``` + +#### 更真实的示例 +这是一个更完整的 Pinia API 示例,在 JavaScript 中也使用了类型提示。对于某些开发者来说,可能足以在不进一步阅读的情况下直接开始阅读本节内容,但我们仍然建议你先继续阅读文档的其余部分,甚至跳过此示例,在阅读完所有核心概念之后再回来。 + +``` +js +import { defineStore } from 'pinia' + +export const useTodos = defineStore('todos', { + state: () => ({ + /** @type {{ text: string, id: number, isFinished: boolean }[]} */ + todos: [], + /** @type {'all' | 'finished' | 'unfinished'} */ + filter: 'all', + // 类型将自动推断为 number + nextId: 0, + }), + getters: { + finishedTodos(state) { + // 自动补全! ✨ + return state.todos.filter((todo) => todo.isFinished) + }, + unfinishedTodos(state) { + return state.todos.filter((todo) => !todo.isFinished) + }, + /** + * @returns {{ text: string, id: number, isFinished: boolean }[]} + */ + filteredTodos(state) { + if (this.filter === 'finished') { + // 调用其他带有自动补全的 getters ✨ + return this.finishedTodos + } else if (this.filter === 'unfinished') { + return this.unfinishedTodos + } + return this.todos + }, + }, + actions: { + // 接受任何数量的参数,返回一个 Promise 或不返回 + addTodo(text) { + // 你可以直接变更该状态 + this.todos.push({ text, id: this.nextId++, isFinished: false }) + }, + }, +}) +``` \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/20240514-20.API\345\222\214REST.md" "b/\347\216\213\345\256\235sen/20240514-20.API\345\222\214REST.md" new file mode 100644 index 0000000000000000000000000000000000000000..fff961c3560f7a8ec7b1c62f5b1a3ebc9c99448f --- /dev/null +++ "b/\347\216\213\345\256\235sen/20240514-20.API\345\222\214REST.md" @@ -0,0 +1,30 @@ +## API和REST + +### API + +Application Programming Interface(应用程序接口)是它的全称。简单的理解就是,API是一个接口 + +### REST + +HTTP总共包含八种方法: + +``` +GET +POST +PUT +DELETE +OPTIONS +HEAD +TRACE +CONNECT +``` + +● 2xx = Success(成功) + +● 3xx = Redirect(重定向) + +● 4xx = User error(客户端错误) + +● 5xx = Server error(服务器端错误) + +我们常见的是200(请求成功)、404(未找到)、401(未授权)、500(服务器错误)... \ No newline at end of file diff --git "a/\347\216\213\345\256\235sen/20240516-\350\267\257\347\224\261\345\272\224\347\224\250.md" "b/\347\216\213\345\256\235sen/20240516-\350\267\257\347\224\261\345\272\224\347\224\250.md" new file mode 100644 index 0000000000000000000000000000000000000000..6189ab644105f579262a317de033628dc800624d --- /dev/null +++ "b/\347\216\213\345\256\235sen/20240516-\350\267\257\347\224\261\345\272\224\347\224\250.md" @@ -0,0 +1,28 @@ +### 通过路由方式实现增删改查 +#### 思路: +1. 配置路由: +~~~js +// src/router/router.js + import { createRouter, createWebHistory } from 'vue-router'; + import Home from './components/Home.vue'; + import ManageItem from './components/Edit.vue'; + const router = createRouter({ + history: createWebHistory(), + routes:[ + {path:'/home',component:Home}, + { path: '/edit/:id?', + name: 'Edit', + component: Edit, + }, + {path:'/',component:App}, + // 这里也可以加上redirect:'/home' 表示一打开就跳转到列表页,但是不推荐 + ] + } ); + export default router; +~~~ +2. 配置入口文件: +~~~js + import router from '.Router/router'; + const app = createApp(App); + app.use(router); +~~~ \ No newline at end of file