博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用TypeScript开发Vue——如何通过vue实例化对象访问实际ViewModel对象
阅读量:4658 次
发布时间:2019-06-09

本文共 2926 字,大约阅读时间需要 9 分钟。

用TypeScript开发Vue——如何通过vue实例化对象访问实际ViewModel对象

背景

我个人很喜欢TypeScript也很喜欢Vue,但在两者共同使用的时候遇到一个问题。

Vue的实例化对象代理了所有实际ViewModel对象,具体可参见(

Vue的属性与方法:

每个 Vue 实例都会代理其 data 对象里所有的属性

实际上vue实例不仅仅是代理了data属性,还代理了methods属性、computed属性等,可以通过 看到。那么怎么在TypeScript里面通过vue实例访问data属性和methods属性里面的变量是最大问题,否则就没办法使用TS的最大的作用——强类型检查。

如下图可以看到:

746158-20160810173910934-1445615870.jpg

虽然实际上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没有任何区别了。

解决方案

  1. 将data属性,以及methods等需要合并进vue类型的对象分开写
  2. 利用TypeScript的typeofdeclare关键字将类型合并声明。
  3. 最后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 = 
new Vue({ el: "#app", data: vmData, methods:
vmMethods});

效果如下,既可以实现识别Vue内置函数及属性:

746158-20160810173910934-388929101.jpg

也能实现识别我们自定义的data属性和methods属性中的值:

746158-20160810173910918-773278404.jpg

关于Vue中的计算属性类型

Vue有有一种特殊的ViewModel的属性——

计算属性在使用ts的强类型的时候就会出错,代码如下:

declare var VM: vuejs.Vue & typeof vmComputed;var vmComputed = {    /**     * 字符串计算属性     */    xxcanghaiCom: function () {        return "xxcanghaiCom";    }}var vm: typeof VM = 
new Vue({ el: "#app", computed:
vmComputed});

计算属会被ts的类型系统识别为一个函数,而出现函数相关的方法,此时调用字符串方法自然会报错。如图:

746158-20160810173911309-1497143274.jpg

虽然计算属性实际上确实是一个函数,但是我们希望能够把计算属性拿来当一个字符串变量来使用。

TypeScript的强制类型声明语法

这里可以使用ts的强制类型声明语法 <TYPE>,来把指定类型强制声明为其他类型,如下:

var a;(
a).charAt(0);//合法(
a).toFixed();//合法

强制类型声明的局限性

但是此语法也有局限性,即只能强制声明那些未知类型的变量,不能强制声明已知类型的变量,如下:

var a = 0;(
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: 
(
function () { return "xxcanghaiCom"; }), /** * getter和setter形式的字符串计算属性 */ xxcanghaiGetSet:
(
{ get: function () { return vm.xxcanghaiCom; }, set: function (newVal: string) { vm.xxcanghaiCom = newVal; } })}var vm: typeof VM =
new Vue({ el: "#app", computed:
vmComputed});

效果如下图,虽然xxcanghaiGetSet是object,但此处可以按照我们想要的string类型来使用。

746158-20160810173910934-278733916.jpg

后记

本文比较初级,因为刚刚开始接触Vue,因为之前用过Angular和Avalon,所以上手起来还算舒服,之前用Angular的时候就因为用TypeScript写非常难受,遂打算好好研究下TypeScript与Vue的协同工作的问题。

写的比较匆忙,vue也还没有完全了解,遂文中有不对的地方欢迎指正。:-)

转载于:https://www.cnblogs.com/xxcanghai/p/5757729.html

你可能感兴趣的文章
【Linux学习四】Linux下Vim命令操作
查看>>
2016 京东校招研发算法题 9.6
查看>>
python学习目录
查看>>
关于always块内for循环的执行方式
查看>>
字符串,列表
查看>>
maven的相关命令
查看>>
原型、作用域、闭包的完整解释
查看>>
Solidworks如何导入和使用模板文件
查看>>
使用命令行 Subversion 访问项目源文件(SVN)
查看>>
Lua学习系列(四)
查看>>
Docker - CentOS 安装 Docker 和 Docker-Compose
查看>>
JVM常用参数
查看>>
开源协议
查看>>
第一个HTML文档
查看>>
一道面试题作为blog的开头
查看>>
Django Admin 本质
查看>>
搭建 MobileNet-SSD 开发环境并使用 VOC 数据集训练 TensorFlow 模型
查看>>
macd综合版
查看>>
二分法查找数据
查看>>
.post
查看>>