From 30ffa46c6538f3acf054c607a85de151aad2eba8 Mon Sep 17 00:00:00 2001 From: suim Date: Sun, 10 May 2026 07:36:43 -0800 Subject: [PATCH 1/2] Update --- ...4\344\270\232+\347\254\224\350\256\260.md" | 283 ++++++++++++++++++ ...4\344\270\232+\347\254\224\350\256\260.md" | 114 +++++++ ...4\344\270\232+\347\254\224\350\256\260.md" | 32 ++ 3 files changed, 429 insertions(+) create mode 100644 "\345\274\240\345\256\207\350\210\252/20260506-\344\275\234\344\270\232+\347\254\224\350\256\260.md" create mode 100644 "\345\274\240\345\256\207\350\210\252/20260507-\344\275\234\344\270\232+\347\254\224\350\256\260.md" create mode 100644 "\345\274\240\345\256\207\350\210\252/20260508-\344\275\234\344\270\232+\347\254\224\350\256\260.md" diff --git "a/\345\274\240\345\256\207\350\210\252/20260506-\344\275\234\344\270\232+\347\254\224\350\256\260.md" "b/\345\274\240\345\256\207\350\210\252/20260506-\344\275\234\344\270\232+\347\254\224\350\256\260.md" new file mode 100644 index 0000000..b81211e --- /dev/null +++ "b/\345\274\240\345\256\207\350\210\252/20260506-\344\275\234\344\270\232+\347\254\224\350\256\260.md" @@ -0,0 +1,283 @@ +## 练习 + +```vue + + + + + +``` diff --git "a/\345\274\240\345\256\207\350\210\252/20260507-\344\275\234\344\270\232+\347\254\224\350\256\260.md" "b/\345\274\240\345\256\207\350\210\252/20260507-\344\275\234\344\270\232+\347\254\224\350\256\260.md" new file mode 100644 index 0000000..6d957e8 --- /dev/null +++ "b/\345\274\240\345\256\207\350\210\252/20260507-\344\275\234\344\270\232+\347\254\224\350\256\260.md" @@ -0,0 +1,114 @@ +## 组件的创建与调用 +### 全局注册 +```vue +app.component('注册的组件名',定义的组件名) +``` + +### 局部注册 +```vue +const 组件X = {...} +const 组件Y = { + component: { + 注册的组件名 : 组件X + } +} +``` + +### 组件调用 +```vue + +``` + +## 组件之间的数据传递 +### 父组件向子组件传递数据 +在子组件中声明数据 +```vue +props:['属性1','属性2',...] +props:{ + 属性1:数据类型, + 属性2:数据类型, + ... +} +``` + +在使用setup语法糖的单文件组件中声明数据 +```vue +const props = defineProps(['属性1','属性2',...]) +const props = defineProps({ + 属性1:数据类型, + 属性2:数据类型 +}) +``` + +校验传递数据 +```vue +props:{ + 属性名:Number, + 属性名:[String,String] + 属性名:{type:Number,required:true} + 属性名:{type:Number,default:200} + 属性名:{ + type:Object + default(){ + return {info:'内容'} + } + } +} +``` + +使用接收的数据 +```vue +

{{message}}

