一、前言
前段时间学习了ts,于是用脚手架搭了个vue3.0+ts的项目,引入详细步骤及语法校验报错解决办法,整理下遇到的问题以及解决办法,分享给大家。
二、使用
1. 引入ts
Q:
在vue项目中编写tsx函数式组件提示报错。在没有引入ts的项目中,写tsx语法提示报错。无法使用 JSX,除非提供了 “–jsx” 标志。ts(17004)

A:
- 先检查是否安装ts,cmd输入 tsc -v, 显示了版本号即安装了ts;未安装则执行 npm install -g typescript,全局安装ts;
- 下载依赖包 yarn add typescript @vue/cli-plugin-typescript;
- 添加tsconfig.json配置文件 。在项目目录下控制台输入tsc --init,该目录下生成tsconfig.json文件,内容替换成以下:
| { |
| "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/main.js"], |
| "exclude": ["node_modules"], |
| "compilerOptions": { |
| "jsx": "preserve", |
| "noImplicitAny": false, |
| "allowJs": true, |
| "target": "es2016", |
| "module": "commonjs", |
| "baseUrl": "./", |
| "paths": { |
| "@/*": ["./src/*"] |
| }, |
| "types": ["webpack-env"], |
| "esModuleInterop": true, |
| "forceConsistentCasingInFileNames": true, |
| "strict": true, |
| "skipLibCheck": true |
| }, |
| } |
复制
- jsconfig.json 文件添加 “jsx”: “preserve” 配置项。
R: 问题解决视图

2 main.js 修改成 main.ts
Q: 控制台报错 Can’t resolve ‘./src/main.js’ in ‘F:\code\st\Vue\v3_ts’

A: 停止运行后重新运行npm run serve 即可
R: 运行成功

3. 修改app.vue 后缀为 .tsx, 修改文件内容
| import { defineComponent } from 'vue' |
| export default defineComponent({ |
| setup() { |
| return () => ( |
| <router-view /> |
| ) |
| } |
| }) |
复制
4. 组件引入less
复制
| import "./index.less" |
| export default (props, ctx) => { |
| return () => ( |
| <span>123</span> |
| ) |
| } |
复制
5. 组件引入图片
使用import导入的方式引入,代码如下:

Q:报错找不到模块“./img/right.png”或其相应的类型声明。
A:在src目录下新增文件 shims.d.ts 文件,内容如下:
| declare module '*.vue' { |
| import { ComponentOptions } from 'vue' |
| const componentOptions: ComponentOptions |
| export default componentOptions |
| } |
| |
| declare module '*.less'; |
| declare module '*.png'; |
| declare module '*.json'; |
复制
三、报错类型及解决办法
-
Q:eslint 校验报错。
A: vue.config.js 中添加 lintOnSave:false 配置项,重新运行即可。

-
Q: 引入 less 报错。

A:未下载less依赖包,yarn add less less-loader即可。
-
Q:使用navigator.getUserMedia 提示报错 类型“Navigator”上不存在属性“getUserMedia”;

A:在src目录下 shims.d.ts 文件中添加如下内容即可。
| interface Navigator { |
| getUserMedia( |
| constraints: MediaStreamConstraints, |
| successCallback: NavigatorUserMediaSuccessCallback, |
| errorCallback: NavigatorUserMediaErrorCallback |
| ): Promise<MediaStream>; |
| } |
| declare const navigator: Navigator; |
复制
- Q:使用dom获取页面元素,修改属性值时报错。不能将类型“HTMLElement | null”分配给类型“HTMLVideoElement”。不能将类型“null”分配给类型“HTMLVideoElement”。

A:使用断言,把获取到的dom元素设置成 HTMLVideoElement 类型,代码如下:
| videoEle = document.getElementById("video") as HTMLVideoElement; |
| videoEle.srcObject = stream; |
| videoEle.onloadedmetadata = function (e) { |
| videoEle.play(); |
| }; |
复制
暂时遇到了这些,后续遇到其他语法报错的问题再更新。
- Q: 父组件传子组件非必传参数,在子组件中使用报错。类型“string | undefined”的参数不能赋给类型“string”的参数。
不能将类型“undefined”分配给类型“string”。

A: 使用断言,设置成对应类型,如
| let placeholder = ref<string>(props?.placeholder as string) |
复制
- Q: 引入第三方js,报错 找不到名称“XLSX”。

A:在src目录下 shims.d.ts 文件中添加如下内容即可。
复制
- Q 使用父组件传入的属性报错,property) s: string | undefined,对象可能为“未定义”。ts(2532)

A: 使用 let str = props.s as string; 变量接收属性值后断言成对应类型的数据类型
| import { defineComponent } from "vue"; |
| import VP from "./components/poker" |
| interface Props { |
| s?: string |
| } |
| export default defineComponent({ |
| props: { |
| s: { |
| type: String |
| } |
| }, |
| setup(props: Props, ctx) { |
| let str = props.s as string; |
| return () => ( |
| <> |
| { |
| str.split("").map(v => { |
| return (<VP></VP>) |
| }) |
| } |
| </> |
| ) |
| } |
| }) |
复制