Мне нужно добавить виджет Vue в существующее приложение TypeScript. Vue был объявлен как библиотека, которая позволяет легко реализовать графическое представление:
Vue.js более гибок, менее прост в решении. Это позволяет вам структурировать ваше приложение по своему усмотрению, а не заставлять его делать все на Angular. Vue - это просто уровень представления, поэтому вы можете использовать его в качестве ненавязчивой функции на странице приложения вместо полнофункциональной среды.
Но когда я искал, как реализовать компонент в Vue + TypeScript, единственные ссылки, которые я нашел, были о vue-cli, которые не адаптировались бы к уже существующему приложению, где компонент vue только один из многих.
Я постарался максимально использовать преимущества, поэтому я получил приложение vue-ts hello world и привязал его к пользовательской конфигурации веб-пакета. После многих попыток это было самое многообещающее webpack.config.js
:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
require('file-loader');
module.exports = {
entry: './src/main.ts',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'main.bundle.js'
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader'
},
{
test: /\.vue$/,
use: [{loader: 'vue-loader', options: {loaders: {}, esModule: false}}, {loader: 'ts-loader'}]
},
{
test: /\.css$/,
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }]
},
{
test: /\.(png|jpg|gif)$/,
loader: 'file-loader',
query: {
name: '[name].[ext]?[hash]',
useRelativePath: true
}
}
]
},
plugins: [
new HtmlWebpackPlugin({template: './index.html'}),
new VueLoaderPlugin()
],
resolve: {
alias: {
'vue$': 'vue/dist/vue.js' // I tried all of these...
},
extensions: ['.vue', '.ts', '.js', '.json']
},
};
Однако, даже если сборка завершается без усилий, страница Hello World не появляется, и я вижу это сообщение в консоли:
vue.js: 633 [Vue warn]: не удалось смонтировать компонент: шаблон или визуализацию
функция не определена.
найдено в
---> в src / App.vue
Это мой package.json
:
{ ...
"devDependencies": {
"@types/vue": "^2.0.0",
"@types/webpack-env": "^1.13.9",
"css-loader": "^2.1.1",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"style-loader": "^0.23.1",
"ts-loader": "^5.4.4",
"typescript": "^3.4.5",
"vue-loader": "^15.7.0",
"vue-template-compiler": "^2.6.10",
"webpack": "4.30.0",
"webpack-cli": "^3.3.1"
},
"dependencies": {
"core-js": "^3.0.1",
"vue": "^2.6.10",
"vue-class-component": "^7.0.2",
"vue-property-decorator": "^8.1.0"
}
}
Папка, которую я пытаюсь скомпилировать, состоит из 3 файлов на разных уровнях, типично для vue-cli приложений: main.ts , App.vue и HelloWorld.vue . Я не публикую код, чтобы вопрос был как можно более понятным, но если это необходимо, просто задайте его в комментарии.
Почему я получаю сообщение об ошибке в консоли?
Спасибо
Редактировать
В ответ на запрос я вставляю код App.vue и HelloWorld.vue :
App.vue:
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from './components/HelloWorld.vue';
@Component({
components: {
HelloWorld,
},
})
export default class App extends Vue {}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
HelloWorld.vue:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class HelloWorld extends Vue {
@Prop() private msg!: string;
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
main.ts:
import Vue from 'vue';
import App from './App.vue';
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App)
}).$mount('#app');