0.0.2 • Published 5 years ago
vue-class-ts v0.0.2
vue-class-ts
Coding Vue happier with Class and TypeScript.
VueClassTs is a good helper for you to use Vue with Class and TypeScript, it's supported by vue-class-component, vue-property-decorator and vue-tsx-support
Usage
Install
npm install vue-class-ts
Config TypeScript with webpack
Install devDependencies
npm install --save-dev typescript ts-loader babel-plugin-syntax-jsx babel-plugin-transform-vue-jsx babel-helper-vue-jsx-merge-props babel-preset-env
TypeScript config: tsconfig.json
{
"include": [
"./src/**/*",
"./types/**/*",
"./node_modules/vue-class-ts/types/enable-tsx-check.d.ts" // Enable tsx check
],
"compilerOptions": {
"target": "es5",
"lib": ["dom", "es2018", "scripthost"],
"strict": true,
"module": "esNext",
"moduleResolution": "node",
"sourceMap": true,
"types": ["node"],
"experimentalDecorators": true,
"jsx": "preserve" // Enable tsx
}
}
Reference
webpack config
Add this to your vue webpack config
{
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
},
},
{
test: /\.tsx$/,
exclude: /node_modules/,
use: [
'babel-loader', // Transform vue jsx with babel
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
},
},
],
},
],
},
resolve: {
extensions: ['.js', '.vue', '.ts', '.tsx'],
},
}
Reference
- TypeScript: Integrating with Build Tools: webpack
- Microsoft/TypeScript-Vue-Starter
- vuejs/babel-plugin-transform-vue-jsx
babel config
{
"presets": ["env"],
"plugins": ["transform-vue-jsx"]
}
types/vue-shims.d.ts
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
Reference
Write your first vue component with tsx
src/components/NavBar/index.tsx
import Vue, { CreateElement } from 'vue'
import { ClassComponent, Component, Emit } from 'vue-class-ts'
import BackButton from '../BackButton'
import StatusBar from '../StatusBar'
import template from './template.vue'
export enum Mode {
Dark = 'dark',
Light = 'light',
}
interface IProps {
mode?: Mode,
}
@ClassComponent({
mixins: [template],
props: {
mode: {
type: String,
default: Mode.Dark,
},
},
})
export default class NavBar extends Component<IProps> {
@Emit()
public back() {
return
}
private render(h: CreateElement) {
return (
<div>
<StatusBar />
<div class={this.navBarClass}>
<div class="left">
<BackButton mode={this.$props.mode} onClick={this.back} />
</div>
<div class="middle">
{this.$slots.default}
</div>
<div class="right">
</div>
</div>
</div>
)
}
private get navBarClass() {
return {
RealNavBar: true,
darkMode: this.$props.mode === Mode.Dark,
lightMode: this.$props.mode === Mode.Light,
}
}
}
src/components/NavBar/template.vue
<style scoped>
.RealNavBar {
display: flex;
justify-content: center;
align-items: center;
height: 44px;
font-size: 18px;
line-height: 20px;
font-weight: 500;
}
.darkMode {
background: white;
color: #333;
}
.lightMode {
background: transparent;
color: white;
}
.left,
.middle,
.right {
display: flex;
flex: 1;
height: 100%;
align-items: center;
}
.middle {
justify-content: center;
}
</style>