Vue Cli 3.0 创建TypeScript项目

笔记来源:http://www.bookcss.com/note/12/59

一、Vue CLI安装

使用的是vue cli 3.0版本

npm install -g @vue/cli

检测是否安装

vue --version

安装全局扩展

npm install -g @vue/cli-service-global

运行单个.vue文件

vue serve Hello.vue

二、创建项目

  1. 创建一个项目
vue create hello-world
  1. 安装router、vuex
vue add router
vue add vuex
  1. 安装eslint
vue add @vue/eslint

eslint相关文档:http://eslint.cn/docs/user-guide/getting-started

  1. 安装typescript
vue add @vue/typescript

三、Vue.config.js配置说明

const path = require('path');

function resolve(dir) {
    return path.join(__dirname, dir)
}

module.exports = {

    // 把开发服务器假设在根路径
    publicPath: process.env.NODE_ENV === 'production' ? './' : '/',

    // 生成文件的目录名称
    outputDir: "dist",

    //用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
    assetsDir: "static",

    // 默认情况下,生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存。
    filenameHashing: true,

    // 不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建,map就是为了方便打印错误位置。
    productionSourceMap: false,

    // 设置单页面与多页面
    // 多页面情况下,每个“page”应该有一个对应的 JavaScript 入口文件。其值应该是一个对象,对象的 key 是入口的名字,value 是:
    // 一个指定了 entry, template, filename, title 和 chunks 的对象 (除了 entry 之外都是可选的);
    // 或一个指定其 entry 的字符串。
    // 具体情况看官网 https://cli.vuejs.org/zh/config/#pages
    // pages: {
    //     index: {
    //         // page 的入口
    //         entry: 'src/main.ts',
    //         // 模板来源
    //         template: 'public/index.html',
    //         // 在 dist/index.html 的输出
    //         filename: 'index.html',
    //         title: 'Vui库',
    //         // 提取出来的通用 chunk 和 vendor chunk。
    //         chunks: ['chunk-vendors', 'chunk-common', 'index']
    //     }
    // },

    //默认情况下,只有以文件结尾的文件*.module.[ext]才会被视为CSS模块。将此设置为true允许您.module放入文件名并将所有*.(css|scss|sass|less|styl(us)?)文件视为CSS模块。
    //extract true在生产中,false在开发中,是否将组件中的CSS提取到独立的CSS文件中(而不是在JavaScript中内联并动态注入,在开发模式下禁用提取CSS,因为它与CSS热重新加载不兼容
    //sourceMap是否为CSS启用源映射。将此设置为true可能会影响构建性能
    //将选项传递给与CSS相关的加载器
    css: {
        modules: false,
        //extract: true, //设为true的话热更新会出问题
        sourceMap: false,
        loaderOptions: {
            css: {
                // options here will be passed to css-loader
            },
            postcss: {
                // options here will be passed to postcss-loader
            }
        }
    },

    // 是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了,但是这会让你的应用额外增加 10kb 左右。
    // 具体信息看官网 https://cn.vuejs.org/v2/guide/installation.html#运行时+编译器vs.只包含运行时
    runtimeCompiler: false,

    // 开启eslint
    // 设置为 true 时,eslint-loader 会将 lint 错误输出为编译警告。默认情况下,警告仅仅会被输出到命令行,且不会使得编译失败。
    // 设置为 error 时,这会强制 eslint-loader 将 lint 错误输出为编译错误,同时也意味着 lint 错误将会导致编译失败。
    lintOnSave: 'error',

    devServer: {
        // 与devServer.quiet启用,那么除了该初始启动信息将被写入到控制台。这也意味着webpack中的错误或警告不可见。
        // quiet: true,
        
        // 通过设置让浏览器 overlay 同时显示警告和错误 在 devServe 配置项中  ==>
        overlay: {
            warnings: true,
            errors: true
        }
    },

    configureWebpack: {
        name: '基于Vue的前端ui库',
        resolve: {
            extensions: ['.js', '.ts', '.tsx', '.json'],
            alias: {
                '@': resolve('src')
            }
        }
    },

    chainWebpack: config => {

        // set svg-sprite-loader
        config.module
            .rule('svg')
            .exclude.add(resolve('src/icons'))
            .end();

        config.module
            .rule('icons')
            .test(/\.svg$/)
            .include.add(resolve('src/icons'))
            .end()
            .use('svg-sprite-loader')
            .loader('svg-sprite-loader')
            .options({
                symbolId: 'icon-[name]'
            })
            .end();

        // set preserveWhitespace
        config.module
            .rule('vue')
            .use('vue-loader')
            .loader('vue-loader')
            .tap(options => {
                options.compilerOptions.preserveWhitespace = true
                return options
            })
            .end();

        config
        
            // https://webpack.js.org/configuration/devtool/#development
            .when(process.env.NODE_ENV === 'development',
                config => config.devtool('cheap-source-map')
            );

        config
            .when(process.env.NODE_ENV !== 'development',
                config => {
                    config
                        .plugin('ScriptExtHtmlWebpackPlugin')
                        .after('html')
                        .use('script-ext-html-webpack-plugin', [{
                            // `runtime` must same as runtimeChunk name. default is `runtime`
                            inline: /runtime\..*\.js$/
                        }])
                        .end();
                    config
                        .optimization.splitChunks({
                        chunks: 'all',
                        cacheGroups: {
                            libs: {
                                name: 'chunk-libs',
                                test: /[\\/]node_modules[\\/]/,
                                priority: 10,
                                chunks: 'initial' // only package third parties that are initially dependent
                            },
                            commons: {
                                name: 'chunk-commons',
                                test: resolve('src/components'), // can customize your rules
                                minChunks: 3, //  minimum common number
                                priority: 5,
                                reuseExistingChunk: true
                            }
                        }
                    });
                    config.optimization.runtimeChunk('single')
                }
            );

        //在单独的进程中,运行打字类型检查器的webpack插件
        config.plugin('fork-ts-checker').tap(([options]) => {
            return [{
                //以下几项都是推荐配置,async false使其可以在页面上显示
                async: false,
                tslint: true,
                vue: true
            }]
        })
    }
};

