【问题标题】:Resolve "Property does not exist on type 'Vue'" error解决“'Vue' 类型的属性不存在”错误
【发布时间】:2018-01-15 05:49:22
【问题描述】:

我正在使用 Typescript 和 Vuejs 来构建应用程序。我有几个独立的组件 (.vue) 文件要导入到 Typescript (.ts) 文件中。在 Typescript 文件中,我从 npm Vue 库中导入 Vue,然后创建一个新的 Vue 来显示我的组件。我看到的错误是:

类型“Vue”上不存在属性 x

我的构建系统是带有 tsc 的 Webpack。为什么我会收到此错误,我该如何解决?

main.ts

import Vue from 'vue';
import Competency from '../components/competency.vue';

new Vue({
  el: "#app",
  components: {
    'competency': Competency
  },
  data:{
    count: 0
  },
  methods:{
    initialize: function(){
      this.count = count + 1; // Errors here with Property count does not exist on type vue
    }
  }
})

tsconfig

{
  "compilerOptions": {
    // "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "lib": [
      "es2015",
      "dom",
      "es2015.promise"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noImplicitAny": false,
    //"outDir": "./build/",
    "removeComments": false,
    "sourceMap": true,
    "target": "es5"

  },
  "exclude": [
    "./node_modules",
    "wwwroot",
    "./Model"
  ],
  "include": [
    "./CCSEQ",
    "./WebResources"
  ]
}

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    entry: {
        Evaluations: './WebResources/js/main.ts'
    },
    devServer: {
        contentBase: './dist'
    },
    module: {
        rules: [{
                test: /\.ts$/,
                exclude: /node_modules|vue\/src/,
                loader: 'ts-loader',
                exclude: /node_modules/,
                options: {
                    appendTsSuffixTo: [/\.vue$/]
                }
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    esModule: true
                }
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
        ]
    },
    resolve: {
        extensions: [".tsx", ".ts", ".js"],
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            filename: 'Evaluations.html',
            template: './WebResources/html/Evaluations.html'
        }), new HtmlWebpackPlugin({
            filename: 'ExpenseUpload.html',
            template: './WebResources/html/ExpenseUpload.html'
        }), new webpack.optimize.CommonsChunkPlugin({
            name: 'WebAPI'
        })
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
}

【问题讨论】:

  • 也许这只是创建这个例子时的一个错字,但你不只是在你的设置中错过了一个“this”吗? this.count = count + 1; 应该是 this.count = this.count + 1;

标签: typescript webpack vue.js vuejs2 vue-component


【解决方案1】:

您应该声明导入 *.vue 文件。

如:

vue-file-import.d.ts

declare module "*.vue" {
   import Vue from "vue";
   export default Vue;
}

