• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

详解Vue 项目中的几个实用组件(ts)

vue 搞代码 4年前 (2022-01-08) 39次浏览 已收录 0个评论

这篇文章主要介绍了详解Vue 项目中的几个实用组件(ts),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

这段时间使用 ts 和 vue 做了一个项目,项目从 0 开始搭建,在建设和优化的同时,实现了很多自己的想法,有那么一两个组件可能在我本人看来有意义,所以从头回顾一下当初的想法,同样也可以做到一个记录的作用。如果还没有使用过 ts 的同学可以通过使用 Vue Cli3 + TypeScript + Vuex + Jest 构建 todoList  这边文章开始你的 ts 之旅,后续代码也是在 todoList 的结构上改进的

vue 路由中的懒加载

你真的用好了路由的懒加载吗?

在 2.x 的文档中、cli 的初始化项目中都会默认生成一个路由文件,大致如下:

 { path: '/about', name: 'about', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ './views/About.vue') } 

通过路由懒加载的组件会在 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

让我们看一下官方的介绍:

 const AsyncComponent = () => ({ // The component to load (should be a Promise) component: import('./MyComponent.vue'), // A component to use while the async component is loading loading: LoadingComponent, // A component to use if the load fails error: ErrorComponent, // Delay before showing the loading component. Default: 200ms. delay: 200, // The error component will be displayed if a timeout is // provided and exceeded. Default: Infinity. timeout: 3000 }) 

这个 2.3+ 新增的功能,使我们的开始有了可能,我们创建一个 loadable.ts 的高阶组件,利用 render 函数生成组件并返回。

 import LoadingComponent from './loading.vue'; export default (component: any) => { const asyncComponent = () => ({ component: component(), loading: LoadingComponent, delay: 200, timeout: 3000 }); return { render(h: any) { return h(asyncComponent, {}); } }; }; 

在 routes 中使用该组件

 import loadable from './loadable'; const routes = [ { path: '/about', name: 'about', // component: () => import(/* webp<strong style="color:transparent">本文来源gaodai#ma#com搞@@代~&码*网/</strong>ackChunkName: "about" */ './views/About.vue') component: loadable( () => import(/* webpackChunkName: "about" */ './views/About.vue') } ] 

看起来貌似已经成功了,但是在这当中还存在问题。

关于 vue-router ,不可避免的会涉及到路由的钩子函数,但是在以上用法中路由钩子是失效的,why ?

路由钩子只直接生效于注册在路由上的组件。

那么通过 loadable 生成渲染的组件中 About 组件已经是一个子组件,所以拿不到路由钩子。

组件必须保证使用上的健壮性,我们换一种方案,直接返回这个组件。

 const asyncComponent = importFunc => () => ({ component: importFunc(), loading: LoadingComponent, delay: 200, timeout: 3000 }); 

我们重新更换 routes :

 const routes = [ { path: '/about', name: 'about', // component: () => import(/* webpackChunkName: "about" */ './views/About.vue') component: asyncComponent( () => import(/* webpackChunkName: "about" */ './views/About.vue') } ] 

上述用法已经解决了路由钩子的问题,但是仍然有两点值得注意:

  • asyncComponent 接受的参数是一个 function , 如果直接写成  import(/* webpackChunkName: “about” */ ‘./views/About.vue’), 则 LoadingComponent 无法生效。
  • AsyncComponent 还可以添加一个 error 的组件,形成逻辑闭环。

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 雪碧图的 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 组件。

    .svg-icon { width: 1em; height: 1em; fill: currentColor; overflow: hidden; } 

在当前目录下创建 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 

使用:

 

我们来看一下原理和值得注意的几点:

  • svg-sprite-loader 处理完通过 import 的 svg 文件后将其生成类似于雪碧图的形式,也就是 symbol, 通过配置中的 .options({ symbolId: ‘icon-[name]’ });可以使用 直接使用这个 svg
  • 添加完 svg-sprite-loader 后,由于 cli 默认对 svg 有处理,所以需要 exclude 指定文件夹的 svg。
  • 使用时由于 svgIcon 组件的处理,只需要将 name 指定为文件名即可。

那么,我们使用 iconfont 和 svg 有什么关系呢?

iconfont 的使用方法有很多种,完全看个人喜好,但是其中一种使用方法,也是用到了 svg symbol  的原理,一般 iconfont 会默认导出这些文件。

 ☁ iconfont [1.1.0] ⚡ tree -L 2 . ├── iconfont.css ├── iconfont.eot ├── iconfont.js ├── iconfont.svg ├── iconfont.ttf ├── iconfont.woff └── iconfont.woff2 

我们关注于其中的 js 文件, 打开文件,可以看出这个 js 文件将所有的 svg 已经处理为了 svg symbol,并动态插入到了 dom 节点当中。

而 iconfont 生成的 symbolId 也符合我们 svg-icon 的 name 命名规则 所以我们在项目的入口文件中引入这个 js 之后可以直接使用。

back-to-up

首先为什么会写这个组件呢,本项目中使用的组件库是 elementUI ,而 UI 库中自带 el-backtop,但是我能说不好用吗? 或者说我太蠢了,在经过一番努力的情况下我还是没能使用成功,所以自己写了一个。

直接上代码:

   <div class="back-to-ceiling">    </div> .back-to-ceiling { background-color: rgb(255, 255, 255); box-shadow: 0 0 6px rgba(0, 0, 0, 0.12); background-color: '#f2f6fc'; position: fixed; right: 50px; bottom: 50px; cursor: pointer; } .back-to-ceiling:hover { background-color: #f2f6fc; } .fade-enter-active, .fade-leave-active { display: block; transition: display 0.1s; } .fade-enter, .fade-leave-to { display: none; } 

使用:

  <i class="el-icon-caret-top"></i>

custom-style 可以自行定义,返回的图标也可以自由替换。

注意,在 safari 中动画中动画表现不一致,使用 requestAnimationFrame 之后仍然不一致。希望同学们有时间可以自由发挥一下。

总结

永远抱着学习的心态去写代码,尝试多种写法,写出你最优雅的那一种。

以上就是详解Vue 项目中的几个实用组件(ts)的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:详解Vue 项目中的几个实用组件(ts)

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址