+props: ['message'] +``` + + +### 在父组件中传递数据 +传递字符串的静态数据 +```vue +<子组件标签名 属性1="数值1" 属性2="数值2" ...> +``` + + +### 子组件向父组件传递数据 +子组件声明自定义事件 +```vue +emits:['自定义事件1','自定义事件2',...] + + +使用setup语法糖 +const emit = defineEmits(['自定义事件1','自定义事件2',...] +) +``` + +### 子组件触发自定义事件 +```vue +<标签名 @click="$emit('自定义事件',数据)" + + +setup(props,ctx){ + ctx.emit('自定义事件名',数据) +} + +emit('自定义事件名',数据) +``` + + +### 多层组件之间的传递 +祖先组件提供数据 +```vue +Vue.provide('注入名称',注入数据) + + +//setup语法糖 + +provide('注入名称',注入数据) + +``` + + +### 后代组件接收数据 +``` +const 变量名 = Vue.inject('注入名称',默认值,布尔值) + +``` diff --git "a/\345\274\240\345\256\207\350\210\252/20260508-\344\275\234\344\270\232+\347\254\224\350\256\260.md" "b/\345\274\240\345\256\207\350\210\252/20260508-\344\275\234\344\270\232+\347\254\224\350\256\260.md" new file mode 100644 index 0000000..626e379 --- /dev/null +++ "b/\345\274\240\345\256\207\350\210\252/20260508-\344\275\234\344\270\232+\347\254\224\350\256\260.md" @@ -0,0 +1,32 @@ +## Slot插槽 +### 在子组件中定义默认插槽 +```vue + +``` + +### 具名插槽 +子组件中定义具名插槽 +```vue + + +``` + +### 作用域插槽 +子组件中定义带数据的作用域插槽 +```vue + + + + + +``` + +### 在父组件中使用作用域插槽 +```vue +<子组件标签名 v-slot = "slotData"> +``` + +### 动态插槽名 +```vue +<子组件标签名 v-slot:[dynamicName] = "slotData"> +``` -- Gitee From 1dabb964ec83ddba167084c347ddaf13d76a40ae Mon Sep 17 00:00:00 2001 From: suim Date: Sun, 17 May 2026 03:04:55 -0800 Subject: [PATCH 2/2] Update --- ...4\344\270\232+\347\254\224\350\256\260.md" | 50 ++++ ...4\344\270\232+\347\254\224\350\256\260.md" | 166 +++++++++++++ ...4\344\270\232+\347\254\224\350\256\260.md" | 162 ++++++++++++ ...4\344\270\232+\347\254\224\350\256\260.md" | 232 ++++++++++++++++++ 4 files changed, 610 insertions(+) create mode 100644 "\345\274\240\345\256\207\350\210\252/20260511-\344\275\234\344\270\232+\347\254\224\350\256\260.md" create mode 100644 "\345\274\240\345\256\207\350\210\252/20260513-\344\275\234\344\270\232+\347\254\224\350\256\260.md" create mode 100644 "\345\274\240\345\256\207\350\210\252/20260514-\344\275\234\344\270\232+\347\254\224\350\256\260.md" create mode 100644 "\345\274\240\345\256\207\350\210\252/20260515-\344\275\234\344\270\232+\347\254\224\350\256\260.md" diff --git "a/\345\274\240\345\256\207\350\210\252/20260511-\344\275\234\344\270\232+\347\254\224\350\256\260.md" "b/\345\274\240\345\256\207\350\210\252/20260511-\344\275\234\344\270\232+\347\254\224\350\256\260.md" new file mode 100644 index 0000000..4037715 --- /dev/null +++ "b/\345\274\240\345\256\207\350\210\252/20260511-\344\275\234\344\270\232+\347\254\224\350\256\260.md" @@ -0,0 +1,50 @@ +## 动态组件 +### 定义动态组件 +基本用法 +```vue + +``` + +### KeepAlive —— 缓存组件状态 +基本用法 +```vue + +> + +``` +```vue + +``` + +标签默认缓存内部所有的组件,使用include,exclude和max属性控制缓存那些组件,不缓存那些组件和缓存组件的最大数量 + +### include属性和exclude +```vue +include属性的值为可缓存的组件的组件名 +exclude属性的值为不可缓存组件的组件名 + +// include属性 + +//缓存的组件 + +//exclude属性 + + +``` + diff --git "a/\345\274\240\345\256\207\350\210\252/20260513-\344\275\234\344\270\232+\347\254\224\350\256\260.md" "b/\345\274\240\345\256\207\350\210\252/20260513-\344\275\234\344\270\232+\347\254\224\350\256\260.md" new file mode 100644 index 0000000..1ac5b4b --- /dev/null +++ "b/\345\274\240\345\256\207\350\210\252/20260513-\344\275\234\344\270\232+\347\254\224\350\256\260.md" @@ -0,0 +1,166 @@ +## 单页面应用路由 +### vue Router 概述 +Vue Router 是 Vue.js 官方提供的路由管理器,用于实现单页面应用(SPA)的导航功能。它允许你在不刷新页面的情况下切换视图。 + +### Vue Router 安装 +``` +npm install vue-router@4.2.5 + +yarn add vue-router@4.2.5 +``` + +### 创建路由配置文件 +路由配置文件中定义 URL 路径与组件的映射关系: + +```js +// src/router/index.js +import { createRouter, createWebHistory } from 'vue-router' +import HomeView from '../views/首页视图.vue' +import ItemGridView from '../views/商品网格.vue' +import CheckoutView from '../views/结算页.vue' + +// 路由规则数组 +const routes = [ + { + path: '/', + name: 'Home', + component: HomeView + }, + { + path: '/items', + name: 'ItemGrid', + component: ItemGridView + }, + { + path: '/checkout', + name: 'Checkout', + component: CheckoutView + } +] + +// 创建路由实例,配置 history 模式 +const router = createRouter({ + history: createWebHistory(), + routes +}) + +export default router +``` + +### 在应用入口挂载路由 +```js +// src/main.js +import { createApp } from 'vue' +import App from './App.vue' +import router from './router/index.js' + +const app = createApp(App) +app.use(router) +app.mount('#app') +``` + +### 在根组件中放置路由出口 +路由出口指示当前路径对应的组件渲染位置: + +```vue + + +``` + +### RouterLink 和 RouterView 组件对比 + +| 组件 | 用途 | 相当于 HTML 标签 | +|------|------|------------------| +| RouterLink | 生成可点击的导航链接 | `` 但拦截默认跳转 | +| RouterView | 渲染当前路径对应的组件 | 内容占位符 | + +### 导航链接的激活状态 +`` 会自动给当前激活的链接添加特定类名: + +```css +/* 链接处于激活状态时的样式 */ +.router-link-active { + color: #42b883; + font-weight: bold; + text-decoration: underline; +} + +/* 链接处于精确激活状态时的样式 */ +.router-link-exact-active { + color: #35495e; + background-color: #f0f0f0; +} +``` + +### History 模式配置 +Vue Router 支持两种 history 模式: + +```js +// HTML5 History 模式(推荐) +const router = createRouter({ + history: createWebHistory(), + routes +}) + +// Hash 模式 +const router = createRouter({ + history: createWebHashHistory(), + routes +}) +``` + +### 路由元信息(meta) +可以为路由添加元信息用于权限控制: + +```js +const routes = [ + { + path: '/admin', + component: AdminPanel, + meta: { requiresAuth: true } + }, + { + path: '/profile', + component: UserProfile, + meta: { requiresAuth: false } + } +] +``` + +### 全局路由守卫 +```js +// 全局前置守卫 +router.beforeEach((to, from, next) => { + if (to.meta.requiresAuth) { + // 检查用户是否已登录 + if (isLoggedIn()) { + next() + } else { + next('/login') + } + } else { + next() + } +}) + +// 全局后置守卫 +router.afterEach((to, from) => { + document.title = to.meta.title || '默认标题' +}) +``` diff --git "a/\345\274\240\345\256\207\350\210\252/20260514-\344\275\234\344\270\232+\347\254\224\350\256\260.md" "b/\345\274\240\345\256\207\350\210\252/20260514-\344\275\234\344\270\232+\347\254\224\350\256\260.md" new file mode 100644 index 0000000..f740bef --- /dev/null +++ "b/\345\274\240\345\256\207\350\210\252/20260514-\344\275\234\344\270\232+\347\254\224\350\256\260.md" @@ -0,0 +1,162 @@ +## 路由参数传递 +### 动态路由概念 +在真实应用中,商品详情页、用户个人页等页面的 URL 中包含可变参数: + +``` +/item/101 +/item/205 +/item/899 +``` + +不可能为每个数据编写独立路由,需要使用动态路由来处理这类场景。 + +### 定义带参数的路由 +在路由路径中使用冒号 `:` 定义可变部分: + +```js +// src/router/index.js +import ItemDetailView from '../views/商品详情视图.vue' + +const routes = [ + { path: '/', component: HomePage }, + { path: '/items', component: ItemListView }, + // :itemId 是动态参数 + { path: '/item/:itemId', component: ItemDetailView } +] +``` + +### 在组件中获取路由参数 +使用 useRoute() 获取当前路由的信息: + +```js +// 在组件中使用 +import { useRoute } from 'vue-router' + +const route = useRoute() + +// 获取参数 +const itemId = route.params.itemId +``` + +### 完整的数据获取示例 +```vue + +``` + +### 跳转到带参数的路由 +方式一:模板中使用 RouterLink +```vue + +``` + +方式二:脚本中使用 useRouter +```vue + +``` + +### 命名路由方式跳转 +给路由定义名称,使用名称跳转更加灵活: + +```js +// router/index.js +const routes = [ + { + path: '/item/:itemId', + name: 'ItemDetail', + component: ItemDetailView + } +] +``` + +```vue + + + {{ item.name }} + + + + +``` + +### Query 查询参数 +除了路径参数,还支持 URL 查询参数: + +``` +/search?keyword=phone&sort=price +``` + +传递 query 参数: +```js +router.push({ + path: '/search', + query: { keyword: 'phone', sort: 'price' } +}) +``` + +获取 query 参数: +```js +const keyword = route.query.keyword +const sort = route.query.sort +``` + +### 路由参数与 Query 参数对比 + +| 类型 | 格式 | 示例 | 获取方式 | +|------|------|------|----------| +| 路径参数 | /item/:id | /item/101 | route.params.id | +| 查询参数 | ?key=value | /search?sort=price | route.query.sort | + +### 路由参数的响应式 +当路由参数变化时,组件不会自动重新渲染,需要监听: + +```js +import { watch } from 'vue' +import { useRoute } from 'vue-router' + +const route = useRoute() + +watch( + () => route.params.itemId, + (newId, oldId) => { + console.log(`从 ${oldId} 变为 ${newId}`) + // 重新获取数据 + fetchItemData(newId) + } +) +``` diff --git "a/\345\274\240\345\256\207\350\210\252/20260515-\344\275\234\344\270\232+\347\254\224\350\256\260.md" "b/\345\274\240\345\256\207\350\210\252/20260515-\344\275\234\344\270\232+\347\254\224\350\256\260.md" new file mode 100644 index 0000000..30e710a --- /dev/null +++ "b/\345\274\240\345\256\207\350\210\252/20260515-\344\275\234\344\270\232+\347\254\224\350\256\260.md" @@ -0,0 +1,232 @@ +## 导航控制与嵌套路由 +### 编程式导航概念 +`` 适用于模板中的声明式导航。但在业务场景中,经常需要在满足某些条件后才跳转,比如登录成功后跳转首页,这就需要在脚本中控制路由跳转。 + +```vue + +``` + +### useRouter 核心方法一览 + +| 方法 | 作用 | 示例 | +|------|------|------| +| push | 跳转到新页面,可后退 | router.push('/home') | +| replace | 替换当前页面,不可后退 | router.replace('/login') | +| back | 后退一步 | router.back() | +| forward | 前进一步 | router.forward() | +| go | 前进或后退指定步数 | router.go(-2) | + +### push 方法的多种用法 +```vue + +``` + +### replace 方法 +replace 不会留下历史记录,常用于避免用户返回到登录页: + +```vue + +``` + +### back 和 forward 方法 +```vue + + + +``` + +## 嵌套路由结构 +### 嵌套路由概念 +很多页面有共同的布局(顶部导航、侧边栏),页面内容区域才变化。嵌套路由用于实现这种"外壳+内容"的布局。 + +``` +/user ← 外壳 +/user/profile ← 内容区:个人信息 +/user/orders ← 内容区:我的订单 +/user/settings ← 内容区:设置 +``` + +### 配置嵌套路由 +在父路由中使用 children 属性配置子路由: + +```js +// src/router/index.js +import MainLayout from '../views/主布局.vue' +import ProfileView from '../views/用户/个人信息页.vue' +import OrdersView from '../views/用户/订单页.vue' +import SettingsView from '../views/用户/设置页.vue' + +const routes = [ + { path: '/', component: HomePage }, + { + path: '/user', + component: MainLayout, + children: [ + { + path: '', + redirect: '/user/profile' + }, + { + path: 'profile', + name: 'UserProfile', + component: ProfileView + }, + { + path: 'orders', + name: 'UserOrders', + component: OrdersView + }, + { + path: 'settings', + name: 'UserSettings', + component: SettingsView + } + ] + } +] +``` + +### 子路由路径规则 +- 子路由的 path 不需要加 `/` +- 系统会自动拼接父路由的路径 +- `profile` 实际匹配 `/user/profile` + +### 父路由组件布局 +父路由组件需要放置 `` 作为子路由内容的出口: + +```vue + + +``` + +### 路由重定向技巧 +访问父路径时自动跳转到默认子页面: + +```js +const routes = [ + { + path: '/user', + redirect: '/user/profile' + }, + { + path: '/user', + redirect: { name: 'UserProfile' } + } +] +``` + +### 捕获所有路由(404) +放在路由数组最后,匹配所有未定义的路径: + +```js +const routes = [ + // 其他路由... + + // 404 页面 + { + path: '/:pathMatch(.*)*', + name: 'NotFound', + component: NotFoundPage + } +] +``` + +### 完整的嵌套路由示例 +```js +// router/index.js +import { createRouter, createWebHistory } from 'vue-router' + +const routes = [ + { + path: '/', + component: MainLayout, + children: [ + { path: '', redirect: '/home' }, + { path: 'home', name: 'Home', component: HomePage }, + { path: 'about', name: 'About', component: AboutPage } + ] + }, + { + path: '/shop', + component: ShopLayout, + children: [ + { path: '', redirect: '/shop/products' }, + { path: 'products', name: 'Products', component: ProductsPage }, + { path: 'cart', name: 'Cart', component: CartPage } + ] + } +] + +const router = createRouter({ + history: createWebHistory(), + routes +}) + +export default router +``` -- Gitee