VUE+js项目改为VUE+TypeScript

VUE+js项目改为VUE+TypeScript


吐槽:不仅要学VUE,还要用TypeScript,对于一个后端,听都没听过好吗;项目都前后端分离了,连个前端工程师都懒得招!害…没得狗了

1.Vue 引入 TypeScript
引入TypeScript需要安装必要的、需要的插件:

//安装vue的官方插件
npm i vue-class-component vue-property-decorator --save

// ts-loader typescript 必须安装,其他的相信你以后也会装上的
npm i ts-loader typescript tslint tslint-loader tslint-config-standard --save-dev

具体啥意思,额也不清楚
2.修改webpack配置
在这里插入图片描述
将main.js改为main.ts;在resolve中添加‘.ts’

entry: {
    // app: './src/main.js',
    app: './src/main.ts',
  }
resolve: {
    extensions: ['.js', '.vue', '.json', '.ts'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  }

找到module.rules 添加webpack对.ts的解析

{                           // 加入对文件的ts识别         
        test: /\.ts$/,
        exclude: /node_modules/,
        enforce: 'pre',
        loader: 'tslint-loader'
      }, {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
          appendTsSuffixTo: [/\.vue$/],
        }
      }

ts-loader 会检索当前目录下的 tsconfig.json 文件,根据里面定义的规则来解析.ts文件(就跟.babelrc的作用一样)
tslint-loader 作用等同于 eslint-loader

既然上面的路径名改了,那对应的文件也要改咯。
将对应目录下的main.js改为main.ts
在这里插入图片描述
改为ts文件后,里面有些语法会报警告的,根据警告修改就好。
以下是我的:

an alias.
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import elementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import 'element-ui/lib/theme-chalk/display.css'

Vue.use(elementUI)

import axios from 'axios'
Vue.prototype.axios = axios

import qs from 'qs'
Vue.prototype.qs = qs

Vue.config.productionTip = false

/* eslint-disable no-new */
const app = new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

注意:该加‘.vue’,还有该去除‘;’号的,这些都会报出警告
在这里插入图片描述
在这里插入图片描述
3.添加tsconfig.json文件
文件地址放在根目录:
在这里插入图片描述

{
  "compilerOptions": {
    // 编译目标平台
    "target": "es5",
    // 输出目录
    "outDir": "./dist/",
    // 添加需要的解析的语法,否则TS会检测出错。
    "lib": ["es2015", "es2016", "dom"],
    // 模块的解析
    "moduleResolution": "node",
    // 指定生成哪个模块系统代码
    "module": "esnext",
    // 在表达式和声明上有隐含的any类型时报错
    "noImplicitAny": false,
    // 把 ts 文件编译成 js 文件的时候,同时生成对应的 map 文件
    "sourceMap": true,
    // 允许编译javascript文件
    "allowJs": true,
    // 指定基础目录
    "baseUrl": "./",
    // 启用装饰器
    "experimentalDecorators": true,
    // 移除注释
    "removeComments": true,
    "pretty": true,
    // 是相对于"baseUrl"进行解析
    "paths": {
      "vue": ["node_modules/vue/types"],
      "@/*": ["src/*"]
    }
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules"
  ]
}

4.添加tslint.json文件

{
  "extends": "tslint-config-standard",
  "globals": {
    "require": true
  }
}

5.让ts识别vue
由于 TypeScript 默认并不支持 *.vue 后缀的文件,所以在 vue 项目中引入的时候需要创建一个 vue-shim.d.ts 文件,放在项目项目对应使用目录下,例如 src/vue-shim.d.ts

/**
 * 告诉 TypeScript *.vue 后缀的文件可以交给 vue 模块来处理
 * 而在代码中导入 *.vue 文件的时候,需要写上 .vue 后缀。
 * 原因还是因为 TypeScript 默认只识别 *.ts 文件,不识别 *.vue 文件
 */
