Home

Awesome

TypeScript Vue 入门 translate-svg

校对 ✅

<!-- doc-templite START generated --> <!-- repo = 'Microsoft/TypeScript-Vue-Starter' --> <!-- commit = 'c243b11a6f827e780a5163999bc472c95ff5a0e0' --> <!-- time = '2018-5-24' -->
翻译的原文与日期最新更新更多
commit⏰ 2018-5-24last中文翻译
<!-- doc-templite END generated -->

贡献

欢迎 👏 勘误/校对/更新贡献 😊 具体贡献请看

生活

If help, buy me coffee —— 营养跟不上了,给我来瓶营养快线吧! 💰


目录

<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->

TypeScript Vue Starter

本快速入门指南,将教您如何让 TypeScript和Vue一起工作. 本指南非常灵活,不管你位于本指南的哪个步骤, 都可以让你把 TypeScript集成到 现有的Vue项目中.

初始化您的项目

让我们创建一个新项目包.

mkdir typescript-vue-tutorial
cd typescript-vue-tutorial

接下来,我们将通过以下架构,构建项目:

typescript-vue-tutorial/
├─ dist/
└─ src/
   └─ components/

TypeScript文件将从您的src文件夹开始,运行T ypeScript编译器,然后运行 webpack,最后dist文件夹有了个bundle.js. 我们写的任何组件都会进入src/components文件夹.

让我们来继续吧:

mkdir src
cd src
mkdir components
cd ..

Webpack最终将生成我们的dist目录.

初始化该项目

现在我们将把这个文件夹变成一个 npm包裹.

npm init

您将获得一系列提示. 除 入口点{entry point} 外,您都可以使用默认值. 您可以随时返回,并更改这些内容在package.json - 已为您生成的文件.

安装我们的依赖项

确保安装 TypeScript,Webpack,Vue和必要的加载器.

npm install --save-dev typescript webpack ts-loader css-loader vue vue-loader vue-template-compiler

Webpack 是一个将 代码和可选的所有依赖项 捆绑在单个.js文件的工具. 虽然您不需要使用像 Webpack或Browserify 这样的捆绑器,但这些工具将允许我们使用.vue文件 - 我们稍后会介绍.

我们不需要加入 .d.ts「声明文件」 文件,但如果我们使用的是 未发送声明文件 的软件包,我们需要安装相应的软件包@types/包. 了解更多 - 声明文件{官方}.

添加 TypeScript 配置文件

您需要将 TypeScript文件 放在一起 - 您要编写的代码以及任何必要的 声明文件.

要做到这一点,你需要创建一个tsconfig.json,其中包含 输入文件列表 以及 所有编译设置. 在项目根目录中创建一个名为tsconfig.json的新文件,并填写以下内容:

{
    "compilerOptions": {
        "outDir": "./built/",
        "sourceMap": true,
        "strict": true,
        "noImplicitReturns": true,
        "module": "es2015",
        "moduleResolution": "node",
        "target": "es5"
    },
    "include": [
        "./src/**/*"
    ]
}

请注意strict是设置为true. 至少,TypeScript的noImplicitThis需要打开,来影响 Vue的声明文件,但是strict给了我们更多选项1 (比如noImplicitAnystrictNullChecks) . 我们强烈建议您使用TypeScript 更 严格-strict 的模式选项以获得更好的体验.

添加 Webpack

我们需要添加一个webpack.config.js捆绑我们的应用程序.

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/index.ts',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'build.js'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            // 由于 sass-loader(很奇怪)将 SCSS 作为其默认的解析模式,
            // 我们映射
            // “scss”和“sass”语言值位于 配置的右边。
            // 其他预处理器应该开箱即用,没有像这样的加载器配置。
            'scss': 'vue-style-loader!css-loader!sass-loader',
            'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
          }
          // 其他 vue-loader 选项就在这里
        }
      },
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
          appendTsSuffixTo: [/\.vue$/],
        }
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      }
    ]
  },
  resolve: {
    extensions: ['.ts', '.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true
  },
  performance: {
    hints: false
  },
  devtool: '#eval-source-map'
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'
  // http://vue-loader.vuejs.org/en/workflow/production.html
  module.exports.plugins = (module.exports.plugins || []).concat([
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  ])
}

