TypeScript开发Vue
用TypeScript开发Vue——如何通过vue实例化对象访问实际ViewModel对象
背景
我个人很喜欢TypeScript也很喜欢Vue,但在两者共同使用的时候遇到一些问题。
Vue的实例化对象代理了所有实际ViewModel对象,具体可参见官方文档(
http://vuejs.org.cn/guide/instance.html#属性与方法)
Vue的属性与方法:
每个 Vue 实例都会代理其 data 对象里所有的属性
实际上vue实例不仅仅是代理了data属性,还代理了methods属性、computed属性等,可以通过这篇文档 看到。那么怎么在TypeScript里面通过vue实例访问data属性和methods属性里面的变量是最大问题,否则就没办法使用TS的最大的作用——强类型检查。
如下图可以看到:
虽然实际上vm.xxcanghaiFn是可用的,但是过不了TypeScript的编辑检查,提示不在'xxcanghaiFn'不在'Vue'类型中。
因为类型'Vue'中肯定只有内部方法,自然会报错,虽然我们可以通过<any>
语法强制使语法检查失效,如下代码:
var vm: any = new Vue({//vm变量增加any声明
el: "#app",
data: {
xxcanghaiData: "xxcanghai"
},
methods: {
xxcanghaiFn: function () { }
}
});
vm.xxcanghaiFn//无编译器报错
虽然没有编译器报错,但同时也无法再使用TS提供的智能补全,强类型检查等功能。这就跟直接写js没有任何区别了。
解决方案
- 将data属性,以及methods等需要合并进vue类型的对象分开写
- 利用TypeScript的
typeof
和declare
关键字将类型合并声明。 - 最后new Vue时强制用
<any>
声明并赋值。
如下代码:
//核心声明,利用typeof将data和methods属性合并进Vue类型
declare var VM: typeof vmData & typeof vmMethods & vuejs.Vue;
var vmData = {
xxcanghaiData: "xxcanghai"
};
var vmMethods = {
xxcanghaiFn: () => { }
}
var vm: typeof VM = <any>new Vue({
el: "#app",
data: vmData,
methods: <any>vmMethods
});
效果如下,既可以实现识别Vue内置函数及属性:
也能实现识别我们自定义的data属性和methods属性中的值:
关于Vue中的计算属性类型
Vue中有一种特殊的ViewModel的属性——计算属性。
计算属性在使用ts的强类型的时候就会出错,代码如下:
declare var VM: vuejs.Vue & typeof vmComputed;
var vmComputed = {
/**
* 字符串计算属性
*/
xxcanghaiCom: function () {
return "xxcanghaiCom";
}
}
var vm: typeof VM = <any>new Vue({
el: "#app",
computed: <any>vmComputed
});
计算属会被ts的类型系统识别为一个函数,而出现函数相关的方法,此时调用字符串方法自然会报错。如图:

虽然计算属性实际上确实是一个函数,但是我们希望能够把计算属性拿来当一个字符串变量来使用。
TypeScript的强制类型声明语法
这里可以使用ts的强制类型声明语法 <TYPE>
,来把指定类型强制声明为其他类型,如下:
var a;
(<string>a).charAt(0);//合法
(<number>a).toFixed();//合法
强制类型声明的局限性
但是此语法也有局限性,即只能强制声明那些未知类型的变量,不能强制声明已知类型的变量,如下:
var a = 0;
(<string>a);//报错 Neither type 'number' nor type 'string' is assignable to the other.
因为变量a已经可以被类型推断出为number
类型了,遂不能再强制声明为string
类型。
计算属性类型的解决方案
解决方案为 利用any
类型中转来实现强制类型声明转换。
在TypeScript中的any
类型的规则为:
1、任何类型都可以被转换为
any
类型。
2、any
类型可以转换为任何类型。
所以先将计算属性的函数,或是getter,setter的Object声明为any
类型,再声明为你想实际使用的变量类型。如下:
declare var VM: vuejs.Vue & typeof vmComputed;
var vmComputed = {
/**
* 字符串计算属性
*/
xxcanghaiCom: <string>(<any>function () {
return "xxcanghaiCom";
}),
/**
* getter和setter形式的字符串计算属性
*/
xxcanghaiGetSet: <string>(<any>{
get: function () {
return vm.xxcanghaiCom;
},
set: function (newVal: string) {
vm.xxcanghaiCom = newVal;
}
})
}
var vm: typeof VM = <any>new Vue({
el: "#app",
computed: <any>vmComputed
});
效果如下图,虽然xxcanghaiGetSet
是object,但此处可以按照我们想要的string
类型来使用。
后记
本文比较初级,因为刚刚开始接触Vue,因为之前用过Angular和Avalon,所以上手起来还算舒服,之前用Angular的时候就因为用TypeScript写非常难受,遂打算好好研究下TypeScript与Vue的协同工作的问题。
写的比较匆忙,vue也还没有完全了解,遂文中有不对的地方欢迎指正。:-)
如果您认为本文对得起您所阅读他所花的时间,欢迎点击右下角推荐。您的支持是我继续写作最大的动力,谢谢
作者:小小沧海
TypeScript开发Vue的更多相关文章
- 用TypeScript开发Vue——如何通过vue实例化对象访问实际ViewModel对象
用TypeScript开发Vue--如何通过vue实例化对象访问实际ViewModel对象 背景 我个人很喜欢TypeScript也很喜欢Vue,但在两者共同使用的时候遇到一个问题. Vue的实例化对 ...
- 使用 typescript 开发 Vue
基础配置: 1. 准备一个使用 vue-cli 生成的项目 2. 使用 npm 一建安装基础配置 npm i -S @types/node typescript vue-class-component ...
- Vue使用Typescript开发编译时提示“ERROR in ./src/main.ts Module build failed: TypeError: Cannot read property 'afterCompile' of undefined”的解决方法
使用Typescript开发Vue,一切准备就绪.但npm start 时,提示“ ERROR in ./src/main.tsModule build failed: TypeError: Cann ...
- TypeScript编写Vue项目结构解析
使用TypeScript编写Vue项目也已经有了一段时间,笔者在刚刚使用TypeScript时候也是很茫然,不知道从何下手,感觉使用TypeScript写项目感觉很累赘并不像JavaScript那么灵 ...
- 001——Typescript 介绍 、Typescript 安 装、Typescript 开发工具
一. Typescript 介绍 1. TypeScript 是由微软开发的一款开源的编程语言. 4. TypeScript 是 Javascript 的超级,遵循最新的 ES6.Es5 规范.Typ ...
- 使用 VS Code 搭建 TypeScript 开发环境
使用 VS Code 搭建 TypeScript 开发环境 TypeScript 是 JavaScript 的超集,TypeScript 只是增强了 JavaScript 而非改变了 JavaScri ...
- 搜狗高级架构师帮你系统掌握TypeScript开发
JavaScript 是一门动态弱类型语言,对变量的类型非常宽容,而且不会在这些变量和它们的调用者之间建立结构化的契约. Angular 已经使用 TypeScript 重构了代码,另一大前端框架 V ...
- 如何用TypeScript开发微信小程序
微信小程序来了!这个号称干掉传统app的玩意儿虽然目前处于内测阶段,不过目前在应用号的官方文档里已经放出了没有内测号也能使用的模拟器了. 工具和文档可以参考官方文档:https://mp.weixin ...
- 使用TypeScript开发
学习过一段时间CoffeeScript,然后再学习TypeScript,最后还是决定使用TypeScript开发. CofeeScript主要是给js添加一些语法糖,编写代码要快捷的多,少量的代码开发 ...
随机推荐
- MySQL binlog_rows_query_log_events
当binlog_format=statement的时候进制日志只记录的是SQL语句,当binlog_fromat=row的时候记录的是event,如果想要在row模式的情况下 也记录SQL语句:bin ...
- Javascript quiz
作为一个勤劳的corder,在大年三十的前一天还留守在公司的最前线.百无聊赖中看到一套关于js的测试题,测试过后发现有些题还是有很大的意义,至少能够让我门对js基础有所重视.本人将每道题的考察点总结了 ...
- 疯狂delphi - 朱建强 (一些小例子很实用,也是我所关心的几个问题)
疯狂delphi - 朱建强 (一些小例子很实用,也是我所关心的几个问题) Android实例-获取安卓手机WIFI信息(XE8+小米2)http://www.cnblogs.com/FKdelphi ...
- 【转】ubuntu14.04 trusty的源
原文网址:http://blog.chinaunix.net/uid-15041-id-4821715.html 一.编辑更新源文件:/etc/apt/sources.list二.更新源索引文件:ap ...
- 利用linux信号机制调试段错误(Segment fault)
在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...
- cf442B Andrey and Problem
B. Andrey and Problem time limit per test 2 seconds memory limit per test 256 megabytes input standa ...
- poj3667---Hotel 线段树区间合并,区间更新
题意:有N个房间,M次操作.有两种操作(1)"1 a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住.(2)"2 b len",把起点为b ...
- spring简单入门示例
1 控制反转IOC\依赖注入DI,因为翻译的不同,因此有两个名字. 控制反转意思就是说,当我们调用一个方法或者类时,不再有我们主动去创建这个类的对象,控制权交给别人(spring). 依赖 ...
- js原型和原型链个人理解(我的理解)
<script> //普通对象与函数对象,js万物皆是对象 //自带的 function a1() { function f1() {} var f2=function () {} var ...
- java基础 二分查找算法
/* * 折半查找法: * 思路: * 定义三个变量记录查找范围中最大.最小和中间的索引值,每次都是使用中间索引值与要查找的目标进行对比,如果不符合,那么就不停缩小查找范围 * */ ...