Vue+TS 踩坑记录与方案总结

网友投稿 363 2022-08-22

Vue+TS 踩坑记录与方案总结

Vue+TS 踩坑记录与方案总结

​​前言​​整个 vue 项目的目录结构

​​main.ts 中,提示import App from './App.vue'处,找不到 App.vue 这个模块​​​​main.ts 中,往 Vue 的原型 prototype 上挂载全局变量​​

​​全局组件注册​​​​SFC 单 vue 文件组件的基本写法和结构​​​​computed 计算属性的写法​​watch 监听器的使用

​​同一个 vue 页面中使用​​​​父子两个 vue 页面传值后使用 watch 监听​​

​​Watch 监听 store 中的数据改变​​​​vue+ts 中,使用 filter 过滤器​​​​自定义指令 过滤器【待补充】​​​​watch 监听 router 的变化​​​​main.ts 中注册路由导航守卫并在组件中使用路由钩子函数​​​​父子传值 - 子组件修改触发父组件的方法执行​​​​@Prop 默认参数​​​​中央总线注册与使用【待解决】​​​​vue + ts 中使用 vue-echarts​​​​vue + ts 中使用 Element-ui​​​​全局 scss 变量​​​​alias 别名设置​​​​请求接口的代理设置​​​​本地服务域名修改​​vue + ts 在 vscode 中的问题

前言

vue 和 TypeScript 结合的情况下,很多写法和我们平时的写法都不太一样,这里总结我项目开发过程中遇到的问题和问题的解决方案有些问题可能还没解决,欢迎各位大佬给与提点。 另外,使用本文前可以先看​​​vue 官方文档关于 typescript 的使用讲解​​

整个 vue 项目的目录结构

大体用 vue-cli 创建的项目,结构基本不变。

这里只写我后来为了解决问题改动的地方

main.ts 中,提示​​import App from './App.vue'​​处,找不到 App.vue 这个模块

解决方案: 1、将 shims-vue.d.ts 文件一分为二。 2、在 shims-vue.d.ts 文件同级目录下新建 vue.d.ts(名字不一定叫 vue,如 xxx.d.ts 也可以),然后此文件包含代码如下

// vue.d.tsdeclare module '*.vue' { import Vue from 'vue' export default Vue}

3、而原来的 shims-vue.d.ts 代码修改、新增如下:

// shims-vue.d.tsimport Vue from 'vue'import VueRouter, { Route } from 'vue-router'import { Store } from 'vuex'declare module 'vue/types/vue' {interface Vue {$router: VueRouter;$route: Route;$store: Store;// 以下是在main.ts中挂载到Vue.prototype上的变量$api: any;$mock: any;$configs: any;}}

main.ts 中,往 Vue 的原型 prototype 上挂载全局变量

1、main.ts 配置

// main.tsimport api from "./api/request";import mock from "./api/mock";import configs from "./utils/config";Vue.prototype.\(api = api;Vue.prototype.\)mock = mock;Vue.prototype.$configs = configs;

2、shims-vue.d.ts 配置

// shims-vue.d.ts 新增如下declare module 'vue/types/vue' { interface Vue { // ... // 以下是在main.ts中挂载到Vue.prototype上的变量 $api: any; $mock: any; $configs: any; }}

全局组件注册

注册

// main.tsimport Page from "@/components/page.vue";import AllComponent from "@/common/AllComponent.vue";Vue.component("Page", Page);Vue.component("all-component", AllComponent);

使用

写法一:写法二:

SFC 单 vue 文件组件的基本写法和结构

一個简陋的 demo,展示 ts 下的 vue 文件中,对于相关功能的使用,重点关注``里的代码

computed 计算属性的写法

// 计算属性get computedKey() { return this.selfKey1.length}

watch 监听器的使用

同一个 vue 页面中使用