添加构建脚本

打开你的package.json,并添加一个build来运行Webpack. 你的"scripts"字段应该看起来像这样:

"scripts": {
    "build": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

一旦我们添加了一个入口文件,我们就可以通过运行,来构建

npm run build

并通过运行下面的,观察更改

npm run build -- --watch

创建一个基本项目

让我们创建一个最简单的 Vue和TypeScript 示例 来尝试一下. 首先,创建文件./src/index.ts:

// src/index.ts

import Vue from "vue";

let v = new Vue({
    el: "#app",
    template: `
    <div>
        <div>Hello {{name}}!</div>
        Name: <input v-model="name" type="text">
    </div>`,
    data: {
        name: "World"
    }
});

我们来检查一切<>是否正确连线. 在您的根目录中创建一个index.html,包含以下内容:

<!doctype html>
<html>
<head></head>

<body>
    <div id="app"></div>
</body>
<script src="./dist/build.js"></script>

</html>

现在运行npm run build,并在浏览器中输入,打开你的index.html文件.

你应该看到一些文字说Hello World!. 在此之下,您将看到一个文本框. 如果更改文本框的内容,您将注意到在两者之间是同步的文本.

恭喜!你已经完全搞定了 TypeScript和Vue! 

添加组件

正如您刚才所见,Vue有一个非常简单的界面,可用于完成简单任务. 当我们的页面只需要在两个元素之间传递一些数据时,它只花了很少的代码.

对于更复杂的任务,Vue非常灵活,因为它支持整顿您的应用程序变成组件. Components对于将实体如何显示给用户的问题分开是有用的. 了解更多 vue组件.

可以通过以下方式 声明Vue组件:

// src/components/Hello.ts

import Vue from "vue";

export default Vue.extend({
    template: `
        <div>
            <div>Hello {{name}}{{exclamationMarks}}</div>
            <button @click="decrement">-</button>
            <button @click="increment">+</button>
        </div>
    `,
    props: ['name', 'initialEnthusiasm'],
    data() {
        return {
            enthusiasm: this.initialEnthusiasm,
        }
    },
    methods: {
        increment() { this.enthusiasm++; },
        decrement() {
            if (this.enthusiasm > 1) {
                this.enthusiasm--;
            }
        },
    },
    computed: {
        exclamationMarks(): string {
            return Array(this.enthusiasm + 1).join('!');
        }
    }
});

该组件有 两个按钮 和 一些文本. 渲染时,它需要初始值nameinitialEnthusiasm 这是我们想要显示的感叹号的数量. 当我们击中+按钮,它在文本的末尾添加一个感叹号. 同样,当我们击中时-按钮,它会删除一个感叹号, 除非我们只是一个感叹号.

我们的 根 Vue实例 可以按 如下方式使用它:

// src/index.ts

import Vue from "vue";
import HelloComponent from "./components/Hello";

let v = new Vue({
    el: "#app",
    template: `
    <div>
        Name: <input v-model="name" type="text">
        <hello-component :name="name" :initialEnthusiasm="5" />
    </div>
    `,
    data: { name: "World" },
    components: {
        HelloComponent
    }
});

但是,我们会注意到它的使用相当普遍Vue 的单文件组件. 让我们尝试将上述内容写成SFC.

单个文件组件

使用 Webpack或Browserify 时,Vue有插件vue-loadervueify 它允许您在类似 HTML的文件 中创作组件. 这些文件以.vue扩展结尾,是单个文件组件.

这里需要搞些事情,才能使用.vue与TypeScript 的文件,但幸运的是我们已经在那里完成一半了. 我们在获得 开发依赖项-{dev dependencies}时 已经安装了 vue-loader. 我们还指定了appendTsSuffixTo: [/\.vue$/],同时我们的webpack.config.js文件中ts-loader选项,它允许 TypeScript 处理从 单个文件组件 中提取的代码.

我们要做的另一件事是告诉 TypeScript,.vue文件在导入时是什么样子滴. 我们这样做是为了vue-shims.d.ts文件:

// src/vue-shims.d.ts

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

我们不需要在任何地方导入此文件. 它被 TypeScript自动包含,并告诉它 任何 .vue导入的内容都具有与 Vue构造函数 本身相同的形状.

还剩下什么? 编辑体验! TypeScript为我们提供的最佳功能之一,是它完善的编辑器支持. 为了用好.vue文件,我们建议使用Visual Studio Code和随着Vetur的Vue插件.

现在,让我们写一个SFC!

<!-- src/components/Hello.vue -->

<template>
    <div>
        <div class="greeting">Hello {{name}}{{exclamationMarks}}</div>
        <button @click="decrement">-</button>
        <button @click="increment">+</button>
    </div>
</template>

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

export default Vue.extend({
    props: ['name', 'initialEnthusiasm'],
    data() {
        return {
            enthusiasm: this.initialEnthusiasm,
        }
    },
    methods: {
        increment() { this.enthusiasm++; },
        decrement() {
            if (this.enthusiasm > 1) {
                this.enthusiasm--;
            }
        },
    },
    computed: {
        exclamationMarks(): string {
            return Array(this.enthusiasm + 1).join('!');
        }
    }
});
</script>

<style>
.greeting {
    font-size: 20px;
}
</style>

然后让我们在 根实例 导入它:

// src/index.ts

import Vue from "vue";
import HelloComponent from "./components/Hello.vue";

let v = new Vue({
    el: "#app",
    template: `
    <div>
        Name: <input v-model="name" type="text">
        <hello-component :name="name" :initialEnthusiasm="5" />
    </div>
    `,
    data: { name: "World" },
    components: {
        HelloComponent
    }
});

请注意我们的单文件组件的一些事项:

试试运行npm run build,并打开index.html看到结果!

使用 装饰器-decorators 定义组件

组件也可以使用decorators定义. 在另外两个包, (vue-class-componentvue-property-decorator)的帮助下 ,我们的组件可以通过以下方式重写:

import { Vue, Component, Prop } from "vue-property-decorator";

@Component
export default class HelloDecorator extends Vue {
    @Prop() name!: string;
    @Prop() initialEnthusiasm!: number;

    enthusiasm = this.initialEnthusiasm;

    increment() {
        this.enthusiasm++;
    }
    decrement() {
        if (this.enthusiasm > 1) {
            this.enthusiasm--;
        }
    }

    get exclamationMarks(): string {
        return Array(this.enthusiasm + 1).join('!');
    }
}

已经不是使用Vue.extend来定义我们的组件,我们创建了一个类来扩展和装饰Vue,用于vue-class-component包的@Component装饰器 (从中重新导出 vue-property-decorator包) .

通过使用 实例变量 加 前缀@Prop() - {来自vue-property-decorator包的装饰器}来定义属性.

因为--strictPropertyInitialization选项打开,我们需要告诉TypeScript , 有关 Vue 将通过 添加一个! 来初始化我们的属性 给他们. 这告诉 TypeScript "嘿,放松,别人会给这个属性分配一个值. "

常规实例变量,例如在我们的示例中的enthusiasm,自动用于 绑定到 template 的数据,就像它们已经在 template 中定义的data字段一样. 请注意,所有变量必须设置为 除undefined以外的值 来使绑定工作.

同样,方法如increment被视为写在methods字段,并自动为 template 提供.

最后,计算-computed属性如exclamationMarks简单地写成get存取.

接下来是什么?

您可以从 Github 中 clone 这个项目来试试.

一旦你觉得你已经掌握了它,你可以试试更复杂的TodoMVC风格 应用来自TypeScript 和 Vue. 这个TodoMVC风格 的 样本 具有路由功能vue-router以便您的应用程序可以根据当前URL 显示不同的视图.

您可能还想了解一下Vuex,如果你正在寻找Redux式的状态管理的话.