# TypeScript-Vue-Starter **Repository Path**: hqywork/TypeScript-Vue-Starter ## Basic Information - **Project Name**: TypeScript-Vue-Starter - **Description**: https://github.com/Microsoft/TypeScript-Vue-Starter 学习研究及翻译项目。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master-CN - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2018-04-01 - **Last Updated**: 2022-05-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TypeScript Vue Starter - TypeScript Vue 入门 This quick start guide will teach you how to get TypeScript and [Vue](https://vuejs.org) working together. This guide is flexible enough that any steps here can be used to integrate TypeScript into an existing Vue project. > [!TRANSLATION] > 这个快速入门指南将教你如何让 TypeScript 和 [Vue](https://vuejs.org) 一起工作。该指南是足够灵活的,可以使用这里讲述的步骤将 TypeScript 集成到现有的 Vue 项目中。 # Initialize your project - 初始化你的项目 Let's create a new package. > [!TRANSLATION] > 让我们创建一个新的包。 ```sh mkdir typescript-vue-tutorial cd typescript-vue-tutorial ``` Next, we'll scaffold our project in the following way: > [!TRANSLATION] > 接着,我们将以下方式作为我们项目的脚手架: ```txt typescript-vue-tutorial/ ├─ dist/ └─ src/ └─ components/ ``` TypeScript files will start out in your `src` folder, run through the TypeScript compiler, then webpack, and end up in a `bundle.js` file in `dist`. Any components that we write will go in the `src/components` folder. > [!TRANSLATION] > 从 `src` 文件夹出发,其中的 TypeScript 文件通过 TypeScript 编译器,然后 webpack 的运行,最后结束于 `dist` 中的 `bundle.js` 文件中。我们编写的任何组件都将放置于 `src/components` 文件夹。 Let's scaffold this out: > [!TRANSLATION] > 让我们把脚手架创建出来: ```shell mkdir src cd src mkdir components cd .. ``` Webpack will eventually generate the `dist` directory for us. > [!TRANSLATION] > Webpack 将最终为我们生成 `dist` 目录。 # Initialize the project - 初始化项目 Now we'll turn this folder into an npm package. > [!TRANSLATION] > 现在,我们将把这个文件夹转变成一个 NPM 包。 ```shell npm init ``` You'll be given a series of prompts. You can use the defaults except for your entry point. You can always go back and change these in the `package.json` file that's been generated for you. > [!TRANSLATION] > 你将得到一系列的提示。除了入口点外,你都可以使用默认值。你常常可以返回,并在为你生成的 `package.json` 文件中修改这些内容。 # Install our dependencies - 安装我们的依赖 Ensure TypeScript, Webpack, Vue and the necessary loaders are installed. > [!TRANSLATION] > 确保 TypeScript、Webpack、Vue 及必要的加载器都已经安装。 ```sh npm install --save-dev typescript webpack ts-loader css-loader vue vue-loader vue-template-compiler ``` Webpack is a tool that will bundle your code and optionally all of its dependencies into a single `.js` file. While you don't need to use a bundler like Webpack or Browserify, these tools will allow us to use `.vue` files which we'll cover in a bit. > [!TRANSLATION] > Webpack 是一个可以将你的代码及其所有的依赖项捆绑到一个单一 `.js` 文件的工具。虽然你不需要使用像 Webpack 或 Browerify 等捆绑器,但这些工具将允许我们使用 `.vue` 文件,我们将在后序进行介绍。 We didn't need to [add `.d.ts` files](https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html), but if we were using a package which didn't ship declaration files, we'd need to install the appropriate `@types/` package. [Read more about using definition files in our documentation](https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html). > [!TRANSLATION] > 我们不需要添加 [`.d.ts` 文件](https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html),但是如果我们使用的包不包含声明文件,那么我们需要安装适当的 `@types` 包。[更多信息请阅读我们文档中有关使用声明文件](https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html)。 # Add a TypeScript configuration file - 添加 TypeScript 配置文件 You'll want to bring your TypeScript files together - both the code you'll be writing as well as any necessary declaration files. > [!TRANSLATION] > 你将想在提供 TypeScript 文件的同时,将编写的代码和任何必须的声明文件放到一起。 To do this, you'll need to create a `tsconfig.json` which contains a list of your input files as well as all your compilation settings. Simply create a new file in your project root named `tsconfig.json` and fill it with the following contents: > [!TRANSLATION] > 为此,你将需要创建一个 `tsconfig.json`,它包含了你输入文件的列表以及你的所有编译设置。仅需在你的项目根创建一个 `tsconfig.json` 的文件,并填充下列内容: ```json { "compilerOptions": { "outDir": "./built/", "sourceMap": true, "strict": true, "noImplicitReturns": true, "module": "es2015", "moduleResolution": "node", "target": "es5" }, "include": [ "./src/**/*" ] } ``` Notice the `strict` flag is set to true. At the very least, TypeScript's `noImplicitThis` flag will need to be turned on to leverage Vue's declaration files, but `strict` gives us that and more (like `noImplicitAny` and `strictNullChecks`). We strongly recommend using TypeScript's stricter options for a better experience. > 注意 `strict` 标记被设置为 true。至少,TypeScript 的 `noImplicitThis` 标记将需要打开用来发挥 Vue 的声明文件,但是 `strict` 提供了更多(像 `noImplicitAny` 和 `strictNullChecks`)。我们强烈推荐使用 TypeScript 更严格的选项,以便获得更多的体验。 # Adding Webpack - 添加 Webpack We'll need to add a `webpack.config.js` to bundle our app. > [!TRANSLATION] > 我们将需要添加 `webpack.config.js` 来打包我们的应用程序。 ```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: { // Since sass-loader (weirdly) has SCSS as its default parse mode, we map // the "scss" and "sass" values for the lang attribute to the right configs here. // other preprocessors should work out of the box, no loader config like this necessary. // 由于 SASS 加载器(古怪的)将 SCSS 作为它默认的解析模块,所以我们为语言特性映射“scss”和“sass”值以便在这里恰当的配置。 // 其它的预处理程序应该是开箱即用的,没有像这种必要的加载器配置。 'scss': 'vue-style-loader!css-loader!sass-loader', 'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax', } // other vue-loader options go here // 其它 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 }) ]) } ``` # Add a build script - 添加生成脚本 Open up your `package.json` and add a script named `build` to run Webpack. Your `"scripts"` field should look something like this: > [!TRANSLATION] > 打开你的 `package.json`,并添加一个被命名为 `build` 的脚本来运行 Webpack。你的“scripts”域应该看起来像: ```json "scripts": { "build": "webpack", "test": "echo \"Error: no test specified\" && exit 1" }, ``` Once we add an entry point, we'll be able to build by running > [!TRANSLATION] > 一旦我们添加了一个入口点,我们就可以通过运行以下命令来生成 ```sh npm run build ``` and have builds get triggered on changes by running > [!TRANSLATION] > 并通过运行来触发生成 ```sh npm run build -- --watch ``` # Create a basic project - 创建一个基本项目 Let's create the most bare-bones Vue & TypeScript example that we can try out. First, create the file `./src/index.ts`: > [!TRANSLATION] > 让我们创建一个最简单的使用 Vue 和 TypeScript 的示例。首先,创建文件 `./src/index.ts`: ```ts // src/index.ts import Vue from "vue"; let v = new Vue({ el: "#app", template: `
Hello {{name}}!
Name:
`, data: { name: "World" } }); ``` Let's check to see if everything is wired up correctly. Create an `index.html` with the following content at your root: > [!TRANSLATION] > 让我们检查一下看看是否所有内容都连接正确。在你的根目录使用下列内容创建一个 `index.html`。 ```html
``` Now run `npm run build` and open up your `index.html` file in a browser. > [!TRANSLATION] 现在运行 `npm run build`,并在浏览器中打开你的 `index.html`。 You should see some text that says `Hello World!`. Below that, you'll see a textbox. If you change the content of the textbox, you'll notice how the text is synchronized between the two. > [!TRANSLATION] > 你应该看到一些短语,写着 `Hello World!`。接下来,你将看到一个文本框。如果你改变了文本框的内容,你将注意到文本是如果在两者之间的同步的。 Congrats! You've gotten TypeScript and Vue fully hooked up! > [!TRANSLATION] > 恭喜!你已经把 TypeScript 和 Vue 完全贯通了! # Adding a component - 添加一个组件 As you've just seen, Vue has a very simple interface for when you need to accomplish simple tasks. When our page only needed to communicate a bit of data between two elements, it took very little code. > [!TRANSLATION] > 正如你刚刚看到的,Vue 拥有一个非常简单的接口用于你需要达到的简单任务。当我们页面仅需要在两个元素间传送一点数据时,它只花费很少的代码。 For more complex tasks, Vue is flexible in that it supports breaking your application into *components*. [Components](https://vuejs.org/v2/guide/components.html) are useful for separating the concerns of how entities are displayed to the user. [Read up more on components from Vue's documentation.](https://vuejs.org/v2/guide/components.html) > [!TRANSLATION] > 对于更复杂的任务,Vue 是灵活的,因为它支持把应用程序分解为组件。[组件]((https://vuejs.org/v2/guide/components.html)有助于分享如何将实体显示给用户的关注点。[从 Vue 文档阅读更多有关组件的内容](https://vuejs.org/v2/guide/components.html) A Vue component can be declared in the following manner: > [!TRANSLATION] > 可以使用下面的方式声明一个 Vue 组件: ```ts // src/components/Hello.ts import Vue from "vue"; export default Vue.extend({ template: `
Hello {{name}}{{exclamationMarks}}
`, 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('!'); } } }); ``` This component has two buttons and some text. When rendered, it takes an initial `name` and an `initialEnthusiasm` which is the number of exclamation marks we want to display. When we hit the `+` button, it adds an exclamation mark to the end of the text. Likewise, when we hit the `-` button, it removes an exclamation mark unless we're down to just one. > [!TRANSLATION] > 该组件拥有两个按钮和一些文本。当渲染时,它初始化了 `name` 和我们想要显示感叹号个数的 `initialEnthusiasm`。当我们点击 `+` 按钮时,它添加一个感叹号到文件的后面。同样的,当我们点击 `-` 按钮时,它将移除一个感叹号除非我们仅有一个。 Our root Vue instance can consume it as follows: > [!TRANSLATION] > 在我们的根 Vue 实例中可以如下消费它: ```ts // src/index.ts import Vue from "vue"; import HelloComponent from "./components/Hello"; let v = new Vue({ el: "#app", template: `
Name:
`, data: { name: "World" }, components: { HelloComponent } }); ``` However, we'll note that it is fairly popular to use [Vue's *single file components*](https://vuejs.org/v2/guide/single-file-components.html). Let's try writing the above as an SFC. > [!TRANSLATION] > 然而,我们将注意到 [Vue 的单文件组件](https://vuejs.org/v2/guide/single-file-components.html)使用的相当流行。让我们尝试将上述以 SFC 方式改写。 # Single File Components - 单文件组件。 When using Webpack or Browserify, Vue has plugins like [vue-loader](https://github.com/vuejs/vue-loader) and [vueify](https://www.npmjs.com/package/vueify) which allow you to author your components in HTML-like files. These files, which end in a `.vue` extension, are single file components. > [!TRANSLATION] > 当使用 Webpack 或 Browserify 时,Vue 有像 [vue-loader](https://github.com/vuejs/vue-loader) 及 [vueify](https://www.npmjs.com/package/vueify) 样的插件,允许你在类 HTML 文件中创作你的组件。这些文件以 `.vue` 扩展名结尾,是单文件组件。 There are a few things that need to be put in place to use `.vue` files with TypeScript, but luckily we're already halfway there. We already installed vue-loader earlier when we got our dev dependencies. We also specified the `appendTsSuffixTo: [/\.vue$/],` option to ts-loader in our `webpack.config.js` file, which allows TypeScript to process the code extracted from a single file component. > [!TRANSLATION] > 有一些情况需要使用放置了 TypeScript 的 `.vue` 文件,但幸运的是我们已经完全一半了。当我们获取开发依赖项时已经安装了 vue-loader。我们还在 `webpack.config.js` 文件中指定了 `appendTsSuffixTo: [/\.vue$/]` 选项给 ts-loader,它允许 TypeScript 处理从单文件组件中提取的代码。 One extra thing we'll have to do is tell TypeScript what `.vue` files will look like when they're imported. We'll do this with a `vue-shims.d.ts` file: > [!TRANSLATION] > 我们将作一件额外的事情就是告诉 TypeScript `.vue` 文件将像它们被导入时一样。我们将使用 `vue-shims.d.ts` 文件作这些: ```ts // src/vue-shims.d.ts declare module "*.vue" { import Vue from "vue"; export default Vue; } ``` We don't need to import this file anywhere. It's automatically included by TypeScript, and it tells it that anything imported that ends in `.vue` has the same shape of the Vue constructor itself. > [!TRANSLATION] > 我们不需要在任何地方导入这个文件。它自动被 TypeScript 包含,并且它告诉任何以 `.vue` 结尾的被导入内容与 Vue 构造函数本身具有相同的模型。 What's left? The editing experience! One of the best features TypeScript gives us is its editor support. To leverage that within `.vue` files, we recommend using [Visual Studio Code](https://code.visualstudio.com/) with the [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) plugin for Vue. > [!TRANSLATION] > 还剩下什么?编辑体验!TypeScript 给我们的最佳特性是它的编辑器支持。要在 `.vue` 文件中利用这点,我们推荐使用带有 Vue 插件 [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) 的 [Visual Studio Code](https://code.visualstudio.com/) Now, let's write an SFC! > [!TRANSLATION] > 现在,让我们书写一个 SFC! ```html ``` and let's import it for our root instance: > [!TRANSLATION] > 让我们为根实例导入它: ```ts // src/index.ts import Vue from "vue"; import HelloComponent from "./components/Hello.vue"; let v = new Vue({ el: "#app", template: `
Name:
`, data: { name: "World" }, components: { HelloComponent } }); ``` Notice a few things about our single-file component: > [!TRANSLATION] > 有一些关于单文件组件的事情需要关注: * We had to write `