import { Component, Vue, Prop, Watch } from 'vue-property-decorator'@Watch('boxHeight')getboxHeight(val) { // get+上边括号里的名字// xxx}

父子两个 vue 页面传值后使用 watch 监听

子组件监听从父组件传过来的值 1、父组件用属性传值【前提是父组件引入子组件、注册并调用了】

2、子组件要使用的工具引入工作

import { Component, Vue, Prop, Watch } from "vue-property-decorator";

3、子组件 Prop 接受

export default class ZiZuJian extends Vue { @Prop() private oneKey: object}

4、子组件 Watch 监听

@Watch('oneKey')getoneKey(newVal,oldVal) { // 监听成功后要做 log(newVal) this.myfunction(newVal)}

5、父组件(内部)改动值,会被子组件监听

export default class FuZuJian extends Vue { oneKeyObj = {} ... mounted(){ $.ajax().then(()=>{ // 适时情况下改动props传递的值,就会被子组件监听到改变 oneKeyObj = { name : '测试' } oneKeyObj.age = 18 }) }}

Watch 监听 store 中的数据改变

主要思路是计算属性获取 state 里的数据,watch 再监听计算属性

import { Component, Vue, Prop, Watch } from 'vue-property-decorator' // 引入Watchget stateSomeKey() { // 计算属性 // 监听state下的stateSomeKey对象中的keyName属性,return返回该值 return this['$store'].state.stateSomeKey.keyName}@Watch('stateSomeKey') // 与上边计算属性同名getstateSomeKey(val) { // get+上边括号里的名字 // 监听到变化后,执行对应的内容 this.myFunction() ...}

其中,第七行,监听器那里也可以這麽写

@Watch('stateSomeKey') // 与上边计算属性同名watchMenuState(val) { // 这里可以这么写:或用watch+上边括号里的名字也可以(虽然不太确定为什么,只是代码这么写成功了) // 下同 // ...}

vue+ts 中,使用 filter 过滤器

定义:(在@Component 里边,写 filters,注意 s 单词)

使用:同之前,正常使用:

{{showValue | filterValue}}

自定义指令 过滤器【待补充】

// 待补充

watch 监听 router 的变化

1、shims-vue.d.ts 的设置

// shims-vue.d.tsimport Vue from 'vue'import VueRouter, {Route} from 'vue-router';declare module 'vue/types/vue' {interface Vue {$router: VueRouter; // 这表示this下有这个东西$route: Route;}}

2、main.ts 的设置

// main.tsimport { Component } from "vue-class-component";Vue.config.productionTip = false;Component.registerHooks([ "beforeRouteEnter", //进入路由之前 "beforeRouteLeave", //离开路由之前 "beforeRouteUpdate"]);

3、需要监听路由钩子的 SCF 组件:

监听路由的第二种写法 (如果只是想更新视图的话可以考虑监听路由)

@Watch('$route')routeWatch() { this.loadData();}

main.ts 中注册路由导航守卫并在组件中使用路由钩子函数

基本同上 1、shims-vue.d.ts 的设置

// shims-vue.d.tsimport Vue from 'vue'import VueRouter, {Route} from 'vue-router';declare module 'vue/types/vue' {interface Vue {$router: VueRouter; // 这表示this下有这个东西$route: Route;}}

2、main.ts 的设置

// main.tsimport { Component } from "vue-class-component";Component.registerHooks([ "beforeRouteEnter", //进入路由之前 "beforeRouteLeave", //离开路由之前 "beforeRouteUpdate"]);

3、需要监听路由钩子的 SCF 组件:

父子传值 - 子组件修改触发父组件的方法执行

父组件内部: 1、调用子组件、并绑定传值:

准备好一会会被子组件触发的函数:

FuQinZiJiYong(){ console.log('我是父亲内部待被触发的方法')}

子组件 ZiZuJian 内部在需要触发的地方执行$emit

export default class Menu extends Vue { // 在需要触发的地方,执行如下代码 this.$emit('chuanDiGuoQu', '')}

最后还有另一种网友总结很麻烦的写法:​​参见地址​​

@Prop 默认参数

第一种:github 找到的 demo 这样。如下代码中​​hideHeader​​就是由默认参数的父组件传过来的属性

export default class ComponentName extends Vue { @Prop({ type: Boolean, required: false, default: false // 默认属性的默认值 }) private hideHeader!: boolean | undefined}

第二种:vue 原生的写法,并写到了@component 构造器中就好了: 如果不传值此函数默认就是 true,传 false 就是 false 了。并且能严格判断只能传 Boolean 类型。挺好。

@Component({ props: { hideHeader: { type: Boolean, required: false, default: false // 默认属性的默认值 } }})

中央总线注册与使用【待解决】

// 待解决

vue + ts 中使用 vue-echarts

安装

npm i -S vue-echarts echarts

main.ts 中引入并注册

// main.ts// 引用import ECharts from "vue-echarts";// 用到的模块要单独引用import "echarts/lib/chart/line"; // 线图为例,其他图一样import "echarts/lib/component/title.js"; // 标题import "echarts/lib/component/legend"; // 图例import "echarts/lib/component/tooltip"; // 提示框import "echarts/lib/component/toolbox"; // 工具(如下载功能与按钮)// 注册Vue.component("v-chart", ECharts);

vue.config.js 中设置

// vue.config.jsmodule.exports = { // For Vue CLI 3+, add vue-echarts and resize-detector into transpileDependencies in vue.config.js like this: transpileDependencies: ["vue-echarts", "resize-detector"]};

tsconfig.json 中也要设置

// tsconfig.json{ "compilerOptions": { "types": ["webpack-env", "echarts"] }}

SFC 应用

vue + ts 中使用 Element-ui

// main.tsimport ElementUI from "element-ui";Vue.use(ElementUI);

全局 scss 变量

在 assets/styles 下新建_variable.scss 文件,用于存放 scss 变量。 然后再 vue.config.js 中设置全局变量

// vue.config.jsmodule.exports = { css: { loaderOptions: { sass: { prependData: ` @import "@/assets/styles/_variable.scss"; ` } } }};

alias 别名设置

// vue.config.jsmodule.exports = { chainWebpack: config => { // 别名配置 config.resolve.alias .set("comp", resolve("src/components")) .set("css", resolve("src/assets/styles")); // ...同上,路径核对好就行 }};

jsconfig.json 配置。注意这里的名字要和上边 set 后边的名字保持一致

// jsconfig.json{ "compilerOptions": { "paths": { "@/*": [ "src/*" // 这个本来就有 ], // 后边追加 "comp/*": [ "src/components/*" ], "css/*": [ "src/assets/styles/*" ], // ... 同上,路径核对好就行 }, }};

SCF 使用设定的别名

// main.tsimport MyError from "view/error/Error.vue";/* SCF单页中scss路径引用 */@import "css/_variable.scss";

请求接口的代理设置

vue.config.js 配置

// vue.config.jsmodule.exports = { devServer: { proxy: { "/api": { target: "// 示例ip地址,也可以填域名,需要的是后端接口地址的相同部分 changeOrigin: true, pathRewrite: { "^/api": "" } } } }};

axios 请求地址时的写法: 注意​​​/api​​一定要有,且在路径的最前边,代替相同的路径。

axios .get("/api/wo/de/di/zhi") // 前边的'/api'一定要有,它代表的就是vue.config.js中proxy.target的路径 .then(() => { // 接口成功... });

本地服务域名修改

vue.config.js 配置

// vue.config.jsmodule.exports = { devServer: { disableHostCheck: true, // 用域名代替localhost,禁用主机检查 host: "haha.com" // 另外端口也可以在这里改,只不过我写到了package.json总,见下边 }};

package.json dev 命令的配置

{ "scripts": { "dev": "npm run serve", "serve": "vue-cli-service serve --port 80 --open", # 端口设置为80,--open运行完毕后自动打开地址 }}

本地 host 配置

127.0.0.1 haha.com # 这里注意和vue.config.js中的host的值对应

此时,​​npm run dev​​​成功后,浏览器跑项目输入地址​​+ ts 在 vscode 中的问题

1、扩展商店安装插件 - Path Intellisense

2、配置代码(vscode setting.json 中设置)

"path-intellisense.mappings": { "@": "\${workspaceRoot}/src"}

3、在 package.json 统计目录下创建 jsconfig.json 文件,并填入下边代码

// jsconfig.json{ "compilerOptions": { "paths": { "@/*": ["src/*"] } }}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:nginx,tomcat,apache三者分别用来做什么,有何区别(nginx,tomcat,apache 都是什么?)
下一篇:2022年最新Python大数据之Python基础【五】
相关文章

 发表评论

暂时没有评论,来抢沙发吧~