vue2+typescript 项目、相关配置 「爱情、让人受尽委屈。」 2022-12-16 13:26 170阅读 0赞 ### 1、新建项目并引入typescripe相关的loader、依赖包 ### **1.1新建项目** vue init webpack 项目名称 **1.2 添加 typescript 以及 ts-loader** cnpm install typescript ts-loader --save **1.3 添加运行依赖包** cnpm install vue-class-component vue-property-decorator --save ### 2、配置webpack 、添加配置、文件引入的改动 ### **2.1 打开`webpack.base.conf.js`文件,进行以下改动** * 修改入口文件`main.js`为`main.ts` * `extensions`配置出增加 .ts 和 .tsx 后缀 * 添加ts-loader entry: { // 修改入口文件格式 app: './src/main.ts' } // 修改extension增加.ts 和 .tsx后缀 extensions: ['.js','.ts','.tsx', '.vue', '.json'], // 添加ts-loader rules:[ { test:/\.tsx?$/, loader:"ts-loader", exclude:/node_modules/, options:{ appendTsSuffixTo:[/\.vue$/] } } ] **2.2 修改js文件为ts文件** > 找到入口文件`main.js`======》`main.ts` > main.ts中 将`import App from "./App"`改为 `import App from "./App.vue"` **注意**,原来import的vue文件以后都必须加上.vue后缀 **2.3 在根目录下添加tsconfig.json并配置** > ts-loader会检索tsconfig.json文件,根据内部配置的规则来解析.ts文件 { "include": [ "./src/**/*" ], "exclude": [ "node_modules" ], "compilerOptions": { "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "strict": true, "allowJs": true, "module": "es2015", "target": "es5", "moduleResolution": "node", "isolatedModules": true, "lib": [ "dom", "es5", "es2015.promise" ], "sourceMap": true, "pretty": true } } **2.4 在src 目录下创建文件 vue-shim.d.ts** > 由于typescript默认并不支持.vue文件,所以在vue项目中引入的时候,需要创建一个文件 > 告诉typescript --------.vue后缀的文件交给vue来处理 declare module "*.vue" { import Vue from "vue"; export default Vue; } ### 3、修改hello.vue用typescript写法实现 ### template和style部分不做改动,主要修改script部分。大致如下 <template> <div> <h3>{ { msg}}</h3> <p>{ { computedMsg}}</p> </div> </template> <script lang="ts"> import Vue from "vue"; import Component from "vue-class-component"; @Component export default class App extends Vue{ // 定义data msg:string="欢迎来到王者荣耀" // 定义computed get computedMsg(){ return this.msg+"computed"; } mounted(){ this.hello(); } // 定义method hello(){ console.log("你好啊,白白"); } } </script> 这样,一个最最最最基本的 typescript的配置和最简单的写法就完成了 现在就可以运行 npm run dev,启动项目了 ### 4、运行时遇到的问题 ### 命令行执行`npm run dev`是报错如下: ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ppYW5nTGl0dGxlQmFp_size_16_color_FFFFFF_t_70_pic_center] 网上查了下解决方法:将package.json中 ts-loader的版本改为3.5 。从新 cnpm install ,然后再次npm run dev ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ppYW5nTGl0dGxlQmFp_size_16_color_FFFFFF_t_70_pic_center 1] 出现了这个报错,,,,,,意思是说将`./app`的引用改为`./App.vue` 忙着改配置把整个给漏掉了。。。。 改完之后,再次 npm run dev,一切正常 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ppYW5nTGl0dGxlQmFp_size_16_color_FFFFFF_t_70_pic_center 2] ### 5、typescript写法 ### 当vue+typescript之后,之前的data/computed/component/props/watch 等等等等的写法都和之前有所不同。 参考地址:[vue-property-decorator][] [vue-class-component][] **5.1 data 的定义** import { Component} from "vue-property-decorator"; @Component; export default class Index extends Vue{ msg:string="pang pang"; flag:boolean=false; list:number[]=[1,2,3,4]; } **5.2 computed 计算属性的定义** > get后面跟上计算属性名称即可 。 在模板中直接`{ {计算属性名}}`这样使用 import { Component} from "vue-property-decorator"; @Component; export default class Index extends Vue{ get name(){ return "这是一个计算属性" } } **5.3 组件的引用** <script type="ts"> import { Component } from "vue-property-decorator"; import Dialog from "../components/Dialog.vue"; import List Dialog from "../components/List.vue"; @Component({ components:{ Dialog } }) export default class Index extends Vue{ } </script> **5.4 子组件中接收参数** > 每个传入的参数都需要单独以`@Prop()`的方式书写 <script lang="ts"> import Vue from "vue"; import { Prop, Component } from "vue-property-decorator"; @Component export default class Dialog extends Vue { @Prop({ type: Boolean,required: true,})show!: Boolean; @Prop({ type:Array,required:false})list!:Array<Number>; @Prop({ type:Number})readonly count!:Number|String @Prop() readonly name!:Number|String } </script> **5.5 watch** > `@Watch()`下面紧跟的那个函数,就是当前watch监控的字段的回调函数,和这个回调函数的名字无关。 只要紧跟在`@Watch()`后面,watch的值改变下面的函数就会触发 import { Watch} from "vue-property-decorator"; @Component; export default class Index extends Vue{ msg:string="pangpang"; show:boolean=false; @Watch("msg") onMsgChange(val:string,val2:string){ //...... } @Watch("show",{ deep:true,immediate:true}) onShow(val:boolean,val2:boolean){ //...... } } **5.6 emit事件的写法** > 使用了typescript之后,子组件中使用 this.$emit() 的写法也要改了 <button @click="clickBtn">点我啊</button> <script type="ts"> import { Component,Emit} from "vue-property-decorator"; @Component; export default class Dialog extends Vue{ @Emit("closeDialog") clickBtn(){ return "点击了一下按钮"; } } </script> 事件的接收 Index.vue .....// closeDialog(msg){ console.log(msg); } 这么写了一下,报错了。。。msg隐式称为any类型了。。。。。 意思是应该给msg指定一个类型,, ![在这里插入图片描述][2020102117171931.png_pic_center] 这样写 closeDialog(msg:string){ console.log(msg); } ### 6、vuex的写法 ### 安装依赖 `cnpm install vuex-class` 在`tsconfig.json`中添加配置 { "compilerOptions": { // 启用 vue-class-component 及 vuex-class 需要开启此选项 "experimentalDecorators": true, // 启用 vuex-class 需要开启此选项 "strictFunctionTypes": false } } ### 7、遇到的一些其他问题 ### 路由异步加载。当在vue route部分通过下面的方式引入组件时报错 component:()=>import("@/pages/Tab.vue"); ![在这里插入图片描述][20201021181501969.png_pic_center] 解决方法:修改tsconfig.json 修改moule字段,为 提示字段中的其中一个。。。。 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ppYW5nTGl0dGxlQmFp_size_16_color_FFFFFF_t_70_pic_center]: /images/20221123/27058356ed1e4464b724513da699fd88.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ppYW5nTGl0dGxlQmFp_size_16_color_FFFFFF_t_70_pic_center 1]: /images/20221123/0a3a3a30a92b4d85855867aa3681d6ef.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0ppYW5nTGl0dGxlQmFp_size_16_color_FFFFFF_t_70_pic_center 2]: /images/20221123/5cb205c1d7424c9bbff2cac031bfdd5d.png [vue-property-decorator]: https://github.com/kaorun343/vue-property-decorator [vue-class-component]: https://github.com/vuejs/vue-class-component [2020102117171931.png_pic_center]: /images/20221123/f395ed5e40884c7fb39b45ec29ef529d.png [20201021181501969.png_pic_center]: /images/20221123/8edf346becf341a58232e1e47c037981.png
还没有评论,来说两句吧...