时间:2021-05-25
前言
这段时间使用 ts 和 vue 做了一个项目,项目从 0 开始搭建,在建设和优化的同时,实现了很多自己的想法,有那么一两个组件可能在我本人看来有意义,所以从头回顾一下当初的想法,同样也可以做到一个记录的作用。如果还没有使用过 ts 的同学可以通过使用 Vue Cli3 + TypeScript + Vuex + Jest 构建 todoList 这边文章开始你的 ts 之旅,后续代码也是在 todoList 的结构上改进的
vue 路由中的懒加载
你真的用好了路由的懒加载吗?
在 2.x 的文档中、cli 的初始化项目中都会默认生成一个路由文件,大致如下:
通过路由懒加载的组件会在 webpack 打包之后生成名为 about 的 dist/js/about.39d4f7ae.js 文件。
但是在 react 中,react-loadable 可以使路由在懒加载之前先加载一个其他的组件(一般是 loading )过度这个加载的过程。
A higher order component for loading components with promises.
其实这也就是 react 的高阶组件 (HOC),那么根据 HOC 的思想,我们能否在 vue 中也实现这样一个 HOC 呢?答案是 YES
让我们看一下官方的介绍:
这个 2.3+ 新增的功能,使我们的开始有了可能,我们创建一个 loadable.ts 的高阶组件,利用 render 函数生成组件并返回。
在 routes 中使用该组件
import loadable from './loadable';const routes = [ { path: '/about', name: 'about', // component: () => import( './views/About.vue') component: loadable( () => import( './views/About.vue') }]看起来貌似已经成功了,但是在这当中还存在问题。
关于 vue-router ,不可避免的会涉及到路由的钩子函数,但是在以上用法中路由钩子是失效的,why ?
路由钩子只直接生效于注册在路由上的组件。
那么通过 loadable 生成渲染的组件中 About 组件已经是一个子组件,所以拿不到路由钩子。
组件必须保证使用上的健壮性,我们换一种方案,直接返回这个组件。
我们重新更换 routes :
上述用法已经解决了路由钩子的问题,但是仍然有两点值得注意:
SVG 、Iconfont 在 vue 项目中最优雅的用法
能用 svg 的地方尽量不使用图片 笔者在使用 svg 的时候一开始是使用vue-svg-loader, 具体用法,请自行查看。
但是在写 sidebar 时,笔者想将 svg 通过配置文件的形式写入,让 sidebar 形成多层的自动渲染。
显然 vue-svg-loader 的用法不合适。我们先了解 svg 的用法,我们可以看一篇乃夫的介绍:SVG 图标简介。
SVG symbol ,Symbols let you define an SVG image once, and reuse it in multiple places.
和雪碧图原理类似,可以将多个 svg 合成一个,但是这里用 id 来语意化定位图标
// 定义<svg class="hidden"> <symbol id="rectangle-1" viewBox="0 0 20 20"> <rect x="0" y="0" width="300" height="300" fill="rgb(255,159,0)" /> </symbol> <symbol id="reactangle-2" viewBox="0 0 20 20"> <rect x="0" y="0" width="300" height="300" fill="rgb(255,159,0)" /> </symbol></svg>// 使用<svg> <use xlink:href="#rectangle-1" rel="external nofollow" href="#rectangle" rel="external nofollow" /></svg>正好有这么一个 svg 雪碧图的 webpack loader,svg-sprite-loader,下面是代码
首先根据官网修改配置:
// vue.config.js const svgRule = config.module.rule('svg'); // 清除已有的所有 loader。 // 如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。 svgRule.uses.clear(); svgRule.exclude.add(/node_modules/); // 添加要替换的 loader // svgRule.use('vue-svg-loader').loader('vue-svg-loader'); svgRule .test(/\.svg$/) .pre() .include.add(/\/src\/icons/) .end() .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }); const imagesRule = config.module.rule('images'); imagesRule.exclude.add(resolve('src/icons')); config.module.rule('images').test(/\.(png|jpe?g|gif|svg)(\?.*)?$/);创建 ICON 文件夹,然后在文件夹中创建 svgIcon.vue 组件。
<template> <svg v-show="isShow" :class="svgClass" aria-hidden="true"> <use :xlink:href="iconName" rel="external nofollow" /> </svg></template> <script lang="ts">import { Component, Vue, Prop } from 'vue-property-decorator';@Componentexport default class SvgIcon extends Vue { @Prop({ required: true }) private readonly name!: string; @Prop({ default: () => '' }) private readonly className!: string; private get isShow() { return !!this.name; } private get iconName() { return `#icon-${this.name}`; } private get svgClass() { if (this.className) { return 'svg-icon ' + this.className; } else { return 'svg-icon'; } }}</script> <style scoped>.svg-icon { width: 1em; height: 1em; fill: currentColor; overflow: hidden;}</style>在当前目录下创建 index.ts
import Vue from 'vue';import SvgIcon from './svgIcon.vue'; // svg组件// 注册到全局Vue.component('svg-icon', SvgIcon);const requireAll = (requireContext: any) => requireContext.keys().map(requireContext);const req = require.context('./svg', false, /\.svg$/);requireAll(req);在当前目录下新建 svg 文件夹,用于存放需要的 svg 静态文件。
☁ icons [1.1.0] ⚡ tree -L 2.├── index.ts├── svg│ └── loading.svg└── svgIcon.vue使用:
我们来看一下原理和值得注意的几点:
那么,我们使用 iconfont 和 svg 有什么关系呢?
iconfont 的使用方法有很多种,完全看个人喜好,但是其中一种使用方法,也是用到了 svg symbol 的原理,一般 iconfont 会默认导出这些文件。
我们关注于其中的 js 文件, 打开文件,可以看出这个 js 文件将所有的 svg 已经处理为了 svg symbol,并动态插入到了 dom 节点当中。
而 iconfont 生成的 symbolId 也符合我们 svg-icon 的 name 命名规则 所以我们在项目的入口文件中引入这个 js 之后可以直接使用。
back-to-up
首先为什么会写这个组件呢,本项目中使用的组件库是 elementUI ,而 UI 库中自带 el-backtop,但是我能说不好用吗? 或者说我太蠢了,在经过一番努力的情况下我还是没能使用成功,所以自己写了一个。
直接上代码:
使用:
custom-style 可以自行定义,返回的图标也可以自由替换。
注意,在 safari 中动画中动画表现不一致,使用 requestAnimationFrame 之后仍然不一致。希望同学们有时间可以自由发挥一下。
总结
永远抱着学习的心态去写代码,尝试多种写法,写出你最优雅的那一种。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文介绍了如何在vue中使用ts的示例代码,分享给大家,具体如下:注意:此文并不是把vue改为全部替换为ts,而是可以在原来的项目中植入ts文件,目前只是实践阶
注意:此文并不是把vue改为全部替换为ts,而是可以在原来的项目中植入ts文件,目前只是实践阶段,向ts转化过程中的过渡。ts有什么用?类型检查、直接编译到原生
分页组件在项目中经常要用到之前一直都是在网上找些jq的控件来用(逃..),最近几个项目用上vue了项目又刚好需要一个分页的功能。具体如下:文件page.vue为
vue-beauty有丰富的vue组件库,使用vue-beauty方便项目的开发,下面介绍在vue项目中引入vue-beauty。1、vue项目初始化npmin
本文将详细介绍Vue单文件组件概述在很多Vue项目中,使用Vue.component来定义全局组件,紧接着用newVue({el:'#container'})在