# Vue SFC [Vue.js](https://vuejs.org/), The Progressive JavaScript Framework, is an approachable, performant and versatile framework for building web user interfaces. This is the documentation for LiveCodes language support for Vue [Single-File Component (SFC)](https://vuejs.org/api/sfc-spec.html). The support for Vue 2 SFC (the older, EOL version) is [documented separately](./vue2.html.md). ## Usage Vue SFC can be used as documented in the [specs](https://vuejs.org/api/sfc-spec.html), including support for [Scoped CSS](https://vuejs.org/api/sfc-css-features.html#scoped-css), [CSS Modules](https://vuejs.org/api/sfc-css-features.html#css-modules), [pre-processors](https://vuejs.org/api/sfc-spec.html#pre-processors), [JSX](https://vuejs.org/guide/extras/render-function.html#jsx-tsx) and [`src` imports](https://vuejs.org/api/sfc-spec.html#src-imports). See below for usage. ### Demo import LiveCodes from '../../src/components/LiveCodes.tsx'; import RunInLiveCodes from '../../src/components/RunInLiveCodes.tsx'; ### Scoped CSS > When a `\n\n`, }; ### CSS Modules > A ``, }; ### CSS Frameworks [CSS Frameworks](../features/css.html.md)#css-processors) supported in LiveCodes (e.g. [Tailwind CSS](./tailwindcss.html.md), [UnoCSS](./unocss.html.md), [WindiCSS](./windicss.html.md)) can detect class names added in Vue SFCs. Make sure that the required utility is enabled (from style editor menu or in `processors` property of [configuration object](../configuration/configuration-object.html.md)#processors)). See [example below](#multiple-components). ### Languages and Pre-Processors > Blocks can declare pre-processor languages using the `lang` attribute. > > — [docs](https://vuejs.org/api/sfc-spec.html#pre-processors) Many of the [languages supported in LiveCodes](./index.html.md) can be used. The value of `lang` attribute can be the language name (specified in its documentation page) or any of its aliases (extensions). export const processorsDemo = { vue: `\n\n\n\n\n`, }; ### JSX JSX can be used in render functions without needing any configuration. export const jsxDemo = { vue: `\n\n`, }; ### `src` Imports The src attribute can be used to import an external file for a language block: ```html ``` The value of `src` attribute can be either: - Absolute URL (e.g. `https://unpkg.com/todomvc-app-css/index.css`) - Path in npm package (e.g. `todomvc-app-css/index.css`) Relative paths (e.g. `./my-styles.css`) cannot be used (because there is no file system in LiveCodes). The imported sources can use any of the supported languages/pre-processors (identified by the file extension or can be specified by `lang` attribute). ### Module Imports npm modules can be imported as described in the section about [module resolution](../features/module-resolution.html.md), including bare module imports and importing from different CDNs. Stylesheets imported in the `script` block are added as `` tags in the page `head`. Example: export const importsDemo = { vue: `\n\n\n`, }; Module imports can be customized using import maps as described in [module resolution](../features/module-resolution.html.md)#custom-module-resolution) documentations. ### Multiple Components Vue is supported in both [markup](../features/projects.html.md)#markup-editor) and [script](../features/projects.html.md)#script-editor) editors. This allows having a component in the markup editor that imports (and passes props to) a component in the script editor. The opposite is not supported. This can be done using relative import of a file name in the same directory. Any file name will resolve to the component in the script editor, e.g. `./script.vue`, `./Component.vue`, `./Counter.vue`, etc. export const multi = { markup: { language: 'vue', content: ` `, }, script: { language: 'vue', content: ` `, }, style: { language: 'css', content: '@import "tailwindcss";\n', }, processors: ['tailwindcss'], } Please note that LiveCodes [does not have the concept of a file system](../features/projects.html.md). However, you can configure [editor options](../configuration/configuration-object.html.md)#markup) like `title`, `order` and `hideTitle` to simulate multiple files, change editor order or even hide editors. Example: export const multiFiles = { ...multi, markup: { ...multi.markup, title: 'App.vue', }, script: { ...multi.script, title: 'Counter.vue', }, style: { ...multi.style, title: 'styles.css', order: 3, }, }; When both markup and script editors use Vue, the component in the markup editor is used as the main component rendered in the [root element](#root-element). To render the component in the script editor, it has to be imported and used by the main component. ### Importing External SFCs External Vue SFCs can be imported. The import URL has to be an absolute URL ending with `.vue` extension. Any bare or relative imports in the imported files are resolved and compiled recursively. This is an example of importing a Vue SFC, which in turn imports other Vue SFCs (the imported components use Tailwind CSS, which is enabled in this project as a CSS preprocessor): export const importExternal = { activeEditor: 'script', script: { language: 'vue', content: ` ` }, style: { language: 'css', content: '@import "tailwindcss";\n', }, processors: ['tailwindcss'], }
{ ' - ' } <>view source on GitHub
Please note that extensionless imports are not supported. However, you may customize the import URL using import maps as described in [module resolution](../features/module-resolution.html.md)#custom-module-resolution) section. Example: ```json title="Custom Settings" { "imports": { "https://raw.githubusercontent.com/hatemhosny/vue3-samples/master/src/composable/useTodoList": "https://raw.githubusercontent.com/hatemhosny/vue3-samples/master/src/composable/useTodoList.js", "https://raw.githubusercontent.com/hatemhosny/vue3-samples/master/src/composable/useMousePosition": "https://raw.githubusercontent.com/hatemhosny/vue3-samples/master/src/composable/useMousePosition.js" } } ``` export const importExternalWithImportMap = { activeEditor: 'script', script: { language: 'vue', content: ` `, }, imports: { "https://raw.githubusercontent.com/hatemhosny/vue3-samples/master/src/composable/useTodoList": "https://raw.githubusercontent.com/hatemhosny/vue3-samples/master/src/composable/useTodoList.js", "https://raw.githubusercontent.com/hatemhosny/vue3-samples/master/src/composable/useMousePosition": "https://raw.githubusercontent.com/hatemhosny/vue3-samples/master/src/composable/useMousePosition.js" } };
{' '} {' - '} <>view source on GitHub
### Importing Data URLs You may want to import other SFCs without having to host them on a server. These components can be encoded as [data URLs](https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data) and imported as usual. The data URL has to start with `data:text/vue` to be recognized as a Vue SFC. Any imports in the imported URLs (even if they are also data URLs) are resolved and compiled recursively. :::info The code in any code editor can be encoded as data URL from the LiveCodes UI using the "Copy code as data URL" button below the code editor. ::: This is the previous demo that uses data URLs (with nested imports) instead of external URLs: export const importDataUrls = { activeEditor: 'script', script: { language: 'vue', content: ` ` }, style: { language: 'css', content: '@import "tailwindcss";\n', }, processors: ['tailwindcss'], }
In the above demo, this component is imported: ``` data:text/vue;charset=UTF-8;base64,PHNjcmlwdCBzZXR1cCBsYW5nPSJ0cyI+DQppbXBvcnQgeyByZWYgfSBmcm9tICJ2dWUiOw0KaW1wb3J0IFByaW1hcnlCdXR0b24gZnJvbSAiZGF0YTp0ZXh0L3Z1ZTtjaGFyc2V0PVVURi04O2Jhc2U2NCxQSE5qY21sd2RDQnpaWFIxY0NCc1lXNW5QU0owY3lJK0RRcGtaV1pwYm1WUWNtOXdjeWg3RFFvZ0lIUnBkR3hsT2lCN0RRb2dJQ0FnZEhsd1pUb2dVM1J5YVc1bkxBMEtJQ0FnSUdSbFptRjFiSFE2SUNKQ2RYUjBiMjRpTEEwS0lDQjlMQTBLZlNrN0RRbzhMM05qY21sd2RENE5DZzBLUEhSbGJYQnNZWFJsUGcwS0lDQThZblYwZEc5dURRb2dJQ0FnWTJ4aGMzTTlJblJsZUhRdGJXUWdabTl1ZEMxdFpXUnBkVzBnWW1jdFozSmhlUzAxTURBZ2FHOTJaWEk2WW1jdFozSmhlUzAyTURBZ2RISmhibk5wZEdsdmJpQndlUzB4SUhCNExUUWdkR1Y0ZEMxM2FHbDBaU0J5YjNWdVpHVmtJR1J5YjNBdGMyaGhaRzkzTFhoc0lnMEtJQ0ErRFFvZ0lDQWdlM3NnZEdsMGJHVWdmWDBOQ2lBZ1BDOWlkWFIwYjI0K0RRbzhMM1JsYlhCc1lYUmxQZz09IjsNCmltcG9ydCBEYW5nZXJCdXR0b24gZnJvbSAiZGF0YTp0ZXh0L3Z1ZTtjaGFyc2V0PVVURi04O2Jhc2U2NCxQSE5qY21sd2RDQnpaWFIxY0NCc1lXNW5QU0owY3lJK0RRcGtaV1pwYm1WUWNtOXdjeWg3RFFvZ0lIUnBkR3hsT2lCN0RRb2dJQ0FnZEhsd1pUb2dVM1J5YVc1bkxBMEtJQ0FnSUdSbFptRjFiSFE2SUNKQ2RYUjBiMjRpTEEwS0lDQjlMQTBLZlNrN0RRbzhMM05qY21sd2RENE5DZzBLUEhSbGJYQnNZWFJsUGcwS0lDQThZblYwZEc5dURRb2dJQ0FnWTJ4aGMzTTlJblJsZUhRdGJXUWdabTl1ZEMxdFpXUnBkVzBnWW1jdGNtVmtMVFV3TUNCb2IzWmxjanBpWnkxeVpXUXROakF3SUhSeVlXNXphWFJwYjI0Z2NIa3RNU0J3ZUMwMElIUmxlSFF0ZDJocGRHVWdjbTkxYm1SbFpDQmtjbTl3TFhOb1lXUnZkeTE0YkNJTkNpQWdQZzBLSUNBZ0lIdDdJSFJwZEd4bElIMTlEUW9nSUR3dlluVjBkRzl1UGcwS1BDOTBaVzF3YkdGMFpUND0iOw0KDQpjb25zdCBjb3VudCA9IHJlZigwKTsNCjwvc2NyaXB0Pg0KDQo8dGVtcGxhdGU+DQogIDxkaXYgY2xhc3M9InctZnVsbCBtdC04IGZsZXgganVzdGlmeS1jZW50ZXIiPg0KICAgIDxzcGFuIHJlZj0iY291bnRlciIgY2xhc3M9InRleHQtM3hsIGZvbnQtYm9sZCI+e3sgY291bnQgfX08L3NwYW4+DQogIDwvZGl2Pg0KICA8ZGl2IGNsYXNzPSJ3LWZ1bGwgbXQtNCBmbGV4IGZsZXgtcm93IHNwYWNlLXgtNCBqdXN0aWZ5LWNlbnRlciI+DQogICAgPHByaW1hcnktYnV0dG9uIHJlZj0iZGVjcmVtZW50QnV0dG9uIiB0aXRsZT0iLSIgQGNsaWNrPSJjb3VudC0tIiAvPg0KICAgIDxwcmltYXJ5LWJ1dHRvbiByZWY9ImluY3JlbWVudEJ1dHRvbiIgdGl0bGU9IisiIEBjbGljaz0iY291bnQrKyIgLz4NCiAgPC9kaXY+DQogIDxkaXYgY2xhc3M9InctZnVsbCBtdC00IGZsZXggZmxleC1yb3cgc3BhY2UteC00IGp1c3RpZnktY2VudGVyIj4NCiAgICA8ZGFuZ2VyLWJ1dHRvbiByZWY9InJlc2V0QnV0dG9uIiB0aXRsZT0iUmVzZXQiIEBjbGljaz0iY291bnQgPSAwIiAvPg0KICA8L2Rpdj4NCjwvdGVtcGxhdGU+ ``` which imports these: ``` data:text/vue;charset=UTF-8;base64,PHNjcmlwdCBzZXR1cCBsYW5nPSJ0cyI+DQpkZWZpbmVQcm9wcyh7DQogIHRpdGxlOiB7DQogICAgdHlwZTogU3RyaW5nLA0KICAgIGRlZmF1bHQ6ICJCdXR0b24iLA0KICB9LA0KfSk7DQo8L3NjcmlwdD4NCg0KPHRlbXBsYXRlPg0KICA8YnV0dG9uDQogICAgY2xhc3M9InRleHQtbWQgZm9udC1tZWRpdW0gYmctZ3JheS01MDAgaG92ZXI6YmctZ3JheS02MDAgdHJhbnNpdGlvbiBweS0xIHB4LTQgdGV4dC13aGl0ZSByb3VuZGVkIGRyb3Atc2hhZG93LXhsIg0KICA+DQogICAge3sgdGl0bGUgfX0NCiAgPC9idXR0b24+DQo8L3RlbXBsYXRlPg== ``` ``` data:text/vue;charset=UTF-8;base64,PHNjcmlwdCBzZXR1cCBsYW5nPSJ0cyI+DQpkZWZpbmVQcm9wcyh7DQogIHRpdGxlOiB7DQogICAgdHlwZTogU3RyaW5nLA0KICAgIGRlZmF1bHQ6ICJCdXR0b24iLA0KICB9LA0KfSk7DQo8L3NjcmlwdD4NCg0KPHRlbXBsYXRlPg0KICA8YnV0dG9uDQogICAgY2xhc3M9InRleHQtbWQgZm9udC1tZWRpdW0gYmctcmVkLTUwMCBob3ZlcjpiZy1yZWQtNjAwIHRyYW5zaXRpb24gcHktMSBweC00IHRleHQtd2hpdGUgcm91bmRlZCBkcm9wLXNoYWRvdy14bCINCiAgPg0KICAgIHt7IHRpdGxlIH19DQogIDwvYnV0dG9uPg0KPC90ZW1wbGF0ZT4= ``` ### Root Element To [mount](https://vuejs.org/api/application.html#app-mount) the application instance to a specific DOM element use `"livecodes-app"` as the element `id` in the HTML. Otherwise, if that element is not found, a new `div` element is added to `document.body` and is used to mount the instance. Example: export const customRoot = { markup: { language: 'html', content: `

Custom Root Element

...other page content

`, }, script: { language: 'vue', content: ``, }, }; ## Language Info ### Name `vue` ### Extensions `.vue`, `.vue3` ### Editor `script`, `markup` ## Compiler The official [@vue/compiler-sfc](https://github.com/vuejs/core/tree/main/packages/compiler-sfc). ### Version `@vue/compiler-sfc`: v3.5.13 ## Code Formatting Using [Prettier](https://prettier.io/). ## Limitations Currently, Vue support has the following limitations: - SSR is not supported. - The [`defineProps()`](https://vuejs.org/guide/components/props#props-declaration) macro cannot infer props from TypeScript types not defined in the same file. [PRs are welcome](https://github.com/live-codes/livecodes/issues/757). ## Starter Template https://livecodes.io/?template=vue ## Links - [Vue.js](https://vuejs.org/) - [Vue SFC specs](https://vuejs.org/api/sfc-spec.html) - [CSS Modules](https://github.com/css-modules/css-modules)