Please consider donating to this project's author, EGOIST, to show your ❤️ and support.
- Use all Vue SFC features in JavaScript / TypeScript files
- Type-safe Vue templates (#1)
Combine vue-loader
and lit-vue/loader
to make the dream come to reality.
yarn add lit-vue --dev
Previously you can use .vue
single-file component like this:
<template>
<div>
<h1>hello</h1>
<hr />
<button @click="inc">{{ count }}</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
methods: {
inc() {
this.count++
}
}
}
</script>
<style scoped>
h1 {
color: red;
}
</style>
Now with lit-vue
you can use .js
and .ts
extensions:
import { html } from 'lit-vue'
html`
<template>
<div>
<h1>hello</h1>
<hr />
<button @click="inc">{{ count }}</button>
</div>
</template>
<style scoped>
h1 {
color: red;
}
</style>
`
export default {
data() {
return {
count: 0
}
},
methods: {
inc() {
this.count++
}
}
}
You might need to configure the ESLint rule: no-unused-expressions
ESLint might complain about the the html``
expression not being used when you enabled the rule: no-unused-expressions, there're three ways to solve it:
- Disable this rule for tagged template expression in your ESLint config
{
"rules": {
"no-unused-expressions": ["error", { "allowTaggedTemplates": true }]
}
}
- Or export it
export const template = html`
<template>
<div>{{ count }}</div>
</template>
`
You can just assign it to a variable and export it, though the exported variable will never be used. The return value of html
tag is always undefined.
- Or use it as component option
const template = html`
<template>
<div>{{ count }}</div>
</template>
`
export default {
template,
data() {
return {
count: 0
}
}
}
Similar to #2, this may look more natural because template
is a legit Vue component option.
module.exports = {
module: {
rules: [
{
// Match .js .ts files
test: [/\.[jt]s$/],
// Exclude .vue.js .vue.ts files
// Since we want lit-vue to transform them into Vue SFC instead
exclude: [/\.vue.[jt]s/]
loader: 'babel-loader' // Use your desired loader
},
// Handle .vue.js .vue.ts with lit-vue/loader and vue-loader
{
test: [/\.vue.[jt]s$/],
use: [
'vue-loader',
'lit-vue/loader'
]
},
// This rule is also necessary even if you don't directly use .vue files
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
}
}
That's it, all the goodies of .vue
SFC are available in your .vue.js
and .vue.ts
files now!
<template>
inside html
is optional:
html`
<h1>hello</h1>
`
// or
html`
<template>
<h1>hello</h1>
</template>
`
When using templates without <template>
tag, you have to use <custom-block>
element to define custom blocks:
html`
<h1>hello</h1>
<custom-block name="i18n"> {"en": {}} </custom-block>
`
// or
html`
<template>
<h1>hello</h1>
</template>
<i18n> {"en": {}} </i18n>
`
And in fact even the whole Vue template is optional in html
tag, you can just use <style>
and custom blocks with render function instead:
import Vue from 'vue'
import Component from 'vue-class-component'
import { html } from 'lit-vue'
html`
<style scoped>
.msg {
color: red;
}
</style>
`
@Component({
props: {
name: String
}
})
export default class Welcome extends Vue {
// computed
get message() {
return 'hello ' + this.name
}
render() {
return <div class="msg">{this.message}</div>
}
}
To highlight the code inside html
template tag, you can use following editor plugins:
- VSCode: lit-html
- Something is missing? Send a PR to add it here!
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
lit-vue © EGOIST, Released under the MIT License.
Authored and maintained by EGOIST with help from contributors (list).
Website · GitHub @EGOIST · Twitter @_egoistlily