Vue + Typescript + Webpack:将html导入组件

时间:2019-03-25 10:31:56

标签: typescript vue.js webpack

我有一个打字稿+ Vue + Webpack应用程序,我想要将HTML与代码分开。
我遵循了this tutorial,并做了一个简单的Hello Word。

Webpack配置

const path = require('path');

module.exports = {
    mode: "development",
    entry: './src/app.ts',
    output: {
        path: path.resolve('dist'),
        filename: 'bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.(ts|tsx)?$/,
                loader: 'ts-loader',
                exclude: /node_modules/                
            },
            {
                test: /.html$/,
                loader: "vue-template-loader",
                exclude: /index.html/
            }
        ]
    },
    resolve: {
        extensions: [
            '.js',
            '.vue',
            '.tsx',
            '.ts'
        ]
    }
};

HTML

<div>
    <h2>Hello from {{message}}</h2>
</div>

Vue组件

import Vue from "vue";
import Component from "vue-class-component";
// template: '<button @click="onClick">Click!</button>'
import WithRender from "./home.html";

@WithRender
@Component
export default class HomeComponent extends Vue {

    public message: string = "Word";

    constructor() {
        super();
    }

    mounted() { }
}

我添加了这个 shim

declare module '*.html' {

        import Vue, { ComponentOptions, FunctionalComponentOptions } from 'vue'
        interface WithRender {
            <V extends Vue, U extends ComponentOptions<V> | FunctionalComponentOptions>(options: U): U
            <V extends typeof Vue>(component: V): V
        }

        const withRender: WithRender
        export default withRender
}

我(几乎)了解打字机装饰器的工作方式,但我不了解填充代码,该代码如何将html 注入Vue组件?

我从Typescript site阅读了有关装饰器的信息

1 个答案:

答案 0 :(得分:0)

vue-template-loader将HTML模板编译成render函数,@WithRender将其插入到类定义中。

例如,此HTML:

<div>Hello world</div>

转换为此render函数:

render(h) {
  return h('div', 'Hello world')
}

然后,将@WithRender(上面导入示例HTML模板的结果)应用于class Foo extends Vue {}会导致:

class Foo extends Vue {
  render(h) {
    return h('div', 'Hello world')
  }
}