Vue + TypeScript + Element 项目实践(简洁时尚博客网站)及踩坑记(下)

简介: Vue + TypeScript + Element 项目实践(简洁时尚博客网站)及踩坑记(下)

8. 注意点


  • 关于 页面


对于 关于 的页面,其实是一篇文章来的,根据文章类型 type 来决定的,数据库里面 type 为 3

的文章,只能有一篇就是 博主介绍 ;达到了想什么时候修改内容都可以。


所以当 当前路由 === '/about' 时就是请求类型为 博主介绍 的文章。


type: 3,  // 文章类型: 1:普通文章;2:是博主简历;3 :是博主简介;


  • 移动端适配


移动端使用 rem 单位适配。


// 屏幕适配( window.screen.width / 移动端设计稿宽 * 100)也即是 (window.screen.width / 750 * 100)  ——*100 为了方便计算。即 font-size 值是手机 deviceWidth 与设计稿比值的 100 倍
document.getElementsByTagName('html')[0].style.fontSize = window.screen.width / 7.5 + 'px';


如上:通过查询屏幕宽度,动态的设置 html 的 font-size 值,移动端的设计稿大多以宽为 750 px 来设置的。


比如在设计图上一个 150 * 250 的盒子(单位 px):


原本在 css 中的写法:


width: 150px;
heigth: 250px;


通过上述换算后,在 css 中对应的 rem 值只需要写:


width: 1.5rem; // 150 / 100 rem
heigth: 2.5rem; // 250 / 100 rem


如果你的移动端的设计稿是以宽为 1080 px 来设置的话,就用 window.screen.width / 10.8 吧。


9. 踩坑记


  • 1. 让 vue 识别全局方法/变量


  1. 我们经常在 main.ts 中给 vue.prototype 挂载实例或者内容,以方便在组件里面使用。


import service from "./utils/https";
import urls from "./utils/urls";
Vue.prototype.$https = service; // 其他页面在使用 axios 的时候直接  this.$http 就可以了
Vue.prototype.$urls = urls; // 其他页面在使用 urls 的时候直接  this.$urls 就可以了


然而当你在组件中直接 this.$http 或者 this.$urls 时会报错的,那是因为 $http 和 $urls 属性,并没有在 vue 实例中声明。


  1. 再比如使用 Element-uI 的 meesage。


import { Message } from "element-ui";
Vue.prototype.$message = Message;


之前用法如下图:


this.$message({
    message: '恭喜你,这是一条成功消息',
    type: 'success'
  })


然而还是会报错的。


再比如 监听路由的变化:


import { Vue, Watch } from "vue-property-decorator";
import Component from "vue-class-component";
import { Route } from "vue-router";
@Component
export default class App extends Vue {
  @Watch("$route")
  routeChange(val: Route, oldVal: Route) {
      //  do something
  }
}


只是这样写的话,监听 $route 还是会报错的。


想要以上三种做法都正常执行,就还要补充如下内容:


在 src 下的 shims-vue.d.ts 中加入要挂载的内容。 表示 vue 里面的 this 下有这些东西。


import VueRouter, { Route } from "vue-router";
declare module "vue/types/vue" {
  interface Vue {
    $router: VueRouter; // 这表示this下有这个东西
    $route: Route;
    $https: any; // 不知道类型就定为 any 吧(偷懒)
    $urls: any;
    $Message: any;
  }
}


  • 2. 引入的模块要声明


比如 在组件里面使用 window.document 或者 document.querySelector 的时候会报错的,npm run build 不给通过。


再比如:按需引用 element 的组件与动画组件:


import { Button } from "element-ui";
import CollapseTransition from "element-ui/lib/transitions/collapse-transition";


npm run serve 时可以执行,但是在 npm run build 的时候,会直接报错的,因为没有声明。


正确做法:


我在 src 下新建一个文件 shime-global.d.ts ,加入内容如下:


// 声明全局的 window ,不然使用 window.XX 时会报错
declare var window: Window;
declare var document: Document;
declare module "element-ui/lib/transitions/collapse-transition";
declare module "element-ui";


当然,这个文件你加在其他地方也可以,起其他名字都 OK。


但是即使配置了以上方法之后,有些地方使用 document.XXX ,比如 document.title 的时候,npm run build 还是通过不了,所以只能这样了:


