简体   繁体   English

在基于 typescript 的项目中使用 Vue js 组件

[英]Using Vue js components in typescript based project

I googled a lot to no avail and it seems I'm missing something obvious but still... I've created a project in a following stack : Vue+TS+Webpack+ASP.NET Core.我用谷歌搜索了很多无济于事,似乎我遗漏了一些明显的东西,但仍然......我在以下堆栈中创建了一个项目:Vue+TS+Webpack+ASP.NET Core。 Now I'm facing a cruel reality - there are literally dozens of good Vue components, but very few of them have something like *.d.ts attached.现在我面临一个残酷的现实——实际上有几十个优秀的 Vue 组件,但其中很少有附加 *.d.ts 之类的东西。 Is there some relatively easy (rewriting it in TS IMHO is not an easy solution) way to use JS-based Vue components in technology stack mentioned above?上面提到的技术栈中是否有一些相对简单(恕我直言在 TS 中重写不是一个简单的解决方案)的方法来使用基于 JS 的 Vue 组件?

PS: If you know nice modal dialog Vue component with out-of-the-box ts support let me know please :) Though of course I prefer to hear about more general solution. PS:如果您知道带有开箱即用 ts 支持的漂亮模态对话框 Vue 组件,请告诉我 :) 当然,我更喜欢听听更通用的解决方案。

I may not understand the whole situation but, enabling JS usage in webpack should be enough I guess.我可能不了解整个情况,但我想在 webpack 中启用 JS 就足够了。

{
  "compilerOptions": {
    "allowJs": true
  }
}

Vuejs 2.5+ ships with official type declarations for TypeScript. Vuejs 2.5+ 附带了 TypeScript 的官方类型声明。 You would have to install ts-loader , update webpack and ts config and write components like these你必须安装ts-loader ,更新 webpack 和 ts 配置并编写像这样的组件

tsconfig.json tsconfig.json

{
  "compilerOptions": {
    // this aligns with Vue's browser support
    "target": "es5",
    // this enables stricter inference for data properties on `this`
    "strict": true,
    // if using webpack 2+ or rollup, to leverage tree shaking:
    "module": "es2015",
    "moduleResolution": "node"
  }
}

some sample Vue component一些示例 Vue 组件

<script lang="ts">
import Vue from "vue";

export default Vue.extend({
    ...
});
</script>

If you use webpack and/or single component file, you would need additional settings as well.如果您使用 webpack 和/或单个组件文件,则还需要其他设置。

webpack.config.js webpack.config.js

module.exports = {
  entry: './src/main.ts', //TK a typescript file!
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  resolve: {
    extensions: ['.ts','.js'], //TK can't tell if this is actually necessary but is in all the sample code I found
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  module: {
    rules: [
      // TK THE LOADER: needed to process typescript files. Note the option used. We'll also need sfc.d.ts so that typescript can find the necessary .vue files
      // TK make sure to npm install ts-loader and npm link typscript if its installed globally
      {
        test: /\.ts$/,
        exclude: /node_modules|vue\/src/,
        loader: 'ts-loader',
        options: {
          appendTsSuffixTo: [/\.vue$/]
         }
      },
...

in case of single file component, you would need to add this file at root sfc.d.ts so that TypeScript can recognize this as module如果是单个文件组件,您需要将此文件添加到根sfc.d.ts以便 TypeScript 可以将其识别为模块

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

You can read more about it here你可以在这里阅读更多关于它的信息

As far as I have seen, props can't get typed with typescript, instead when you require them you can validate them as shown at vue prop validation so just search for common vue components.据我所见,道具不能用打字稿输入,而是当你需要它们时,你可以验证它们,如vue 道具验证所示,所以只需搜索常见的 vue 组件。

By the way I'm sure you've already seen the vue typescript support .顺便说一句,我相信你已经看过vue typescript support了。

About components, I think the best is to choose a framework like vuetify or bootstrap-vue where you will find a group of components following the same style关于组件,我认为最好是选择像vuetifybootstrap-vue这样的框架,在那里你会发现一组遵循相同样式的组件

I use Vuetify which supports typescript, and then if I need components which isn't supported by Vuetify(which rarely happens) and by Typescript;我使用支持打字稿的Vuetify ,然后如果我需要Vuetify(很少发生)和打字稿不支持的组件; I use require for instance:我使用require例如:

const component = require("module"); // If component does not support TS

import component from "module"; // If component support TS

I managed to use js-based components in a typescript environment by disabling eslint and tslint just for those components:我通过仅对这些组件禁用 eslint 和 tslint 来设法在 typescript 环境中使用基于 js 的组件:

  1. I put all my js-based components into /js/ directory in my project.我将所有基于 js 的组件放入项目的 /js/ 目录中。

  2. I added ignorePatterns to .eslintrc.js :我将ignorePatterns添加到.eslintrc.js

  ignorePatterns: [
    "**/js/*.vue",
    "**/js/*.js",
  ],
  1. I added exclude to tsconfig.json :我将exclude添加到tsconfig.json
 "exclude": [
    "node_modules",
    "src/**/js/*.vue",
    "src/**/js/*.js"
  ]

That made it work.这使它工作。

Here is my full configs for reference:这是我的完整配置供参考:

.eslintrc.js: .eslintrc.js:

module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    'plugin:vue/essential',
    'eslint:recommended',
    '@vue/typescript/recommended',
  ],
  parserOptions: {
    ecmaVersion: 2020,
    project: "./tsconfig.json",
    createDefaultProgram: true,
    async: false,
  },
  ignorePatterns: [
    "**/js/*.vue",
    "**/js/*.js",
  ],
  rules: {
    "no-throw-literal": "error",
    "no-return-await": "error",

    "@typescript-eslint/no-inferrable-types": "off",
    "@typescript-eslint/no-empty-function": "off",

    "@typescript-eslint/ban-ts-ignore": ["error"],
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/explicit-function-return-type": ["error"],
    "@typescript-eslint/explicit-member-accessibility": "off",
    "@typescript-eslint/no-unused-vars": ["error"],
    "@typescript-eslint/restrict-plus-operands": ["error"],
    "@typescript-eslint/restrict-template-expressions": "off",
    "@typescript-eslint/return-await": ["error", "always"],
    "@typescript-eslint/no-unsafe-call": ["error"],
    "@typescript-eslint/no-unsafe-return": ["error"],
    "@typescript-eslint/no-unsafe-member-access": ["error"],
    "@typescript-eslint/no-unused-vars-experimental": ["error"],
    "@typescript-eslint/no-unused-expressions": ["error"],
    "@typescript-eslint/unbound-method": ["error"],
    "@typescript-eslint/strict-boolean-expressions": ["error"],
    "@typescript-eslint/no-throw-literal": ["error"],

    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  }
}

tsconfig.json: tsconfig.json:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "jsx": "preserve",
    "allowJs": false,
    "moduleResolution": "node",
    "strict": true,
    "importHelpers": true,
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noUnusedParameters": true,
    "strictNullChecks": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "noErrorTruncation": true,
    "strictBindCallApply": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "emitDecoratorMetadata": true,
    "noEmitOnError": true,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "jest"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules",
    "src/**/js/*.vue",
    "src/**/js/*.js"
  ]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM