As a lover of TypeScript InteliSense and Vue, I have always tried to use TypeScript in Vue, but Vetur isn't as smart as it should...
- It doesn't suggest as well as raw
*.ts
. - It doesn't work well with a Monorepo / non-root -- https://github.com/vuejs/vetur/issues/815
So, I have found some fixes --
After, vue create <APP_NAME>
- Change
src/App.vue
tosrc/pages/App/index.(tsx|css)
- Change
components/HelloWorld.vue
tosrc/components/HelloWorld/index.(tsx|css)
- Change
.eslintrc.js
to
module.exports = {
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: true,
},
},
}
- I seems to not need to change
.babelrc
as in https://github.com/vuejs/jsx, nor install additional packages.
src/pages/App/index.tsx
will be the following
import { Component, Vue } from 'vue-property-decorator'
import HelloWorld from '@/components/HelloWorld'
import './index.css'
@Component({
components: {
HelloWorld,
},
})
export default class App extends Vue {
render () {
return (
<div id="app">
<img alt="Vue logo" src={ require('@/assets/logo.png') } />
<HelloWorld props={ { msg: 'Welcome to Your Vue.js + TypeScript App' } } />
</div>
)
}
}
About src/components/HelloWorld/index.tsx
, you could probably guess, but in short,
- There needs to be a
/>
or a closing tag. - Props might not work properly. You need
props={ { msg: 'Welcome to Your Vue.js + TypeScript App' } }
. - Don't forget to add
this.
-
require('@/assets/logo.png')
seems to work because of some Webpack loader in Vue CLI.
TLDR / Take Home Message
-
Vetur in VSCode does not always work fully for TypeScript, especially in a Monorepo
- The best fix is indeed, do not use TypeScript in
*.vue
- One of the workarounds is
<script lang="ts" src="./index.ts">
- The best fix is indeed, do not use TypeScript in
-
Vue template string isn't as smart as TypeScript Intellisense.
- The workaround is, do not use
<template>
. Use*.tsx
(or*.jsx
) instead.
- The workaround is, do not use
- It is still simple to reference foldered component if you filename is
./index.tsx
-
import HelloWorld from '@/components/HelloWorld'
for example, will reference@/components/HelloWorld/index.tsx
, will full IntelliSnese.
-
-
@angular/cli
'sng generate component App
doesn't even create a Single File Component, but instead create a single folder with multiple components.
./src/app/comp
├── comp.component.html
├── comp.component.scss
├── comp.component.spec.ts
└── comp.component.ts
Summary
In summary, do not use *.vue
, if you want a better IntelliSense. There are other approaches in component-based structure; like a folder.
Why does Vue adopt Single File Components at all, as it isn't necessarily better than Angular's?
I have also tried https://github.com/vuejs/jsx, but Vue CLI seems to already support JSX by default.
If you stuck somewhere, see this repo. I might also add Nuxt in the future.
Top comments (1)
I'd just like to add a couple updates to this for anyone reading this:
First, Volar has now replaced Vetur as the official Vue extension for VS Code in Vue 3.
Second, you may run into a weird error when using Volar and Typescript. Volar complains that
TypeScript intellisense is disabled on template
.The solution to this is to add
"jsx": "preserve"
in thecompilerOptions
of your.tsconfig
:I wrote about this solution on my blog if you happen to run into this and want more details on this error.