<script lang="ts">
// 在用到 document.XXX  的文件中声明一下即可
declare var document: any;
// 此处省略 XXXX 多的代码
</script>


  • 3. this 的类型检查


比如之前的 事件的节流(throttle)与防抖(debounce)方法:


export function throttle(fn: Function, delay: number) {
  return function() {
    // 保留调用时的 this 上下文
    let context = this;
}


function 里面的 this 在 npm run serve 时会报错的,因为 tyescript 检测到它不是在类(class)里面。


正确做法:


在根目录的 tsconfig.json 里面加上 "noImplicitThis": false ,忽略 this 的类型检查。


// 忽略 this 的类型检查, Raise error on this expressions with an implied any type.
"noImplicitThis": false,


  • 4. import 的 .vue 文件


import .vue 的文件的时候,要补全 .vue 的后缀,不然 npm run build 会报错的。


比如:


import Nav from "@/components/nav"; // @ is an alias to /src
import Footer from "@/components/footer"; // @ is an alias to /src


要修改为:


import Nav from "@/components/nav.vue"; // @ is an alias to /src
import Footer from "@/components/footer.vue"; // @ is an alias to /src


  • 5. 装饰器 @Component


报错。


<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
export default class LoadingCustom extends Vue {}
</script>


以下才是正确,因为这里的 Vue 是从 vue-property-decorator import 来的。


<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
@Component
export default class LoadingCustom extends Vue {}
</script>


  • 6. 路由的组件导航守卫失效


vue-class-component 官网里面的路由的导航钩子的用法是没有效果的 Adding Custom Hooks


路由的导航钩子不属于 Vue 本身,这会导致 class 组件转义到配置对象时导航钩子无效,因此如果要使用导航钩子需要在 router 的配置里声明(网上别人说的,还没实践,不确定是否可行)。


  • 7. tsconfig.json 的 strictPropertyInitialization 设为 false,不然你定义一个变量就必须给它一个初始值。
  • position: sticky;


本项目中的文章详情的目录就是用了 sticky。


.anchor {
  position: sticky;
  top: 213px;
  margin-top: 213px;
}


position:sticky 是 css 定位新增属性;可以说是相对定位 relative 和固定定位 fixed 的结合;它主要用在对 scroll 事件的监听上;简单来说,在滑动过程中,某个元素距离其父元素的距离达到 sticky 粘性定位的要求时(比如 top:100px );position:sticky 这时的效果相当于 fixed 定位,固定到适当位置。


用法像上面那样用即可,但是有使用条件:


1、父元素不能 overflow:hidden 或者 overflow:auto 属性。

2、必须指定 top、bottom、left、right 4 个值之一,否则只会处于相对定位

3、父元素的高度不能低于 sticky 元素的高度

4、sticky 元素仅在其父元素内生效


  • 8. eslint 报找不到文件和装饰器的错


App.vue 中只是写了引用文件而已,而且 webpack 和 tsconfig.josn 里面已经配置了别名了的。


import Nav from "@/components/nav.vue"; // @ is an alias to /src
import Slider from "@/components/slider.vue"; // @ is an alias to /src
import Footer from "@/components/footer.vue"; // @ is an alias to /src
import ArrowUp from "@/components/arrowUp.vue"; // @ is an alias to /src
import { isMobileOrPc } from "@/utils/utils";


但是,还是会报如下的错:


微信图片_20220513223712.png


只是代码不影响文件的打包,而且本地与生产环境的代码也正常,没报错而已。

这个 eslint 的检测目前还没找到相关的配置可以把这些错误去掉。


  • 9. 路由模式修改为 history


因为文章详情页面有目录,点击目录时定位定相应的内容,但是这个目录定位内容是根据锚点来做的,如果路由模式为 hash 模式的话,本来文章详情页面的路由就是 #articleDetail 了,再点击目录的话(比如 #title2 ),会在 #articleDetail 后面再加上 #title2,一刷新会找不到这个页面的。


10. Build Setup


# clone
git clone https://github.com/biaochenxuying/blog-vue-typescript.git


# cd
cd  blog-vue-typescript


# install dependencies
npm install


# Compiles and hot-reloads for development
npm run serve


# Compiles and minifies for production
npm run build


### Run your tests
npm run test


### Lints and fixes files
npm run lint


### Run your unit tests
npm run test:unit


  • Customize configuration


See Configuration Reference.


如果要看有后台数据完整的效果,是要和后台项目 blog-node 一起运行才行的,不然接口请求会失败。


虽然引入了 mock 了,但是还没有时间做模拟数据,想看具体效果,请稳步到我的网站上查看 https://biaochenxuying.cn


11. 项目地址与系列相关文章


基于 Vue + TypeScript + Element 的 blog-vue-typescript 前台展示: https://github.com/biaochenxuying/blog-vue-typescript


基于 react + node + express + ant + mongodb 的博客前台,这个是笔者之前做的,效果和这个类似,地址如下:


blog-react 前台展示: https://github.com/biaochenxuying/blog-react

相关文章
|
15天前
|
JSON 数据可视化 数据库
vue3+threejs+koa可视化项目——实现登录注册(第三步)
vue3+threejs+koa可视化项目——实现登录注册(第三步)
40 5
|
1天前
|
资源调度 JavaScript 前端开发
vue 项目运行过程中出现错误的问题解决
vue 项目运行过程中出现错误的问题解决
|
2天前
|
JavaScript
vue项目切换页面白屏的解决方案
vue项目切换页面白屏的解决方案
5 0
|
2天前
|
XML JavaScript 前端开发
Vue3 项目中怎么使用 jsx——易懂
Vue3 项目中怎么使用 jsx——易懂
5 0
|
3天前
|
缓存 JavaScript API
一些常见的Vue项目性能优化策略
Vue项目性能优化包括代码分割、懒加载以减少初次加载时间;利用计算属性和侦听器处理复杂逻辑;优化v-for,使用key属性;减少DOM操作;借助Vue Devtools分析性能;图片优化如使用WebP格式和懒加载;异步加载组件;精简第三方库和插件;考虑服务端渲染或预渲染;以及优化网络请求,如合并请求和利用缓存。实际应用中,需根据项目需求选择合适策略。
12 2
|
11天前
|
监控 JavaScript 前端开发
【JavaScript与TypeScript技术专栏】TypeScript在JavaScript项目中的渐进式采用
【4月更文挑战第30天】TypeScript是JavaScript的超集,引入静态类型、接口等特性,提升代码安全性和可读性。在JavaScript项目中采用TypeScript可享受类型安全、社区支持及优秀工具集成等优势。渐进式采用策略包括评估项目现状、逐步引入新旧模块、编写类型定义文件、配置编译选项和编写测试用例,以提高项目质量和效率。
|
11天前
|
传感器 JavaScript 前端开发
【TypeScript技术专栏】TypeScript在大型项目中的实践与挑战
【4月更文挑战第30天】TypeScript在大型前端项目中日益流行,以其类型系统和ES6+支持提升代码安全与维护性。然而,采用 TypeScript 面临学习曲线、构建时间增加及类型推断挑战。通过最佳实践和成熟工具链(如 tsc、tslint 和 Visual Studio Code)可克服这些问题。案例如Angular、Basecamp和Slack已成功应用TypeScript。掌握TypeScript对提升开发者技能和市场竞争力至关重要。
|
11天前
|
JavaScript 前端开发 开发工具
【TypeScript 技术专栏】使用 TypeScript 重构 JavaScript 项目
【4月更文挑战第30天】TypeScript 在前端开发中日益流行,因其静态类型检查、增强代码可读性和更好的工具支持。本文讨论如何用 TypeScript 重构 JavaScript 项目,包括评估项目、安装 TypeScript 工具、逐步添加类型注解、处理兼容性问题以及解决重构中遇到的问题。重构后,代码质量、团队协作和可维护性均得到提升。通过实例分析,文章为 TypeScript 重构提供指导,助力构建更可靠的前端应用。
|
15天前
|
JSON 数据可视化 前端开发
vue3+threejs+koa可视化项目——模型文件上传(第四步)
vue3+threejs+koa可视化项目——模型文件上传(第四步)
17 7
|
18天前
|
JavaScript 编译器
TypeScript中类型守卫:缩小类型范围的艺术
【4月更文挑战第23天】TypeScript中的类型守卫是缩小类型范围的关键技术,它帮助我们在运行时确保值的精确类型,提升代码健壮性和可读性。类型守卫包括`typeof`(检查原始类型)、`instanceof`(检查类实例)和自定义类型守卫。通过这些方法,我们可以更好地处理联合类型、泛型和不同数据源,降低运行时错误,提高代码质量。