配置gmail以及使用nodemailer来发送邮件
前言
在自己的kb-mall商城项目中,有通过配置google cloud中的gmail api,来发送邮件,配置过程较为繁琐以及复杂,因此,记录下来,以便于查阅和浏览,👇 是已经实现的发送效果图:
过程记录
下面将对于google cloud的相关配置过程进行详细截图与记录。
1. 打开google cloud控制台访问谷歌控制台
2. 创建google api服务
3. 搜索并使用gmail服务
4. 开通gmail api服务
5. 创建凭据
6. 进入已创建的凭据页面复制这个client_id以及client_secret配置,后续备用
7. 配置权限申请以及添加用户
8. 开始配置权限发起申请打开访问
配置前面复制的客户端ID与客户端密钥,然后选择gmail Api 并点击Authorize APIs 按钮
9.代码调用
至此,已完成对google mail api服务的配置,接下来,将根据获取到的配置信息,复制到代码中进行调用!⭐ 首先,先安装这个nodemailer发送邮件的三方库
1pnpm i nodemailer
⭐ 然后,利用nodemailer.crea ...
vue中的h渲染函数运用与分析
前言
在一般情况下,我们在vue中,推荐使用template模版语法来创建组件,然后在某些场景下,我们需要使用js完全的coding能力(也就是以js函数的思维来编写组件),这个时候就可以使用渲染函数了关于渲染函数,官方的描述已经讲解得比较详细了,具体见 渲染函数 的详细说明!本文将从底层的角度来分析何为vnode、h()函数的使用方式、分析关于h函数的执行过程,以及扩展一下思维,了解关于什么是h高阶组件
vnode虚拟节点
vue提供了一个h()函数,用于创建vnode,也就是说
1const vnode = h('div', {}, [])
🤔 那么,什么是vnode?为什么要生成vnode?对于vnode应该如何使用?
👉 关于vnode的相关知识点,可以查看之前的一篇文章:vm实例如何渲染
⭐ 简而言之,vnode是一个用于描述用户界面结构的JavaScript对象
简而言之,如下图所示:👉 将一个组件渲染成vnode,然后通过对比vnode的不同,形成最终待更新界面的vnode,然后只更新需要更新的dom节点,其工作流程如下图所示:
h()函数的使用方式
用 ...
vue3中的作用域插槽以及defineSlots的应用与过程分析
前言
vue中关于组件间数据的流向一般是父组件往子组件传参,然后子组件回调父组件更新这种单向的数据流的 但是,它也存在一种机制–作用域插槽,使得我们能够在父组件中通过插槽的方式在父组件中使用到子组件中所定义的属性+方法,本文将从一个简单的函数切入,从最简单的角度来观察关于作用域插槽的执行过程!
作用域插槽的简单应用官方插槽例子
⭐ 通过这里例子我们可以发现在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据!🤔 那么这个过程是怎样子的呢?下面我们通过一个类比的函数以及实际过程分析一波
一个简单的函数调用
比如我们有 👇 两个函数以及它们的调用过程:
1234567function fun1(props: { num: number, str: string }){ function fun2(){ const obj = { num: 888, str: '我是字符串' } fun1(obj) } console.info('这是fun1的操作:num=' + number + ', str->' + str)}
💁♂ 这里我们简单定 ...
Vue3中的reactive与readonly
前言
本文主要整理关于在vue3中所提及到的所有与reactive以及readonly相关的API,通过对比每个API的作用以及使用场景,新增对vue3中相关的API的认知,主要借助于vue3官方API的阅读!
ES2015的Proxy与Reflect
在开始学习关于vue3的reactive之前,先来了解一下关于什么是Proxy以及Reflect,Proxy与Reflect都是ES6中引入的新特性,它们通常一起使用以提供更灵活和强大的对象操作能力!
Proxy
Proxy用于修改对象某些操作的默认行为,等同于在语言层面对这个默认行为做出的修改,属于一种“元编程(编程的编程)”,可以理解为在目标对象做出默认响应(如属性查找、赋值、枚举、函数调用等等)之前提供一到“拦截”动作,外界对该对象默认行为的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy原意是代理,用于表示用它来“代理”某些操作,可以简单理解为“代理器”,语法形式如下:
1const p = new Proxy(target, handler)
🤩 参数说明:
target: ...
vue3中的"ref家族"成员剖析
前言
本文主要整理关于在vue3中所提及到的所有与ref相关的API,通过对比每个API的作用以及使用场景,新增对vue3中相关的API的认知,主要借助于vue3官方API的阅读!
“ref”成员一览
参考官方所整理的关于不同场景下的“ref”,对应整理 👇 的相关属性
响应式核心:ref()
ref接收一个内部值,返回一个响应式的,可更改的ref对象,此对象只有一个指向其内部值的属性.value关于该函数的签名以及对象的类型定义如下:
123456789101112131415161718192021222324252627282930313233// packages/activity/src/ref.ts// UnwrapRefSimple类型用于标识取消包装后的简单类型export type UnwrapRef<T> = T extends ShallowRef<infer V> ? V : T extends Ref<infer V> ? UnwrapRefSimple<V> : UnwrapRefSimple<T ...
vue3提供的watchEffect提升编码效率
前言
Vue3中引入了一个新的Composition API函数:watchEffect(),用于自动观察响应式依赖,并在依赖变化时执行副作用,这个API时为了更加方便地处理数据变动响应的情况而设计的!较之前的watch相比,watchEffect更加简洁和主动,因为它不需要指定具体的数据源来观察,而是自动追踪执行过程中所访问的所有响应式状态。关于该API的用法如下:
12345678import { ref, watchEffect } from 'vue'const count = ref(0)cosnt stopWatcher = watchEffect(() => { // 当count.value变化时,这个函数将自动重新执行! console.info(count.value)})// 这个watchEffect()函数一般返回一个待停止的函数地址,因此我们可以直接通过调用该返回函数即可停止监听操作!stopWatcher()
🌟 上述提及到了关于在依赖变化时自动执行副作用,也就是响应式变量所在的函数,当响应式变化时,所在的函数将自动重新执行,然后我们也可以 ...
vue3中的effectScope解决响应式带来的副作用
前言(什么是effectScope)
effectScope是vue3引入的一个功能,它是响应式系统的一部分,可以用来在vue的composition API中管理副作用(effects),通过effectScope,我们可以更好地控制和管理副作用,特别是在构建大型的应用的使用,这能够提高代码的组织性和可维护性!😕 那么什么是副作用?👉 在vue中,副作用(effects)主要是指响应式依赖的注册过程,比如,当使用computed或者watch等“监听性质”的API时,vue内部会建立起一个响应式系统,自动跟踪相关依赖,并在依赖变化时重新执行这些副作用,以保证数据与视图的同步! 这里我将effectScope称之为一种“自动的可管理的垃圾(依赖)处理容器”
为什么要使用effectScope
在没有effectScope之前,vue实例本身应该会跟踪这些副作用,然后在组件销毁(unmounted)的时候,自动销毁这些副作用的,但是随着composition API的使用越来越广泛,应用的结构也变得越来越灵活,原有的副作用跟踪机制在某些场景下显得不够灵活和直观,或者用起来不够顺畅 ...
深入了解TypeScript中的类型操作符
前言
本文主要整理介绍关于Typescripe中对于类型的操作,从而创建出新的类型,也就是说无需从头到位来编写一类型,而是基于原始类型,借助于相关的类型操作符,以及组合其他的类型工具,来创建新的一类型!
泛型Generics
泛型是一种类型变量的概念,可以帮助我们来编写更加灵活更加通用的代码, 😕 既然是“变量”,那么在定义的时候可以通过“传参”的方式来使用,只是这个参数它是一个类型参数,通过在需要的时候,往方法、接口、类中传递类型,即可知道当前的方法、接口、类即将作用在哪种类型上!
1234567891011121314// 泛型函数function identity<Type>(arg: Type): Type{ return arg;}// 泛型接口interface GenericIdentityFn<Type> { Type: type; <Type>(arg: Type): Type}// 泛型类class GenericNumber<Type>{ zeroValue: Type; add: (x: Type, ...
pinia的使用与过程分析
前言
pinia作为全局的状态管理器,可帮助我们在vue项目中跨多个组件间进行通讯,支持vue2以及vue3,我们可通过操作state、action,就像是在一SFC文件中使用一般,本文将从pinia的使用,到源码层面来分析关于pinia的工作过程,加深对pinia的理解,以及在pinia的实现过程上学习到了什么等等!!
pinia的使用
首先在应用程序入口中将pinia引入到vue项目中123456789import { createApp } from 'vue'import { createPinia } from 'pinia'import App from './App.vue'const pinia = createPinia()const app = createApp(App)app.use(pinia)app.mount('#app')
根据业务场景,定义自己的模块store1234567891011121314 // stores/counter.jsimport { defineStore } from 'pinia'export const useCount ...
如何使用vue中的v-model指令来提升编码效率
前言
在vue中,v-model指令用于实现表单输入元素和应用程序状态之间的双向数据绑定,比如像<input>、<textarea>、<select>,使用v-model可以很方便地将表单的值绑定到vue实例的数据上,实现双向数据绑定,本文主要是通过对比在v3.4版本前后的使用对比,进而在后续的项目中大力采用这个v-model来简化纯父子组件之间的通讯机制!
vue3.4之前关于在组件中v-model的使用
自定义组件需要手动接收value属性,并通过$emit触发input事件,来更新父组件的值
12345678<template> <input :value="value" @input="$emit('input', $event.target.value)"></template><script> export default { props: ['value'] }</script>
vue3.4之后关于在组件中 v-model的使用
从vue3.4开始,推荐使用 ...
探索TypeScript辅助工具类型的应用场景与最佳实践
前言👉 TypeScript中的辅助工具类,主要是用于帮助开发者创建可维护性高的代码自动检测机制,举个例子说明以下: 在项目过程中,我们一般需要将环境定义到环境变量中,然后整体项目的编译、打包运行,都依赖于该环境变量,TypeScript中的辅助工具类就是用来基于该环境变量来创建对应的类型,从基准类型中创建新的类型!!
🌠 这边整理了关于TypeScript中所提供的辅助工具类型清单,并根据实际的应用场景进行的划分, 👇 下面将进行一一的分析与场景应用举例!
属性修饰符转换
Required<Type>
Required
用于将类型Type中的所有可选属性变为必选属性,一般接受一个有可选属性的类型,然后返回一新的类型,这个新的类型中的所有属性都是必须属性,比如有 👇 的一个例子:
12345type MyType = { foo?: string, bar?: number}type RequiredMyType = Required<MyType>
🌟 从上述的运行结果,我们可以看出RequireMyType已经是所有属性都必须传递的了!
R ...
mongodb中的query查询以及聚合管道查询
前言
在看完mongodb的官方文档之后,还是有点一头雾水,对于一些相关的查询以及聚合管道很多不能够信手拈来,而且查询文档的时候也发现难以入手,本文主要针对相关的查询选择器以及聚合管道操作进行分类筛选,让自己对mongodb所提供的操作 🈶 一定的概念,然后通过这个分类来进行查询使用,加深理解印象!
mongodb中的查询语句分类
一切以db.collections.find()方法入手,mongodb给我们抽象出来了这个统一的查询入口⚠ 在mongodb中,我们可以通过mongosh程序,通过db.collections.method不带括号的方式来查看一个方法的描述,如下图所示;🌟 通过这种方式,可以查看到该方法的定义与返回值等相关信息
在开始详细介绍这个查询过滤器分类之前,先看一下 👇 的一个分类结构图:👽 从上图可以看出,针对不同的查询筛选操作,进行了以下对应类目的分类:
比较/范围筛选
逻辑操作
属性匹配
数组匹配
地理位置运算匹配
数学运算匹配
投影相关
位运算匹配
其他匹配操作
比较/范围筛选
主要用来筛选某个字段是否满足大于、小于、相等、不等于、大于 ...
Mongodb与Mongoose关于schemaType的差异性
前言
mongodb是一个机遇分布式文件存储的开源数据库系统,使用的非关系型数据库的设计,其提供了一种高性能、高可用一集易扩展的数据库解决方案。其主要的特点有:文档导向、无模式、索引支持、复制与高可用性、自动分片、丰富的查询语言、聚合工具等特性。mongoose是一个开源的对象文档映射器(ODM)库,主要为node.js提供了一种高效的方式来管理mongodb数据库中的数据,其通过模型定义(Schema definition)、数据验证(Data validation)、查询构建(Query building)、中间件(Middleware)、插件体系(Plugins)等功能,极大的简化了使用mongodb的复杂性!schema作为mongodb与mongoose的抽象单元,提供了基础的抽象服务!
什么是schemaType?它有什么作用?
在mongodb中最基本单元是文档(doc),而文档则由一个个的字段构成,mongodb中采用schema的抽象概念来对文档进行抽象化,而schemaType则是对schema中每一个字段的属性的描述,理解了mongodb与mongoose中关于 ...
如何给你的CMS项目添加搜索服务
前言
😕 我们平时在浏览一些开源的在线文档的时候,经常会使用到这个搜索功能,方便自己快速检索到感兴趣的信息,本文将具体带一把,关于如何在自己的文章管理系统中加入此服务,先瞄一眼以下的一个集成后的效果:
是不是觉得也很好用,想要在自己的文档中使用这个吗?下面将一步一步带你进入algolia搜索的世界!!
什么是algolia
algolia 是一家提供搜索和发现解决方案的公司。他们的主要产品是 algolia search,这是一个用于网站、移动应用和其他应用程序的搜索引擎服务。algolia 的搜索引擎旨在提供快速、可定制和易于集成的搜索体验。
algolia 的搜索引擎基于分布式架构,利用了云计算和搜索算法来提供高性能的搜索服务。它支持全文搜索、模糊搜索、过滤、排序和其他高级搜索功能,使开发人员能够创建强大的搜索体验,提高用户在应用程序中找到所需信息的效率。
如何集成algolia
这里以我的hexo博客文档为例,在当前项目中集成三方库 hexo-algoliasearch,通过借助于这个库,可以快速地在我们的项目中集成这个文档搜索服务
😕 这里假定我们已经注册好了 ...
Hexo安装与配置服务升级
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
Quick StartCreate a new post1$ hexo new "My New Post"
More info: Writing
Run server1$ hexo server
More info: Server
Generate static files1$ hexo generate
More info: Generating
Deploy to remote sites1$ hexo deploy
More info: Deployment
Nuxt3.0的学习与使用
前言
之前已经学习过关于Nuxt2.0Nuxt2.0知识文档的相关知识点,也在实际的该框架下进行过对应的项目开发,现在迁移至Nuxt3.0的学习(本文简称Nuxt),并在此框架上进行对应的项目实战,在实战之前,很有必要进行关于Nuxt的使用文档简单的说明!!之前已经针对2.0版本进行一个详细的分析过了,因此本文仅针对3.0的使用特性进行一些补充说明。在开始进行该框架的介绍时,这边想先抛出几个关键词:自动导入(auto-imported)、模块集成、插件集成!!
目录与文件介绍
👇 将进行额外的目录与文件介绍,阐述关于Nuxt在使用上 🈶 什么不同之处
.nuxt
.nuxt目录将是Nuxt运行时的产物,一旦我们run这个命令的时候,将自动生成对应的资源文件。生成的文件内容如下: 从上面的截图我们可以解答这个问题:为什么在Nuxt环境中,可以免导入来直接使用全局组件以及全局API, 👉 因为自动导入的原因!!
components
该目录是放置所有的SFC组件的地方,所有的组件将会被自动注册到全局中,在实际的项目业务开发过程中,可以无需导入来直接使用!默认情况下,该目录的配 ...
如何使用tailwindcss来管理项目的样式
前言😕 大家可以看到之前我们项目(比如使用vue全家桶+某个UI库)中打包出来的结果css内容,可以发现,我们在项目中经常使用的那就那么些样式,但是打包出来的最终效果确是像 ☝ 的一样,将有关的和无关的样式都给怼进来了,搞得整个css样式表非常的大。 更 🐶 的是如果我们要做响应式的交互效果,我们基本上都得一个个媒体查询都得用起来,并维护一套套的不同的样式表,来确保在对应的屏幕上能够按照既定的目标来展示对应的效果。 还有更 🐕 的是作为开发者,还必须想好每个样式的名字,如果按照 css中的BEM命名规范 的话,还得去想好每个样式的名称。当然在实际的coding过程中还有其他比较繁琐的事情,让我们从css样式代码管理工作中释放出来!
👉 因此,tailwindcss 官网 应运而生,就是为了解决上述提及到的相关问题,以及根据更多的使用业务应用场景来管理项目中的样式!!
什么是tailwindcss?
tailwind css的工作原理就是扫描所有的HTML文件、JavaScript组件以及任何其他模版来获取其中出现的类型,生成对应的样式,然后将它们写入到静态的css文件中,也 ...
从vue2迁移到vue3的编码实战思考
前言
习惯了vue2全家桶项目的开发,突然转向vue3,如果单纯的使用选项式的模式来编写vue3的项目的话,与vue2并没有太大的差别,无非是将data从原本的data(){}函数中转移到了setup()函数中而已,但在vue3中提供了另外一种组合式编程的模式,让我们能够以函数调用的方式来编写对应的项目,下面将通过实际的项目编码方式上的对比,来进行整理两者之间的一个区别,加深对vue3项目的理解!
项目实战
👇 基于 1⃣ 开源的项目进行学习与分析:☝ 是对应的项目的源码目录,主要 🈶 api、assets、components、hooks、icons、locates、plugins、router、store、styles、utils、views,下面将一一分析每个文件夹中都代表着什么意义,以及以下都有哪些文件资源,都有各自对应的什么内容!
1、api
一般是前端项目中与业务相关的接口定义,可根据实际业务场景情况进行定义,一般是通过调用公共的axios工具类,来对外暴露业务本地化调用的接口,但是在以前我们所编写的方法中,我们一般是通过接收url+params的方式,来发起的接口 ...
vue3全家桶学习
前言
在从以前vue2项目中转向vue3的领域,据网上说好像有很大的性能以及编码速度的提升空间,感觉已经迫不及待要来接触这个领域,看看vue3是如何“征服”vue2的开发者的,它与之前使用vue2所开发出来的项目 🈶 什么区别? 🈶 什么优势???
在通读了一遍vue3的官方文档 vue3官方文档 之后,感觉编码习惯 🈶 一定的区别,虽然vue3支持“选项式(与vue2编码方式类似)”与“组合式”的编码方式,但在经过简单的练手之后发现,组合式的编码方式能够在一定程度上减少代码量,而且更多地是以函数的思维来编写代码,而且与vue3的其他框架能够无缝衔接!!
😕 但是,这边也 🈶 几个问题,结合以前所开发的项目来进行提问,并在后续的学习过程中将来分析解决这些问题:
vue3中通过import语法来引入vue3的相关API方法(比如ref),然后直接调用,在以前vue2中是直接在data函数中返回的对象中声明,其他API方法也是如此,因为在编写vue3的SFC组件的时候,这些API应该都会被直接调用,那么是否可以将这个import给去掉,然后直接来调用呢?
vue3中通 ...
验证json-web-token的koa中间件:koa-jwt
前言
JSON Web Token(以下简称JWT)是一个开放标准,它定义了一种紧凑且自包含的方式,用于作为JSON对象在各方之间安全地传输信息。此信息可以被验证和信任,因为它是数字签名的。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对来签名。简而言之,就是使用一个加密的以及base64编码组成的字符串,用于解决跨域认证问题的一个机制!
传统的用户认证流程
传统的用户认证流程一般如下:
用户想服务器端发送用户名以及密码;
服务器端认证通过后,将用户信息存储于当前会话(session)中,比如有用户信息、登录时间等等;
服务器端向用户返回一个sessionId,写入到用户的cookie中;
随后用户的每一次请求,都会通过cookie来携带上sessionId,传回给服务器,告知已认证通过,并进行认证通过许可后的资源访问;
服务器从cookie中捞到sessionId之后,认证通过后,放行继续往下执行;
😕 这里方式是拥有一定的弊端的,加入是单机的,一般没有什么太大的问题,但是如果是集群或者是跨域多服务的情况下,就需要将sessionId来进行共享, ...