vue + TS 使用的二三事

前言

离上一篇博客又过去了差不多10天的样子,然后上次里的flag又完美打脸了,主要是最近项目比较繁忙,所以也莫得时间整理,直到今天似乎闲了一点,于是决定随缘写篇博客。那就是分享在vue项目中使用ts的一些心得,这篇文章会长期不定期更新,因为,我使用ts的两个项目都还在开发阶段~要走完一个完整的开发周期才能写一篇比较完整的踩坑文呢~

项目起手

从头配置ts项目比较困难,在这里我们可以使用vue脚手架自带的ts可选项,只要在新建项目时勾选ts,脚手架就可以自动帮我们完成相关配置,非常方便。

然后一路回车,等待几分钟,项目就好了。

这里会介绍vue中如何简单使用ts,想了解更多关于ts的知识,可以选择看看官方文档,当然,我其实挺觉得这个文档不是那么好懂,所以我推荐看这个入门,学习了更多TS的骚操作,你就可以玩的更Happy了。

下面先来讲讲一些常用功能的TS写法

组件写法

如图,组件的写法不再是导出一个对象,而是导出一个类,注意事项有两个,一个是要在类的上面使用Component装饰器装饰这个类,另一个是这个类要继承于Vue,这样就一个组件的声明就大功告成啦。接着我们来看看我们一些常用功能的写法。

数据

声明数据非常简单,你只需要使用下面的方法声明即可


export default class Parent extends Vue {
    // 声明数据
    name = "SakuraSnow";
    age = 19;
}

该代码等效于


export default {
    date() {
    	return {
           name : "SakuraSnow",
           age : 19
       }
    }
}

当然这样就体现不出ts的优势了,你可以加点别的东西,比如数据类型和权限,


export default class Parent extends Vue {
    // 声明数据
    private readonly name = "SakuraSnow";
    private readonly age = 19;
}

加上private和readonly后,这个属性就变成了私有属性,外部访问会报错,同时是只读的,想要修改它的值也会报错。(这里的报错均是指静态类型检查报错,要访问实际上还是可以访问的,要修改实际上也是可以修改的)

属性

声明会接收的属性需要使用Prop装饰器(从"vue-property-decorator"导入),可以传入一些配置项


export default class Parent extends Vue {
    // 声明会接收的属性
    @Prop({
        default() {
            return "this is some message";
        },
        required : false
    })
    message : string | undefined;
}

以上代码等效于


export default {
    props : {
        message : {
           default() {
            	return "this is some message";
	   },
           require : false
	}
    }
}

函数

直接把函数定义在类上即可


export default class Parent extends Vue {
    // 声明函数
    handleClick() {
        console.log("被点击了");
    }
}

该代码等效于


export default {
    methods : {
        handleClick() {
        	console.log("被点击了")
        }
    }
}

计算属性

计算属性需要定义成一个访问器属性来使用,这不是TS的特有语法,在ES6的类中就已经出现。


export default class Parent extends Vue {
        
    private age = 19;
    // 声明一个计算属性
    get doubleAge() {
        return this.age * 2;
    }
    set doubleAge(val) {
        this.age = val / 2;
    }
}

该代码等效于


export default {
    data() {
    	return {
    		age : 16
        }
    },
    computed : {
        doubleAge : {
           get() {
               return this.age;
           },
           set(val) {
               this.age = val / 2;
           }
        }
    }
}

Watch

Watch需要使用Watch装饰器,同样要从" vue-property-decorator "导入


export default class Parent extends Vue {
    private age = 19;
    @Watch("age", {
        immediate : true
    })
    handleAgeUpdate(newVal : number, oldVal : number) {
        console.log("age的值更新了:", newVal, oldVal);
    }
}

该代码等效于


export default {
    data() {
    	return {
    		age : 16
            }
        },
    watch : {
    	age : {
    	    handler(newVal, oldVal) {
		console.log("age的值更新了:", newVal, oldVal);
            },
            immediate : true
        }
    }
}

生命周期

直接定义方法即可


export default class Parent extends Vue {
    mounted() {
        console.log("挂载完成");
    }
}

等效于


export default {
    mounted() {
    	console.log("挂载完成");
    }
}

想了解更多写法,点击这里查看文档]

使用时的一些坑

导入图片报错

当你想引入某个本地图片时,发现ts会报个不能找到模块的错误,这是因为ts没有把图片识别成一个模块,所以需要一点声明,你可以在src下随便找个目录建个文件,后缀是.d.ts然后加上下面的代码


declare module '*.svg';
declare module '*.png';
declare module '*.jpg';
declare module '*.jpeg';
declare module '*.gif';
declare module '*.bmp';
declare module '*.tiff';

然后就不会报错了~

在vue实例上挂自定义属性时会报错

在prototype上放了个$bus用作事件总线,然后使用时就会报错

没错,还是因为没有声明,后来我去element-ui的库里找到了它的声明文件,然后复制改了一下,就解决了这个问题。

同理随便建一个d.ts文件,然后导出一个声明,在上面定义你要的属性,然后就搞定了~


import vue from "vue";
declare module 'vue/types/vue' {
    interface Vue {
        $bus : vue
    }
}

同理,如果你喜欢使用this.$http这种写法,你也可以整个这样的声明


后记

这篇文章从开写到发布,间隔一个月,其实这个月,我难得的很忙,项目每天脑壳疼,然后陷入人生的大思考,在一切告一段落后总算补完了这个博客,这个博客也会长期更新,因为项目还没完工2333,还可以记录很多东西,嘛,下次再见~

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像

Title - Artist
0:00