declare module "*.vue" {
  import Vue from 'vue'
  export default Vue
}
/**
 * 告诉 TypeScript window是个全局对象,直接可用,这样就不会在window.xx = 123时报错
 */
declare var window: any
/**
 * 引入部分第三方库/自己编写的模块的时候需要额外声明文件
 * 引入的时候,需要使用类似 import VueLazyLaod from 'vue-lazyload' 的写法
 */
declare module 'vue-lazyload'
declare module '@zz/perf/vue'
declare module 'raven-js'
declare module 'raven-js/plugins/vue'

到这里基本已经大功告成,运行项目,应该可以正常运行了
最后好事需要将vue中的js代码转成ts代码,详细的转换规则一时也说不清,我将我的贴上来
js:

<script>
    export default {
        data() {
            return {
                //添加form
                addForm: {
                    personName: '',//姓名
                    personSex: '',//性别
                    personAge: '',//年龄
                    personDate: '',//入职日期
                    personEmail: '',//邮箱
                    personPhone: '',//联系方式
                    personPlan: '',//个人规划
                    personAttr: [],//个人定位
                    province: '',//省
                    city: '',//市
                    regional: ''//区
                },
                rules: {
                    personName: [
                        { required: true, message: '请输入姓名', trigger: 'blur' },
                        { min: 2, max: 7, message: '长度在 2 到 7 个字符', trigger: 'blur' }
                    ],
                    personAge: [
                        { required: false, message: '请输入年龄', trigger: 'blur' },
                        { type: 'number', message: '请输入数字类型', trigger: ['blur','change'] }
                    ],
                    personEmail: [
                        { required: true, message: '请输入邮箱地址', trigger: 'blur' },
                        { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
                    ],
                    personPhone: [
                        { required: true, message: '请输入手机号', trigger: 'blur' },
                        { pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/, message: '请输入正确的手机号码或者座机号', }
                    ],
                },
                //时间选择
                pickerOptions1: {
                    disabledDate(time) {
                        return time.getTime() > Date.now();
                    }
                },
                //报表数据集合
                tableData: [],
                search: '',
                dialogVisible: false,
                pageSize: 5,
                currentPage: 1,
                total: 0,
                //查询form
                searchForm: {
                  personName: '',//用户姓名
                  personAttr: '',//个人定位
                  personDate: '',//入职时间
                  province: '',//省
                  city: '',//市
                  regional: ''//区
                },
                disablePage: false,
                provinces: [],//省
                citys: [],//市
                regionals: []//区
            }
        },
        methods: {
            handleSizeChange(val) {
              console.log(`每页 ${val} 条`);
              this.pageSize=val;
            },
            handleCurrentChange(val) {
                console.log(`当前页: ${val}`);
                this.currentPage=val;
                this.onSearch();
            },
            //增加页面关闭事件
            handleClose(done) {
                this.$confirm('确认关闭?')
                    .then(_ => {
                        done();
                    })
                    .catch(_ => {});
            },
            //增加页面取消事件
            cancel() {
                this.dialogVisible = false;
                this.emptyUserData();
            },
            emptyUserData(){
                this.addForm = {
                    personName: '',//姓名
                    personSex: '',//性别
                    personAge: '',//年龄
                    personDate: '',//入职日期
                    personEmail: '',//邮箱
                    personPhone: '',//联系方式
                    personPlan: '',//个人规划
                    personAttr: '',//个人定位
                    province: '',//省
                    city: '',//市
                    regional: ''//区
                }
            },
            //增加用户与服务器交互
            addPerson(addForm) {
               this.$refs[addForm].validate((valid) => {
                 if (valid) {
                   this.addPersonSubmit();
                   this.dialogVisible = false;
                 } else {
                   console.log('error submit!!');
                   return false;
                 }
               });
            },
            //form提交事件
            addPersonSubmit() {
              let postData = this.qs.stringify({
                  personName: this.addForm.personName,//姓名
                  personSex: this.addForm.personSex,//性别
                  personAge: this.addForm.personAge,//年龄
                  personDate: this.addForm.personDate,//入职日期
                  personEmail: this.addForm.personEmail,//邮箱
                  personPhone: this.addForm.personPhone,//联系方式
                  personPlan: this.addForm.personPlan,//个人规划
                  personAttr: this.addForm.personAttr.join(","),//个人定位
                  province: this.addForm.province,//省
                  city: this.addForm.city,//市
                  regional: this.addForm.regional
              });
              this.axios({
                  // headers: {
                  //     'Content-Type': 'application/json;charset=utf-8'
                  // },
                  method: 'post',
                  //http://127.0.0.1:8080
                  url:'/api/person/save',
                  data:postData
              }).then(response =>
              {
                  var code = response.data.code;
                  if(code == 200){
                    this.currentPage = 1;
                    this.$message({
                        type: 'success',
                        message: '已添加!'
                    });
                    this.onSearch();
                  }else{
                    this.$message({
                        type: 'error',
                        message: response.data.msg
                    });
                  }
              }).catch(error =>
              {
                  console.log(error);
              });

            },
            //获取所属城市
            selectCitys(cityParentNum,cityLeave) {
              //http://127.0.0.1:8080
                this.axios.get('/api/city/findList',{
                  params: {
                        cityParentNum: cityParentNum,
                        cityLeave: cityLeave,
                        }
                }).then(response =>
                {
                    console.log(response.data);
                    let data = response.data.data;
                    //判断城市等级,将对应的数据放到对应的集合,同时初始化子城市
                    if(cityLeave == '1'){
                      this.provinces = data;
                    }else if(cityLeave == '2'){
                      this.searchForm.city = '';
                      this.citys = data;
                      this.searchForm.regional = '';
                    }else{
                      this.searchForm.regional = '';
                      this.regionals = data;
                    }
                }).catch(error =>
                {
                    console.log(error);
                });
            },
            //省市区级联选中事件
            selectChanged(cityNum) {
              console.log(cityNum);
              var cityLeave = '2';
              console.log('error'+cityNum.length);
              if(cityNum.length > 4){
                cityLeave = '3';
              }
              this.selectCitys(cityNum,cityLeave);
            },
            //查询按钮
            onSearch() {
                let postData = this.qs.stringify({
                    personName: this.searchForm.personName,
                    personAttr: this.searchForm.personAttr,
                    personDate: this.searchForm.personDate,
                    province: this.searchForm.province,
                    city: this.searchForm.city,
                    regional: this.searchForm.regional,
                    pageNum: this.currentPage,
                    pageSize: this.pageSize,
                });
                console.log("postData:"+postData);
                this.axios({
                    method: 'post',
                    //http://127.0.0.1:8080
                    url: '/api/person/findList',
                    data: postData
                }).then(response =>
                {
                    console.log("person/findList:"+response);
                    this.tableData = response.data.rows;
                    this.disablePage = true;
                    this.total = response.data.total;
                }).catch(error =>
                {
                    console.log(error);
                });
            },

            //重置
            reset(searchForm) {
              this.$refs[searchForm].resetFields()
            }
        },
        created() {
            this.onSearch();
            this.selectCitys('0','1');
        },
    }
</script>

TS:

<script lang="ts">
    import Vue from 'vue'
  import Component from 'vue-class-component'
  import qs from 'qs'
  import axios from 'axios'

  @Component
  export default class HelloWorld extends Vue {

    public $refs!: {
        addForm: Element
    }

    //添加form
    addForm = {
        personName: '',//姓名
        personSex: '',//性别
        personAge: '',//年龄
        personDate: '',//入职日期
        personEmail: '',//邮箱
        personPhone: '',//联系方式
        personPlan: '',//个人规划
        personAttr: [],//个人定位
        province: '',//省
        city: '',//市
        regional: ''//区
    };
    rules = {
        personName: [
            { required: true, message: '请输入姓名', trigger: 'blur' },
            { min: 2, max: 7, message: '长度在 2 到 7 个字符', trigger: 'blur' }
        ],
        personAge: [
            { required: false, message: '请输入年龄', trigger: 'blur' },
            { type: 'number', message: '请输入数字类型', trigger: ['blur','change'] }
        ],
        personEmail: [
            { required: true, message: '请输入邮箱地址', trigger: 'blur' },
            { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
        ],
        personPhone: [
            { required: true, message: '请输入手机号', trigger: 'blur' },
            { pattern: /^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/, message: '请输入正确的手机号码或者座机号', }
        ],
    };
    //时间选择
    pickerOptions1 = {
        disabledDate(time) {
            return time.getTime() > Date.now();
        }
    };
    //报表数据集合
    tableData = []
    search = ''
    dialogVisible = false
    pageSize = 5
    currentPage = 1
    total = 0
    //查询form
    searchForm = {
      personName: '',//用户姓名
      personAttr: '',//个人定位
      personDate: '',//入职时间
      province: '',//省
      city: '',//市
      regional: ''//区
    };
    disablePage = false
    provinces = []//省
    citys = []//市
    regionals = []//区

    handleSizeChange(val: number) {
      console.log(`每页 ${val} 条`);
      this.pageSize=val;
    }
    handleCurrentChange(val: number) {
        console.log(`当前页: ${val}`);
        this.currentPage=val;
        this.onSearch();
    }
    //增加页面关闭事件
    handleClose(done) {
        this.$confirm('确认关闭?')
            .then(_ => {
                done();
            })
            .catch(_ => {});
    }
    //增加页面取消事件
    cancel() {
        this.dialogVisible = false;
        this.emptyUserData();
    }

    emptyUserData(){
        this.addForm = {
            personName: '',//姓名
            personSex: '',//性别
            personAge: '',//年龄
            personDate: '',//入职日期
            personEmail: '',//邮箱
            personPhone: '',//联系方式
            personPlan: '',//个人规划
            personAttr: [],//个人定位
            province: '',//省
            city: '',//市
            regional: ''//区
        }
    }
    //增加用户与服务器交互
    addPerson(addForm) {
       this.$refs[addForm].validate((valid) => {
         if (valid) {
           this.addPersonSubmit();
           this.dialogVisible = false;
         } else {
           console.log('error submit!!');
           return false;
         }
       });
    }
    //form提交事件
    addPersonSubmit() {
      let postData = qs.stringify({
          personName: this.addForm.personName,//姓名
          personSex: this.addForm.personSex,//性别
          personAge: this.addForm.personAge,//年龄
          personDate: this.addForm.personDate,//入职日期
          personEmail: this.addForm.personEmail,//邮箱
          personPhone: this.addForm.personPhone,//联系方式
          personPlan: this.addForm.personPlan,//个人规划
          personAttr: this.addForm.personAttr.join(","),//个人定位
          province: this.addForm.province,//省
          city: this.addForm.city,//市
          regional: this.addForm.regional
      });
      axios({
          // headers: {
          //     'Content-Type': 'application/json;charset=utf-8'
          // },
          method: 'post',
          //http://127.0.0.1:8080
          url:'/api/person/save',
          data:postData
      }).then(response =>
      {
          var code = response.data.code;
          if(code == 200){
            this.currentPage = 1;
            this.$message({
                type: 'success',
                message: '已添加!'
            });
            this.onSearch();
          }else{
            this.$message({
                type: 'error',
                message: response.data.msg
            });
          }
      }).catch(error =>
      {
          console.log(error);
      });

    }
    //获取所属城市
    selectCitys(cityParentNum:String,cityLeave:String) {
      //http://127.0.0.1:8080
        axios.get('/api/city/findList',{
          params: {
                cityParentNum: cityParentNum,
                cityLeave: cityLeave,
                }
        }).then(response =>
        {
            console.log(response.data);
            let data = response.data.data;
            //判断城市等级,将对应的数据放到对应的集合,同时初始化子城市
            if(cityLeave == '1'){
              this.provinces = data;
            }else if(cityLeave == '2'){
              this.searchForm.city = '';
              this.citys = data;
              this.searchForm.regional = '';
            }else{
              this.searchForm.regional = '';
              this.regionals = data;
            }
        }).catch(error =>
        {
            console.log(error);
        });
    }
    //省市区级联选中事件
    selectChanged(cityNum:String) {
      console.log(cityNum);
      var cityLeave = '2';
      console.log('error'+cityNum.length);
      if(cityNum.length > 4){
        cityLeave = '3';
      }
      this.selectCitys(cityNum,cityLeave);
    }
    //查询按钮
    onSearch() {
        let postData = qs.stringify({
            personName: this.searchForm.personName,
            personAttr: this.searchForm.personAttr,
            personDate: this.searchForm.personDate,
            province: this.searchForm.province,
            city: this.searchForm.city,
            regional: this.searchForm.regional,
            pageNum: this.currentPage,
            pageSize: this.pageSize,
        });
        console.log("postData:"+postData);
        axios({
            method: 'post',
            //http://127.0.0.1:8080
            url: '/api/person/findList',
            data: postData
        }).then(response =>
        {
            console.log("person/findList:"+response);
            this.tableData = response.data.rows;
            this.disablePage = true;
            this.total = response.data.total;
        }).catch(error =>
        {
            console.log(error);
        });
    }
    //重置
    reset(searchForm) {
      this.$refs[searchForm].resetFields()
    }


    created() {
        this.onSearch();
        this.selectCitys('0','1');
    }

  }

</script>

关于报错
在这里插入图片描述

Module build failed: Error: You may be using an old version of webpack; please check you’re using at least version 4

这种就是版本冲突了,强制降级就好,执行以下命令
npm install ts-loader@3

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue3 + TypeScript 是一种常用的前端开发技术组合,它结合了Vue框架的便捷性和TypeScript的类型检查能力,可以提高项目的可维护性和开发效率。下面是一些Vue3 + TypeScript项目经验的介绍: 1. 项目初始化:使用Vue CLI创建一个Vue3项目,并选择TypeScript作为项目的语言。这样可以自动生成一些基本的配置和文件结构,方便快速开始开发。 2. 类型定义:在Vue3 + TypeScript项目中,可以使用TypeScript的类型系统来定义组件的props、data、computed等属性的类型,以及事件的参数类型等。这样可以在编码过程中及早发现潜在的类型错误,提高代码的健壮性。 3. 组件开发:在Vue3 + TypeScript项目中,可以使用装饰器(decorators)来定义组件选项,例如使用@Prop来定义props属性的类型,使用@Emit来定义事件的参数类型。这样可以更清晰地描述组件的接口和行为。 4. 路由管理:在Vue3 + TypeScript项目中,可以使用Vue Router进行路由管理。通过定义路由的类型和参数类型,可以在编码过程中获得更好的类型提示和错误检查。 5. 状态管理:在Vue3 + TypeScript项目中,可以使用Vuex进行状态管理。通过定义状态的类型和操作的参数类型,可以提高代码的可读性和可维护性。 6. 第三方库的使用:在Vue3 + TypeScript项目中,可以使用第三方库,并为其编写类型声明文件,以获得更好的类型检查和代码提示。例如,可以使用axios发送HTTP请求,并为其编写类型声明文件,以确保请求参数和响应数据的类型正确。 7. 单元测试:在Vue3 + TypeScript项目中,可以使用Jest等测试框架进行单元测试。通过编写类型安全的测试用例,可以提高代码的质量和可靠性。 8. 构建和部署:在Vue3 + TypeScript项目中,可以使用Webpack等构建工具进行项目的打包和优化。通过配置合适的TypeScript编译选项和Webpack插件,可以生成高效的生产环境代码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值