【讨论】:

    【解决方案2】:

    我有同样的问题,但导出组件。 一些 vs code sn-ps 创建模板没有必要的错字,如下所示

    export default {
      data() {
        return {
          x: "something",
        };
      },
      methods: {
        rename(name: string) {
          this.x = name;
        },
        
      },
    };
    

    问题是我没有将defineComponent() 添加到导出默认值。应该是这样的

    
    import { defineComponent } from "vue";
    
    export default defineComponent({
      data() {
        return {
          x: "something",
        };
      },
      methods: {
        rename(name: string) {
          this.x = name;
        },
        
      },
    });
    
    

    确保您使用 defineComponent() 函数导出组件

    【讨论】:

    • 以上对我不起作用。 import { defineComponent } from "vue"; 行给出错误:Module '"vue"' has no exported member 'defineComponent'. Did you mean to use 'import defineComponent from "vue"' instead?
    • 如果您使用的是nuxt,请使用compostion api 导入defineComponentimport { defineComponent } from "@nuxtjs/composition-api";
    【解决方案3】:

    添加另一个答案以汇总您可能需要修复的几件事。

    确保在导入的文件名中包含“.vue”扩展名

    同时

    import Competency from '../components/competency';
    

    import Competency from '../components/competency.vue';
    

    可能编译成功,第二个将有助于避免在某些IDE中出现的错误,例如VS Code。

    添加 shim 类型文件

    正如@May 上面指出的,您需要一个导入和重新导出“Vue”类型的文件。在@May 的回答中,它被命名为vue-file-import.d.ts,但在互联网的其他地方,它通常被称为vue-shim.d.ts。不管名字,需要的内容都是一样的:

    // vue-file-import.d.ts
    
    declare module "*.vue" {
       import Vue from "vue";
       export default Vue;
    }
    

    为 shim 文件尝试不同的位置。

    最初我把它放在/src。我发现这有一个奇怪的效果。有时它会起作用,即 VS Code 错误消息消失了;其他时候没有,他们又出现了。当我在项目中移动并编辑不同的文件时,这种情况会动态发生。

    我后来发现建议使用相同内容的 shim 文件,但要放在 /typings 中。我试过这个,它一直有效。其他人似乎对/src 位置很满意。

    【讨论】:

      【解决方案4】:

      我试图关注此页面 https://vuejs.org/v2/guide/routing.html 并遇到相同的 TypeScript 错误,我通过将 Vue 实例强制转换为类似这样的类型来修复它

          new Vue({
              el: '#app',
              data: {
                  currentRoute: window.location.pathname
              },
              computed: {
                  ViewComponent() {
                      return routes[(this as any).currentRoute] || routes['/']
                  }
              },
              render (h) { return h((this as any).ViewComponent) }
          })
      

      【讨论】:

      • 你怎么能认为这是一种改进?用 TS 代替 JS 有什么意义?
      • TypeScript 为您提供编译时错误而不是运行时错误,因为类型安全。它还添加了 js 没有的东西,比如接口和联合类型。 IMO 它比 js 好多了。
      • 这不是我的问题。如果你用强制转换“as any”来点亮你的 TS 代码,那么类型安全性是无效的,并且使用 TS 的意义是空的。
      • 在这个小案例中确实如此,我不认为仅仅因为主要的新 Vue 语句中有两个“任何”就使其不值得使用 TS。这是 Vue 没有声明文件的错(虽然我有一段时间没看过 Vue,但他们现在可能有)。
      • 您需要像这样定义计算属性返回类型:ViewComponent(): string[] {
      【解决方案5】:

      我建议在使用 typescript (have a look at this "Writing Class-Based Components with Vue.js and TypeScript") 时使用基于类的组件。这是拥有类型安全代码和使用 IDE 的自动完成功能的唯一方法

      你需要安装vue-property-decorator

      这是一个基于类的组件示例:

      import { Component, Vue, Watch } from 'vue-property-decorator'
      
      @Component({
        props: {
          prop1: { type: Number }
        }
      })
      export default class MyComponent extends Vue {
        // This is how you define computed
        get myComputedRoute() {
           return this.$route.params;
        }
      
        @Watch('myComputedRoute')
        onPropertyChanged(value: string, oldValue: string) {
          // Do stuff with the watcher here.
        }
      }
      

      【讨论】:

        【解决方案6】:

        我遇到了类似的问题(尤其是在 .vue 文件中)。我确实发现这似乎可以解决问题。在您导入 .vue 文件的任何地方,将 ES6 样式的“import”改为“require”。

        所以在你的例子中,改变:

        import Competency from '../components/competency.vue';
        

        到...

        declare var require: any;
        var Competency = require("../components/competency.vue").default;
        

        【讨论】:

          【解决方案7】:

          我在使用 vue 2.8.2 和 Typescript 2.5.3 时遇到了同样的错误。我通过将我的 Vue 实例保存在一个变量中然后给它一个类型来修复它。这样可以确保 TS 在您使用选项对象实例化它时知道所有 Vue 属性。

          var VueApp: any = Vue;
          
          var App = new VueApp({
            el: "#app",
            data() {
               return {
                  count: 0
               }
            },
            methods:{
              initialize() {
                this.count = count + 1; // Should work now
              }
            }
          })

          【讨论】:

            【解决方案8】:

            不要使用任何

            改用Object.assign(vm, source);

            喜欢

            const source= {count: this.count }
            Object.assign(this, source);
            

            【讨论】:

              【解决方案9】:

              我在使用 VS Code 编辑器时遇到了这个错误。

              我在 vs code 上安装了 Vetur 插件,Vetur 将 vue 文件作为 typescript 文件处理,所以我已经修复它来编辑 settings.json 文件

              请在 VS 编辑器的项目根目录中找到此文件,然后像下面这样设置更改

              "vetur.experimental.templateInterpolationService": false
              

              对我有用

              【讨论】:

                【解决方案10】:

                尝试使用 Typescript 的泛型。见https://www.typescriptlang.org/docs/handbook/generics.html

                new Vue<{ count: number }, { initialize: () => void }, {}, {}>({
                
                  //...
                
                  data:{
                    count: 0
                  },
                
                  methods:{
                    initialize: function() {
                      this.count = count + 1;
                    },
                  }
                });
                

                【讨论】:

                  猜你喜欢
                  • 2021-12-05
                  • 2022-01-07
                  • 1970-01-01
                  • 2019-10-10
                  • 2016-07-18
                  • 1970-01-01
                  • 2017-02-09
                  • 2020-12-18
                  • 2021-12-17
                  相关资源
                  最近更新 更多