]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
docs: rulekit link
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 3 Jul 2025 17:11:44 +0000 (19:11 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Thu, 3 Jul 2025 17:11:44 +0000 (19:11 +0200)
packages/docs/.vitepress/theme/components/RuleKitLink.vue [new file with mode: 0644]
packages/docs/.vitepress/theme/index.ts
packages/docs/guide/index.md
packages/docs/zh/guide/index.md

diff --git a/packages/docs/.vitepress/theme/components/RuleKitLink.vue b/packages/docs/.vitepress/theme/components/RuleKitLink.vue
new file mode 100644 (file)
index 0000000..dde1ac9
--- /dev/null
@@ -0,0 +1,204 @@
+<script setup lang="ts">
+import { useData } from 'vitepress'
+
+const { site } = useData()
+
+const translations = {
+  'en-US': 'Vibe code Vue apps with confidence',
+  'zh-CN': '自信地编写 Vue 应用的 Vibe 代码',
+}
+</script>
+
+<template>
+  <div class="rulekit">
+    <a
+      href="https://rulekit.dev?from=vuerouter"
+      target="_blank"
+      rel="sponsored noopener"
+      aria-label="Visit RuleKit - curated rules for Cursor, Claude Code, and more (opens in new tab)"
+      class="rulekit-link"
+    >
+      <div class="rulekit-content">
+        <div class="rulekit-left">
+          <span class="rulekit-sparkles" aria-hidden="true">✨</span>
+          <span class="rulekit-text">
+            <slot>{{ translations[site.lang] || translations['en-US'] }}</slot>
+          </span>
+        </div>
+        <div class="rulekit-right">
+          <svg
+            width="1024"
+            height="1024"
+            viewBox="0 0 1024 1024"
+            fill="none"
+            xmlns="http://www.w3.org/2000/svg"
+            role="img"
+            alt="RuleKit logo"
+            class="rulekit-logo"
+          >
+            <path
+              d="M335 694L353.947 697.225V737L335 733.775V694Z"
+              fill="currentColor"
+            />
+            <path
+              d="M355 538.234V673L335 669.766V536.078L355 538.234Z"
+              fill="currentColor"
+            />
+            <path
+              d="M259.255 329.5L313.424 338.585V414.78L374.576 425.512V350.39L422.5 359.457L422.529 391.816L399.251 388.374V443.756L375.649 440.537V460.314L313.424 449.576V430.878L287.675 426.585L286.602 367.561L259.255 364V329.5Z"
+              fill="currentColor"
+            />
+            <path
+              d="M398.897 113.5L647.031 158.597V199L676.034 205.5V276L836.085 304.623L896.239 362.605V498.968L873.681 516.147V778.5L914.5 792.095L755.522 914.5L180.84 802.832L130.354 738.409V472.125L103.5 457.092V336.835L164.728 270.264L291.48 205.5L321.557 211V176.85L350.56 165.5V139L398.897 113.5ZM379.562 148.933V184L350.56 182.218L349.485 259.527L379.562 263.822V184L582.581 218.725V300.328L622.325 307V224.094L598.693 220.873V188.661L379.562 148.933ZM433.271 218.725V234.831L561.097 257.379V240.2L433.271 218.725ZM291.48 234.831L223.807 272.412L740.484 364.752L802.786 325.024L673.885 302.476L622.325 330L561.097 319V282L433.271 259.527L389.23 285.296L321.557 275V240.2L291.48 234.831ZM180.84 288.517L128.206 343.277V440.537L233.475 461.387L232.401 360.457L259.255 364V446L284.103 449.576V476.42L311.889 480.714V750L373.117 762L374.191 691.165V493.599L399.251 497V472.125L422.5 476.42L422.529 391.816L449.383 396.964V500L543.911 516V414.143L571.839 418.438V388.374L624.474 396.964V423.807L652.402 428V534.5L778.08 551.5V443.756L731 392.244L180.84 288.517ZM831.789 336.835L757.671 383.005L796.341 423.807L871.533 374.416L831.789 336.835ZM807.083 445.281V529.032L871.533 486.083V404.48L807.083 445.281ZM571.839 449.576V521.516L587 524.5V592L606.213 595.603V527.5L624.474 531V458.5L571.839 449.576ZM155.06 472.125V729.5L191.5 778.5L713 880.5L754.448 853.298V579.497L635.215 560.17V601L682.479 609.562V649.29L663.144 647V682.575L682.479 684.723L683.5 814.5L652.402 808.201V839L543.911 819.5V788.874L511.685 783.505V654.5L532.095 658.5V623.52L511.685 620.299V578.424L557.875 585.94V545.138L422.5 521.516L402.12 538.234V654.658V766.326L373.117 762V791.021L311.889 778.5V750L285.035 744.851V512.926L264.5 493.599L155.06 472.125ZM778.08 579.497L780.228 833.971L847.901 781.358V538.234L778.08 579.497ZM561.097 627.5V664.5L543.911 661V788.874L565.394 793.169L567 669L584.729 672V632.5L561.097 627.5ZM611.583 639.626V676.5L628.77 679V802.832L652.402 808.201V682.575L635.215 680.428V643L611.583 639.626Z"
+              fill="currentColor"
+            />
+          </svg>
+          <span class="rulekit-title">RuleKit</span>
+        </div>
+      </div>
+    </a>
+  </div>
+</template>
+
+<style scoped>
+.rulekit {
+  margin: 1rem 0;
+}
+
+.rulekit-title {
+  font-family:
+    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
+    'Liberation Mono', 'Courier New', monospace;
+}
+
+.rulekit-link {
+  display: block;
+  padding: 1rem 1.5rem;
+  border-radius: 12px;
+  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
+  border: 1px solid #dee2e6;
+  text-decoration: none;
+  color: #212529;
+  transition: all 0.3s ease;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  position: relative;
+  overflow: hidden;
+}
+
+.rulekit-link:visited {
+  color: #212529;
+}
+
+.rulekit-link:focus {
+  outline: 2px solid #0066cc;
+  outline-offset: 2px;
+}
+
+.rulekit-link:focus:not(:focus-visible) {
+  outline: none;
+}
+
+.rulekit-link::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: -100%;
+  width: 100%;
+  height: 100%;
+  background: linear-gradient(
+    90deg,
+    transparent,
+    rgba(255, 255, 255, 0.4),
+    transparent
+  );
+  transition: left 0.6s ease;
+}
+
+.rulekit-link:hover::before {
+  left: 100%;
+}
+
+.rulekit-link:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+  background: linear-gradient(135deg, #f1f3f4 0%, #e2e6ea 100%);
+}
+
+.rulekit-content {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 1rem;
+  position: relative;
+  z-index: 2;
+}
+
+.rulekit-left {
+  display: flex;
+  align-items: center;
+  gap: 1rem;
+}
+
+.rulekit-right {
+  display: flex;
+  align-items: center;
+  gap: 0.5rem;
+}
+
+.rulekit-sparkles {
+  font-size: 1.5rem;
+}
+
+.rulekit-logo {
+  width: 2rem;
+  height: 2rem;
+  flex-shrink: 0;
+  color: #495057;
+}
+
+.rulekit-text {
+  font-weight: 500;
+  font-family:
+    'Spectral', ui-serif, system-ui, sans-serif, 'Apple Color Emoji',
+    'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+  font-size: 0.95rem;
+  line-height: 1.4;
+}
+
+/* Dark mode styles */
+.dark .rulekit-link {
+  background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
+  border-color: #404040;
+  color: #e5e5e5;
+}
+
+.dark .rulekit-link::before {
+  background: linear-gradient(
+    90deg,
+    transparent,
+    rgba(255, 255, 255, 0.15),
+    transparent
+  );
+}
+
+.dark .rulekit-link:hover {
+  background: linear-gradient(135deg, #262626 0%, #363636 100%);
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
+}
+
+.dark .rulekit-logo {
+  color: #ffffff;
+}
+
+.dark .rulekit-text {
+  color: #e5e5e5;
+}
+
+.dark .rulekit-link:visited {
+  color: #e5e5e5;
+}
+
+.dark .rulekit-link:focus {
+  outline-color: #66b3ff;
+}
+</style>
index 25da9d003a9f533110dbdb05e1b345d809640587..c2797c6bf9a6f9edfce605af78783c75e28afda2 100644 (file)
@@ -8,6 +8,7 @@ import './styles/vars.css'
 import VueSchoolLink from './components/VueSchoolLink.vue'
 import VueMasteryLogoLink from './components/VueMasteryLogoLink.vue'
 import status from '../translation-status.json'
+import RuleKitLink from './components/RuleKitLink.vue'
 
 const i18nLabels = {
   zh: '该翻译已同步到了 ${date} 的版本,其对应的 commit hash 是 <code>${hash}</code>。',
@@ -25,6 +26,7 @@ const theme: Theme = {
 
   enhanceApp({ app }) {
     app.component('VueSchoolLink', VueSchoolLink)
+    app.component('RuleKitLink', RuleKitLink)
     app.component('VueMasteryLogoLink', VueMasteryLogoLink)
   },
 
index 813ff64c5c7f02ad347fd24f0150c405441d113b..4399da53f146514e6714b2fa9e88bf56728b1cea 100644 (file)
@@ -14,6 +14,8 @@ Vue Router is built on Vue's component system. You configure **routes** to tell
 This guide will assume that you are already familiar with Vue itself. You don't need to be a Vue expert, but you may occasionally need to refer back to [the core Vue documentation](https://vuejs.org/) for more information about certain features.
 :::
 
+<RuleKitLink />
+
 ## An example
 
 To introduce some of the main ideas, we're going to consider this example:
@@ -27,9 +29,7 @@ Let's start by looking at the root component, `App.vue`.
 ```vue
 <template>
   <h1>Hello App!</h1>
-  <p>
-    <strong>Current route path:</strong> {{ $route.fullPath }}
-  </p>
+  <p><strong>Current route path:</strong> {{ $route.fullPath }}</p>
   <nav>
     <RouterLink to="/">Go to Home</RouterLink>
     <RouterLink to="/about">Go to About</RouterLink>
@@ -91,9 +91,7 @@ The `history` option controls how routes are mapped onto URLs and vice versa. Fo
 Once we've created our router instance, we need to register it as a plugin by calling `use()` on our application:
 
 ```js
-createApp(App)
-  .use(router)
-  .mount('#app')
+createApp(App).use(router).mount('#app')
 ```
 
 Or, equivalently:
@@ -212,4 +210,3 @@ The components `RouterView` and `RouterLink` are both [registered globally](http
 In templates, component names can be written in either PascalCase or kebab-case. Vue's template compiler supports either format, so `<RouterView>` and `<router-view>` are usually equivalent. You should follow whatever convention is used within your project.
 
 If you're using in-DOM templates then [the usual caveats](https://vuejs.org/guide/essentials/component-basics.html#in-dom-template-parsing-caveats) apply: component names must be written in kebab-case and self-closing tags are not supported. So rather than writing `<RouterView />`, you would need to use `<router-view></router-view>` instead.
-
index 5294ce0ad4a98273c35069adc8501e9ab169ba91..ef68b15c889fa1d3e67763736a4c20cc54e7c2e7 100644 (file)
@@ -14,6 +14,8 @@ Vue Router 基于 Vue 的组件系统构建,你可以通过配置**路由**来
 这份指南假设你已经对 Vue 有了一定的了解。你不必是 Vue 的专家,但你也许偶尔需要查看 [Vue 的文档](https://cn.vuejs.org/)来了解某些特性。
 :::
 
+<RuleKitLink />
+
 ## 示例
 
 为了引入一些核心概念,我们将使用如下的示例:
@@ -27,9 +29,7 @@ Vue Router 基于 Vue 的组件系统构建,你可以通过配置**路由**来
 ```vue
 <template>
   <h1>Hello App!</h1>
-  <p>
-    <strong>Current route path:</strong> {{ $route.fullPath }}
-  </p>
+  <p><strong>Current route path:</strong> {{ $route.fullPath }}</p>
   <nav>
     <RouterLink to="/">Go to Home</RouterLink>
     <RouterLink to="/about">Go to About</RouterLink>
@@ -82,9 +82,7 @@ const router = createRouter({
 一旦创建了我们的路由器实例,我们就需要将其注册为插件,这一步骤可以通过调用 `use()` 来完成。
 
 ```js
-createApp(App)
-  .use(router)
-  .mount('#app')
+createApp(App).use(router).mount('#app')
 ```
 
 或等价地:
@@ -126,7 +124,6 @@ export default {
 
 这里调用了 `push()`,这是用于[编程式导航](./essentials/navigation)的方法。我们会在后面详细了解。
 
-
 对于组合式 API,我们不能通过 `this` 访问组件实例,所以 Vue Router 给我们提供了一些组合式函数。演练场示例中的 `AboutView.vue` 组件使用了这种方法:
 
 ```vue
@@ -143,7 +140,7 @@ const search = computed({
   },
   set(search) {
     router.replace({ query: { search } })
-  }
+  },
 })
 </script>
 ```