更多配置请查看:https://cli.vuejs.org/zh/config/#vue-config-js

四、TSlint配置

  1. 安装tslint
<!--全局-->
npm install -g tslint

<!--当前项目-->
npm install -D tslint

初始化或自己创建tslint.json文件:

tslint --init

根据自己需要配置:

{
  "defaultSeverity": "warning",
  // 推荐的规则
  "extends": [
    "tslint:recommended"
  ],
  "linterOptions": {
    "exclude": [
      "node_modules/**"
    ]
  },
  "rules": {
    "prefer-const" : false,

    "interface-name" : [true, "never-prefix"],
    //禁用 console
    "no-console": [false, "log", "error"],

    //设置成员对象的访问权限(public,private,protect)
    "member-access": false,
    // 禁止自动检测末尾行必须使用逗号,always总是检测,never从不检测,ignore忽略检测
    "trailing-comma": [
      true,
      {
        "singleline": "never",
        "multiline": {
          "objects": "ignore",
          "arrays": "ignore",
          "functions": "never",
          "typeLiterals": "ignore"
        }
      }
    ],
    //检查对象文字中键的排序。
    //使用默认的字母顺序时,可以使用其他空行将对象属性组合在一起,同时按字母顺序保持每个组中的元素。
    "object-literal-sort-keys": false,
    // 禁止给类的构造函数的参数添加修饰符
    "no-parameter-properties": false,
    // 禁止使用 debugger
    "no-debugger": false,
    // 禁止行尾有空格
    "no-trailing-whitespace": false,
    // 禁止无用的表达式
    "no-unused-expression": true,
    // 定义过的变量必须使用
    "no-unused-variable": false,
    // 变量必须先定义后使用
    "no-use-before-declare": true,
    // 禁止使用 var
    "no-var-keyword": true,
    // 必须使用 === 或 !==,禁止使用 == 或 !=,与 null 比较时除外
    "triple-equals": true,
    // 指定类成员的排序规则
    "member-ordering": false,
    // 禁止将 this 赋值给其他变量,除非是解构赋值
    "no-this-assignment": [
      false,
      {
        "allowed-names": [
          "^self$",
          "^that$"
        ],
        "allow-destructuring": true
      }
    ],
    // 必须使用箭头函数,除非是单独的函数声明或是命名函数
    "only-arrow-functions": [
      true,
      "allow-declarations",
      "allow-named-functions"
    ],
    // 禁止出现空代码块,允许 catch 是空代码块
    "no-empty": [
      true,
      "allow-empty-catch"
    ],
    // 禁止无用的类型断言
    "no-unnecessary-type-assertion": true,
    // 使用 return; 而不是 return undefined;
    "return-undefined": true,
    // 禁止对 array 使用 for in 循环
    "no-for-in-array": true,
    "comment-format": [
      true,
      "check-space"
    ],
    // 单行注释格式化规则
    // 定义函数时如果用到了覆写,则必须将覆写的函数写到一起
    "adjacent-overload-signatures": true,
    // 禁止对函数的参数重新赋值
    "no-parameter-reassignment": true,
    // if 后面必须有 {,除非是单行 if
    "curly": [
      true,
      "ignore-same-line"
    ],
    // for in 内部必须有 hasOwnProperty
    "forin": true,
    // 禁止在分支条件判断中有赋值操作
    "no-conditional-assignment": true,
    // 禁止使用 new 来生成 String, Number 或 Boolean
    "no-construct": true,
    // 禁止 super 在一个构造函数中出现两次
    "no-duplicate-super": true,
    // 禁止在 switch 语句中出现重复测试表达式的 case
    "no-duplicate-switch-case": true,
    // 禁止出现重复的变量定义或函数参数名
    "no-duplicate-variable": [
      true,
      "check-parameters"
    ],
    // 禁止使用 eval
    "no-eval": true,
    // 禁止对对象字面量进行类型断言(断言成 any 是允许的)
    "no-object-literal-type-assertion": true,
    // 禁止没必要的 return await
    "no-return-await": true,
    // 禁止在数组中出现连续的逗号,如 let foo = [,,]
    "no-sparse-arrays": true,
    // 禁止 throw 字符串,必须 throw 一个 Error 对象
    "no-string-throw": true,
    // switch 的 case 必须 return 或 break
    "no-switch-case-fall-through": true,
    // 使用实例的方法时,必须 bind 到实例上
    "no-unbound-method": [
      true,
      "ignore-static"
    ],
    // 使用 { ...foo, bar: 1 } 代替 Object.assign({}, foo, { bar: 1 })
    // 前者的类型检查更完善
    "prefer-object-spread": true,
    // parseInt 必须传入第二个参数
    "radix": true,
    // 必须使用 isNaN(foo) 而不是 foo === NaN
    "use-isnan": true,
    // 可维护性
    // 这些规则可以增加代码的可维护性
    // 禁止函数的循环复杂度超过 20,https://en.wikipedia.org/wiki/Cyclomatic_complexity
    "cyclomatic-complexity": [
      true,
      20
    ],
    // 禁止使用废弃(被标识了 @deprecated)的 API
    "deprecation": true,
    // 一个缩进必须用四个空格替代
    "indent": [
      true,
      "spaces",
      4
    ],
    //import名称排序要求按照字母从小到大排序
    "ordered-imports": false,
    // 禁止出现重复的 import
    "no-duplicate-imports": true,
    // 禁止一个文件中出现多个相同的 namespace
    "no-mergeable-namespace": true,
    // 文件类型必须时 utf-8
    "encoding": true,
    // import 语句中,关键字之间的间距必须是一个空格
    "import-spacing": true,
    // 接口可以 implement extend 和 merge
    "interface-over-type-literal": true,
    // new 后面只必须有一个空格
    "new-parens": true,
    // 类型断言必须使用 as Type,禁止使用 <Type>
    // <Type> 容易被理解为 jsx
    "no-angle-bracket-type-assertion": true,
    // 禁止连续超过三行空行
    "no-consecutive-blank-lines": [
      true,
      3
    ],
    // 禁止使用特殊空白符(比如全角空格)
    "no-irregular-whitespace": true,
    // 禁止使用 JSDoc,因为 TypeScirpt 已经包含了大部分功能
    "no-redundant-jsdoc": true,
    // 禁止使用三斜杠引入类型定义文件
    "no-reference-import": true,
    // 禁止变量定义时赋值为 undefined
    "no-unnecessary-initializer": true,
    // 小数必须以 0. 开头,禁止以 . 开头,并且不能以 0 结尾
    "number-literal-format": true,
    // 必须使用 a = {b} 而不是 a = {b: b}
    "object-literal-shorthand": true,
    // 变量申明必须每行一个,for 循环的初始条件中除外
    "one-variable-per-declaration": [
      true,
      "ignore-for-loop"
    ],
    // if 后的 { 禁止换行
    "one-line": true,
    // 必须使用单引号,jsx 中必须使用双引号
    "quotemark": [
      true,
      "single",
      "jsx-double",
      "avoid-template",
      "avoid-escape"
    ],
    // 行尾必须有分号
    "semicolon": [
      true,
      "always",
      "ignore-interfaces"
    ],
    // 函数名前必须有空格
    "space-before-function-paren": [
      true,
      "asyncArrow"
    ],
    // 括号内首尾禁止有空格
    "space-within-parens": [
      true,
      0
    ],
    // 禁止 finally 内出现 return, continue, break, throw 等
    // finally 会比 catch 先执行
    "no-unsafe-finally": true
  }
}

具体相关tslint规则:https://palantir.github.io/tslint/rules/

五、typescript语法

1. 定义类型变量

  • String
let name: string  = '张三';
  • Number
let num: number  = 123456;
  • Boolean
let isOpen: boolean = false;
  • 数组[]
let arr: number[] = [1,2,3];
let arr: Array<number> = [1, 2, 3];
  • Any - 任何类型
let arr: any = 1;

  • Void - 无任何类型
function warnUser(): void {
    console.log("This is my warning message");
}
let unusable: void = undefined;

2. 函数

传参类型

// 定义组件传参类型
interface ToastOption {
    message: string;
    position?: string;
    duration?: number;
}

let instance: any;
const Toast = (options: ToastOption) => {
    instance = new ToastInstance({
        data: options
    });
    instance.visible = true;
    instance.$mount();
    document.body.appendChild(instance.$el);
};

返回值类型

// 将数组转成对象
function formatObj(arr: number[], key: string):any {
    let obj = {};
    if (arr instanceof Array !== true || !key) return;
    for (let item of arr) {
        obj[item[key]] = item;
    }
    return obj;
}

六、vue-property-decorator使用

文档:https://github.com/kaorun343/vue-property-decorator

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容