PageSourceSearch

https://www.yolo.blue/assets/js/79d4e520.a2aec425.js

js yolo.blue collected 2026-09-24 10:41:03 UTC 16,471 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkyolo=self.webpackChunkyolo||[]).push([["5324"],{40041(e,s,t){t.r(s),t.d(s,{metadata:()=>n,default:()=>h,frontMatter:()=>l,contentTitle:()=>c,toc:()=>d,assets:()=>u});var n=JSON.parse('{"id":"notes/develop/javascript/vue/use-vuetify-in-vitepress","title":"How to Use Vuetify\u2019s Components in a VitePress Website","description":"Use Vuetify\u2019s Components in a VitePress website, including installation, style isolation, and dark mode synchronization.","source":"@site/docs/notes/develop/javascript/vue/use-vuetify-in-vitepress.mdx","sourceDirName":"notes/develop/javascript/vue","slug":"/notes/develop/javascript/vue/use-vuetify-in-vitepress","permalink":"/docs/notes/develop/javascript/vue/use-vuetify-in-vitepress","draft":false,"unlisted":false,"tags":[{"inline":false,"label":"JavaScript","permalink":"/docs/tags/javascript"}],"version":"current","lastUpdatedAt":1763293244000,"frontMatter":{"description":"Use Vuetify\u2019s Components in a VitePress website, including installation, style isolation, and dark mode synchronization.","tags":["javascript"]},"sidebar":"docsSidebar","previous":{"title":"Mismatch in Module Imports between ES6 and CommonJS","permalink":"/docs/notes/develop/javascript/module-imports-mismatch-between-es6-and-commonjs"},"next":{"title":"\u5982\u4F55\u4F7F\u7528 Just My Socks \u79D1\u5B66\u4E0A\u7F51","permalink":"/docs/notes/develop/just-my-socks"}}'),r=t(74848),a=t(28453),i=t(50773),o=t(57250);let l={description:"Use Vuetify\u2019s Components in a VitePress website, including installation, style isolation, and dark mode synchronization.",tags:["javascript"]},c="How to Use Vuetify\u2019s Components in a VitePress Website",u={},d=[{value:"Step 1: Add Vuetify to your VitePress project",id:"step-1-add-vuetify-to-your-vitepress-project",level:2},{value:"Installation",id:"installation",level:3},{value:"Configuration",id:"configuration",level:3},{value:"Initialization",id:"initialization",level:3},{value:"Step 2: Use <code>vp-raw</code> class to remove VitePress\u2019s default styles from Vuetify\u2019s components",id:"step-2-use-vp-raw-class-to-remove-vitepresss-default-styles-from-vuetifys-components",level:2},{value:"Install <code>postcss</code>",id:"install-postcss",level:3},{value:"Transform CSS selectors",id:"transform-css-selectors",level:3},{value:"Apply <code>vp-raw</code> class to Vuetify\u2019s components",id:"apply-vp-raw-class-to-vuetifys-components",level:3},{value:"Step 3: Synchronize dark mode status from VitePress to Vuetify\u2019s components",id:"step-3-synchronize-dark-mode-status-from-vitepress-to-vuetifys-components",level:2}];function p(e){let s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",mdxAdmonitionTitle:"mdxAdmonitionTitle",p:"p",pre:"pre",...(0,a.R)(),...e.components},{Head:t}=s;return t||function(e,s){throw Error("Expected "+(s?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Head",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"how-to-use-vuetifys-components-in-a-vitepress-website",children:"How to Use Vuetify\u2019s Components in a VitePress Website"})}),"\n",(0,r.jsx)(t,{children:(0,r.jsx)("html",{lang:"en"})}),"\n",(0,r.jsx)(s.h2,{id:"step-1-add-vuetify-to-your-vitepress-project",children:"Step 1: Add Vuetify to your VitePress project"}),"\n",(0,r.jsx)(s.h3,{id:"installation",children:"Installation"}),"\n",(0,r.jsxs)(i.A,{groupId:"npm2yarn",children:[(0,r.jsx)(o.A,{value:"npm",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"npm i vuetify\n"})})}),(0,r.jsx)(o.A,{value:"yarn",label:"Yarn",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"yarn add vuetify\n"})})}),(0,r.jsx)(o.A,{value:"pnpm",label:"pnpm",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"pnpm add vuetify\n"})})}),(0,r.jsx)(o.A,{value:"bun",label:"Bun",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"bun add vuetify\n"})})})]}),"\n",(0,r.jsx)(s.h3,{id:"configuration",children:"Configuration"}),"\n",(0,r.jsxs)(s.p,{children:["Use ",(0,r.jsx)(s.a,{href:"https://www.npmjs.com/package/vite-plugin-vuetify",children:(0,r.jsx)(s.code,{children:"vite-plugin-vuetify"})})," to ",(0,r.jsx)(s.a,{href:"https://vuetifyjs.com/en/features/treeshaking/#automatic-treeshaking",children:"import used components and directives automatically"}),"."]}),"\n",(0,r.jsx)(s.admonition,{type:"warning",children:(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.code,{children:"vite-plugin-vuetify"})," plugin only works for ",(0,r.jsx)(s.a,{href:"https://vuejs.org/guide/scaling-up/sfc.html",children:"Vue Single-File Components"}),", when you ",(0,r.jsx)(s.a,{href:"https://vitepress.dev/guide/using-vue#using-vue-in-markdown",children:"use Vue in Markdown"}),", you still need to ",(0,r.jsx)(s.a,{href:"https://vuetifyjs.com/en/features/treeshaking/#manual-imports",children:"manually import components and directives"}),"."]})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-ts",metastring:'title=".vitepress/config.mts"',children:"import vuetify from 'vite-plugin-vuetify';\n\nexport default defineConfig({\n  // ...\n  vite: {\n    plugins: [vuetify()],\n    ssr: {\n      noExternal: ['vuetify'], // https://github.com/vuejs/vitepress/discussions/3578#discussioncomment-8495321\n    },\n  },\n});\n"})}),"\n",(0,r.jsx)(s.h3,{id:"initialization",children:"Initialization"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-ts",metastring:'title=".vitepress/theme/index.ts"',children:"import DefaultTheme from 'vitepress/theme';\nimport 'vuetify/styles';\nimport { createVuetify } from 'vuetify';\n\nconst vuetify = createVuetify({\n  ssr: true, // https://vuetifyjs.com/en/getting-started/installation/#ssr-caveats\n});\n\nexport default {\n  ...DefaultTheme,\n  enhanceApp({ app }) {\n    app.use(vuetify);\n  },\n};\n"})}),"\n",(0,r.jsxs)(s.h2,{id:"step-2-use-vp-raw-class-to-remove-vitepresss-default-styles-from-vuetifys-components",children:["Step 2: Use ",(0,r.jsx)(s.code,{children:"vp-raw"})," class to remove VitePress\u2019s default styles from Vuetify\u2019s components"]}),"\n",(0,r.jsxs)(s.h3,{id:"install-postcss",children:["Install ",(0,r.jsx)(s.code,{children:"postcss"})]}),"\n",(0,r.jsxs)(i.A,{groupId:"npm2yarn",children:[(0,r.jsx)(o.A,{value:"npm",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"npm i -D postcss\n"})})}),(0,r.jsx)(o.A,{value:"yarn",label:"Yarn",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"yarn add 
1--dev postcss\n"})})}),(0,r.jsx)(o.A,{value:"pnpm",label:"pnpm",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"pnpm add -D postcss\n"})})}),(0,r.jsx)(o.A,{value:"bun",label:"Bun",children:(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"bun add --dev postcss\n"})})})]}),"\n",(0,r.jsx)(s.h3,{id:"transform-css-selectors",children:"Transform CSS selectors"}),"\n",(0,r.jsxs)(s.p,{children:["Use ",(0,r.jsx)(s.a,{href:"https://github.com/vuejs/vitepress/blob/8aa6ccbe32655f76c390d15568f69f83d079385d/src/node/postcss/isolateStyles.ts",children:(0,r.jsx)(s.code,{children:"postcssIsolateStyles"})})," to transform all the CSS selector from related ",(0,r.jsx)(s.a,{href:"https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/styles",children:"CSS files"})," (typically ",(0,r.jsx)(s.a,{href:"https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/base.css",children:"base.css"}),", ",(0,r.jsx)(s.a,{href:"https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/components/vp-doc.css",children:"vp-doc.css"}),")."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-js",metastring:'title=".(/docs)/postcss.config.mjs"',children:"import { postcssIsolateStyles } from 'vitepress';\n\nexport default {\n  plugins: [\n    postcssIsolateStyles({\n      includeFiles: [/base\\.css/, /vp-doc\\.css/],\n    }),\n  ],\n};\n"})}),"\n",(0,r.jsxs)(s.p,{children:["For example, CSS selector ",(0,r.jsx)(s.code,{children:".xxx"})," became ",(0,r.jsx)(s.code,{children:".xxx:not(:where(.vp-raw, .vp-raw *))"})," so that it no longer takes effect on the element when the ",(0,r.jsx)(s.code,{children:"vp-raw"})," class is present."]}),"\n",(0,r.jsxs)(s.h3,{id:"apply-vp-raw-class-to-vuetifys-components",children:["Apply ",(0,r.jsx)(s.code,{children:"vp-raw"})," class to Vuetify\u2019s components"]}),"\n",(0,r.jsxs)(s.p,{children:["Wrap Vuetify\u2019s component with ",(0,r.jsx)(s.a,{href:"https://vitepress.dev/guide/markdown#raw",children:"raw"})," container"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-markdown",children:"::: raw\n<MyComponent />\n:::\n"})}),"\n",(0,r.jsxs)(s.p,{children:["or directly add ",(0,r.jsx)(s.code,{children:"vp-raw"})," class to it (or any of its parents)"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-markdown",children:'<MyComponent class="vp-raw"/>\n'})}),"\n",(0,r.jsxs)(s.admonition,{type:"tip",children:[(0,r.jsx)(s.mdxAdmonitionTitle,{children:(0,r.jsx)(s.a,{href:"https://vuejs.org/guide/components/registration.html#component-name-casing",children:"Component Name Casing"})}),(0,r.jsxs)(s.p,{children:["Vue supports resolving kebab-case tags to components registered using PascalCase. This means a component registered as ",(0,r.jsx)(s.code,{children:"MyComponent"})," can be referenced inside a Vue template (or inside an HTML element rendered by Vue) via both ",(0,r.jsx)(s.code,{children:"<MyComponent>"})," and ",(0,r.jsx)(s.code,{children:"<my-component>"}),"."]})]}),"\n",(0,r.jsx)(s.h2,{id:"step-3-synchronize-dark-mode-status-from-vitepress-to-vuetifys-components",children:"Step 3: Synchronize dark mode status from VitePress to Vuetify\u2019s components"}),"\n",(0,r.jsxs)(s.p,{children:["VitePress has a hook ",(0,r.jsx)(s.a,{href:"https://vitepress.dev/reference/runtime-api#usedata",children:(0,r.jsx)(s.code,{children:"useData"})})," which returns page-specific data, which contains a field ",(0,r.jsx)(s.code,{children:"isDark"}),". ",(0,r.jsx)(s.a,{href:"https://vuejs.org/guide/essentials/watchers.html",children:"Watch"})," this field to ",(0,r.jsx)(s.a,{href:"https://vuetifyjs.com/en/features/theme/#changing-theme",children:"change the theme of the Vuetify components"})," accordingly."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-js",children:"import { useData } from 'vitepress';\nimport { useTheme } from 'vuetify';\nimport { watchEffect } from 'vue';\n\nconst { isDark } = useData();\nconst theme = useTheme();\nwatchEffect(\n  () => {\n    theme.change(isDark.value ? 'dark' : 'light');\n  },\n  {\n    flush: 'post', // Post Watchers: https://vuejs.org/guide/essentials/watchers.html#post-watchers\n  },\n);\n"})})]})}function h(e={}){let{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},57250(e,s,t){t.d(s,{A:()=>o});var n=t(74848);t(96540);var r=t(34164),a=t(57663);function i({children:e,className:s,hidden:t}){return(0,n.jsx)("div",{role:"tabpanel",className:(0,r.A)("tabItem_Ymn6",s),hidden:t,children:e})}function o({children:e,className:s,value:t}){let{selectedValue:r,lazy:l}=(0,a.uc)(),c=t===r;return!c&&l?null:(0,n.jsx)(i,{className:s,hidden:!c,children:e})}},50773(e,s,t){t.d(s,{A:()=>p});var n=t(74848);t(96540);var r=t(34164),a=t(88287),i=t(57663),o=t(28584),l=t(19863);function c({className:e}){let{selectedValue:s,selectValue:t,tabValues:a,block:l}=(0,i.uc)(),u=[],{blockElementScrollPositionUntilNextRender:d}=(0,o.a_)(),p=e=>{let n=e.currentTarget,r=a[u.indexOf(n)].value;r!==s&&(d(n),t(r))}
1,h=e=>{let s=null;switch(e.key){case"Enter":p(e);break;case"ArrowRight":{let t=u.indexOf(e.currentTarget)+1;s=u[t]??u[0];break}case"ArrowLeft":{let t=u.indexOf(e.currentTarget)-1;s=u[t]??u[u.length-1]}}s?.focus()};return(0,n.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":l},e),children:a.map(({value:e,label:t,attributes:a})=>(0,n.jsx)("li",{role:"tab",tabIndex:s===e?0:-1,"aria-selected":s===e,ref:e=>{u.push(e)},onKeyDown:h,onClick:p,...a,className:(0,r.A)("tabs__item","tabItem_LNqP",a?.className,{"tabs__item--active":s===e}),children:t??e},e))})}function u({children:e}){return(0,n.jsx)("div",{className:"margin-top--md",children:e})}function d({className:e,children:s}){return(0,n.jsxs)("div",{className:(0,r.A)(a.G.tabs.container,"tabs-container","tabList__CuJ"),children:[(0,n.jsx)(c,{className:e}),(0,n.jsx)(u,{children:s})]})}function p(e){let s=(0,l.A)(),t=(0,i.OC)(e);return(0,n.jsx)(i.O_,{value:t,children:(0,n.jsx)(d,{className:e.className,children:(0,i.vT)(e.children)})},String(s))}},57663(e,s,t){t.d(s,{OC:()=>p,O_:()=>f,uc:()=>m,vT:()=>u});var n=t(74848),r=t(96540),a=t(56347),i=t(99989),o=t(96629),l=t(80618),c=t(41367);function u(e){return r.Children.toArray(e).filter(e=>"\n"!==e)}function d({value:e,tabValues:s}){return s.some(s=>s.value===e)}function p(e){let s,{defaultValue:t,queryString:n=!1,groupId:u}=e,p=function(e){let{values:s,children:t}=e;return(0,r.useMemo)(()=>{let e=s??r.Children.toArray(t).flatMap(e=>{if(!e)return[];if((0,r.isValidElement)(e)&&function(e){let{props:s}=e;return!!s&&"object"==typeof s&&"value"in s}(e))return[e];let s="string"==typeof e.type?e.type:e.type.name;throw Error(`Docusaurus error: Bad <Tabs> child <${s}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.
2If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)}).map(({props:{value:e,label:s,attributes:t,default:n}})=>({value:e,label:s,attributes:t,default:n})),n=(0,l.XI)(e,(e,s)=>e.value===s.value);if(n.length>0)throw Error(`Docusaurus error: Duplicate values "${n.map(e=>`'${e.value}'`).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[s,t])}(e),[h,m]=(0,r.useState)(()=>(function({defaultValue:e,tabValues:s}){if(0===s.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!d({value:e,tabValues:s}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${s.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let t=s.find(e=>e.default)??s[0];if(!t)throw Error("Unexpected error: 0 tabValues");return t.value})({defaultValue:t,tabValues:p})),[f,v]=function({queryString:e=!1,groupId:s}){let t=(0,a.W6)(),n=function({queryString:e=!1,groupId:s}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!s)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return s??null}({queryString:e,groupId:s});return[(0,o.aZ)(n),(0,r.useCallback)(e=>{if(!n)return;let s=new URLSearchParams(t.location.search);s.set(n,e),t.replace({...t.location,search:s.toString()})},[n,t])]}({queryString:n,groupId:u}),[j,x]=function({groupId:e}){let s=e?`docusaurus.tab.${e}`:null,[t,n]=(0,c.Dv)(s);return[t,(0,r.useCallback)(e=>{s&&n.set(e)},[s,n])]}({groupId:u}),y=d({value:s=f??j,tabValues:p})?s:null;return(0,i.A)(()=>{y&&m(y)},[y]),{selectedValue:h,selectValue:(0,r.useCallback)(e=>{if(!d({value:e,tabValues:p}))throw Error(`Can't select invalid tab value=${e}`);m(e),v(e),x(e)},[v,x,p]),tabValues:p,lazy:e.lazy??!1,block:e.block??!1}}let h=(0,r.createContext)(null);function m(){let e=r.useContext(h);if(!e)throw Error("useTabsContext() must be used within a Tabs component");return e}function f(e){return(0,n.jsx)(h.Provider,{value:e.value,children:e.children})}},28453(e,s,t){t.d(s,{R:()=>i,x:()=>o});var n=t(96540);let r={},a=n.createContext(r);function i(e){let s=n.useContext(a);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.