<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[doubi6的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/doubi6</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; doubi6]]></copyright><item><title><![CDATA[koa 运用 joi 实现 接口一致性检]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/121148344</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/121148344</guid><author>doubi6</author><pubDate>Thu, 04 Nov 2021 18:20:55 +0800</pubDate><description><![CDATA[import Koa from 'koa';
import Joi from 'joi';
import Router from '@koa/router';
import validateSchemaJoi from './middlewares/schema.js';

const app = new Koa();
const router = new Router();

const loginSchema = Joi.object({
  a: Joi.string()
      .min(3)
]]></description><category></category></item><item><title><![CDATA[数据交换之中介者模式]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/121139495</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/121139495</guid><author>doubi6</author><pubDate>Thu, 04 Nov 2021 11:50:38 +0800</pubDate><description><![CDATA[export default class DataMediator {
  constructor() {
    this.store = new Map();
  }

  notify(sender, event, data = undefined) {
    let res;
    if (sender &amp;&amp; event) {
      switch (event) {
        case 'get':
          res = this.get(sender);
]]></description><category></category></item><item><title><![CDATA[对象类型深层次属性的获取并且能够自定义空状态的返回值]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/121139195</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/121139195</guid><author>doubi6</author><pubDate>Thu, 04 Nov 2021 11:37:21 +0800</pubDate><description><![CDATA[function switchEmpty(caseValue) {
  let resValue;
  switch (caseValue) {
    case 'undefined':
      resValue = undefined;
      break;

    case 'null':
      resValue = null;
      break;

    case 'number':
      resValue = 0;
      break;

    case 'ob]]></description><category></category></item><item><title><![CDATA[vue 中引用类型数据 watch 监听失效 问题 解决方案]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/121139092</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/121139092</guid><author>doubi6</author><pubDate>Thu, 04 Nov 2021 11:33:38 +0800</pubDate><description><![CDATA[&lt;template&gt;
 &lt;div&gt;
   &lt;VueDeepWatch :objectValue="objectValue" :arrayValue="arrayValue" /&gt;
 &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import VueDeepWatch from '@/components/vueDeepWatch.vue'

export default {
  data () {
    return {
]]></description><category></category></item><item><title><![CDATA[js 中 null 与undefined 的区别总结]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/121137381</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/121137381</guid><author>doubi6</author><pubDate>Thu, 04 Nov 2021 10:39:20 +0800</pubDate><description><![CDATA[null 是对象， 是 JavaScript 保留关键字。
null是一个表示"无"的对象，转为数值时为0；undefined是一个表示"无"的原始值，转为数值时为NaN
null表示"没有对象"，即该处不应该有值。
null的用法是：

（1） 作为函数的参数，表示该函数的参数不是对象。 （2） 作为对象原型链的终点。

undefined表示"缺少值"，就是此处应该有一个值，但是还没有定义。
undefined是全局对象（window）的一个特殊属性。
undefine用法是：

（1）变量被声明了，但]]></description><category></category></item><item><title><![CDATA[从模板编译到虚拟dom]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/119250099</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/119250099</guid><author>doubi6</author><pubDate>Fri, 30 Jul 2021 16:07:46 +0800</pubDate><description><![CDATA[将html字符串转换为AST(parseHtmlToAst.js)
const unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/;
const attribute = /^\s*([^\s"'&lt;&gt;\/=]]></description><category></category></item><item><title><![CDATA[excel.js实践（2021-6-25）]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/118223803</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/118223803</guid><author>doubi6</author><pubDate>Fri, 25 Jun 2021 16:32:00 +0800</pubDate><description><![CDATA[import * as ExcelJs from 'exceljs/dist/exceljs';

export function jsonToExcel(data) {
  const tableName = "表名称";
  const borderStyle = {
    top: { style: 'thin' },
    left: { style: 'thin' },
    bottom: { style: 'thin' },
    right: { style: 'thin' }
  ]]></description><category></category></item><item><title><![CDATA[字符串特殊字符加反斜杠（2021-5-26）]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/117298739</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/117298739</guid><author>doubi6</author><pubDate>Wed, 26 May 2021 17:31:35 +0800</pubDate><description><![CDATA[stripscript(s) {
      const str = "[`~!@#$^&amp;*()=|{}':;',\\[\\].&lt;&gt;/?~！@#￥……&amp;*（）;—|{}【】‘；：”“'。，、？]";
      const pattern = new RegExp(str);
      let rs = '';
      Array.from(s).forEach((char) =&gt; {
        rs += char.replace(pattern, `\\${]]></description><category></category></item><item><title><![CDATA[基于vuex 的全局组件通信(2021-5-25)]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/117253013</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/117253013</guid><author>doubi6</author><pubDate>Tue, 25 May 2021 11:56:13 +0800</pubDate><description><![CDATA[store/index.js
import Vue from "vue";
import Vuex from "vuex";
import testModule from "./modules/test";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    user: {
      name: "",
      other: undefined
    },
    test: {
      testInfo: ""
   ]]></description><category></category></item><item><title><![CDATA[vuetify上传图片组件封装(2021-5-24)]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/117252997</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/117252997</guid><author>doubi6</author><pubDate>Tue, 25 May 2021 11:55:14 +0800</pubDate><description><![CDATA[&lt;template&gt;
  &lt;div&gt;
    &lt;div class="d-flex flex-wrap "&gt;
      &lt;div v-for="(item, key) in imgList" :key="key" class="ma-2"&gt;
        &lt;v-sheet color="white" elevation="1" width="200" :height="showAdd ? 240 : 200"&gt;
          &lt;v-]]></description><category></category></item><item><title><![CDATA[node  express 使用  Sequelize 操作数据库(2021-5-23)]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/117201667</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/117201667</guid><author>doubi6</author><pubDate>Sun, 23 May 2021 22:08:01 +0800</pubDate><description><![CDATA[mysql 链接配置文件

const conf = {
  database: 'node',
  user: 'root',
  password: 'xxxxx',
  options: {
    host: 'rm-2vcnsje1qrd9c966ago.mysql.cn-chengdu.rds.aliyuncs.com',
    dialect: 'mysql',
    define: {
      charset: 'utf8mb4',
      dialectOptions: {
.]]></description><category></category></item><item><title><![CDATA[node  express使用 express-auto-routes 管理路由(2021-5-23)]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/117201651</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/117201651</guid><author>doubi6</author><pubDate>Sun, 23 May 2021 22:06:42 +0800</pubDate><description><![CDATA[----app.js
// auto-routes配置
const autoRoutes = require('express-auto-routes')(app);
autoRoutes(path.join(__dirname, './routes'));

----模型（位于route目录下）

exports.get = async function get(req, res, next) {
  // const token = req.headers['t-data']
  // console.]]></description><category></category></item><item><title><![CDATA[node  express使用 cors 实现跨域 (2021-5-23)]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/117201634</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/117201634</guid><author>doubi6</author><pubDate>Sun, 23 May 2021 22:05:30 +0800</pubDate><description><![CDATA[参考：https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
// **** 跨域 *(废弃)***
// app.all('*', function (req, res, next) {
//   res.header("Access-Control-Allow-Origin", "*");
//   res.header("Access-Control-Allow-Headers", "X-Requested-With, t-data");
//  ]]></description><category></category></item><item><title><![CDATA[2020-5-17(eventBus ----vue)]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/117069139</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/117069139</guid><author>doubi6</author><pubDate>Thu, 20 May 2021 11:35:02 +0800</pubDate><description><![CDATA[局部
1. 初始化
  --单文件初始化
  // event-bus.js
    import Vue from 'vue'
    export const EventBus = new Vue()
2. 引用（单文件）
	import { EventBus } from "{path}/event-bus.js";
3. 方法
	// 发送消息
	EventBus.$emit("aMsg", '')
    // 监听接收消息
    EventBus.$on("aMsg", (msg) =&g..]]></description><category></category></item><item><title><![CDATA[2021-5-20 (代码规范)]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/117068955</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/117068955</guid><author>doubi6</author><pubDate>Thu, 20 May 2021 11:31:18 +0800</pubDate><description><![CDATA[代码规范
VScode配置 (适用于airbnb-base)
{
  "editor.quickSuggestions": {
    //开启自动显示建议
    "other": true,
    "comments": true,
    "strings": true
  },
  // vscode默认启用了根据文件类型自动设置tabsize的选项
  "editor.detectIndentation": false,
  // 重新设定tabsize，一个tab=2个空格
  "editor]]></description><category></category></item><item><title><![CDATA[2021-5-13]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/116760498</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/116760498</guid><author>doubi6</author><pubDate>Thu, 13 May 2021 18:21:18 +0800</pubDate><description><![CDATA[js引用对象深度复制
 /**
  * alias: 传入的引用对象
  * return: 深度复制后的引用对象
 */

function aliasObjDeepCopy(alias = undefined) {
      if (Array.isArray(alias)) {
        return [...alias];
      }
      if (alias.constructor === Object) {
        return JSON.parse(JSON.stri]]></description><category></category></item><item><title><![CDATA[按钮原子化操作数据刷新方法]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/116663273</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/116663273</guid><author>doubi6</author><pubDate>Tue, 11 May 2021 17:29:54 +0800</pubDate><description><![CDATA[/**
 * @param {array} arr  被改变的数组
 * @param {object} item  对象数据项
 * @param {array} paramName 用于筛选的具有唯一标识的参数名称
 * @param {*} param 用于筛选的具有唯一标识的参数
 * @param {String} type 可供操作的类型，有 "add","up","del"
 * @returns {array} 重构后的数据  
 */

const refreshData = functi]]></description><category></category></item><item><title><![CDATA[ubuntu 云服务器 部署node express 持续化集成docker镜像且开放外网访问 -2021-5-2]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/116354436</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/116354436</guid><author>doubi6</author><pubDate>Sun, 02 May 2021 16:06:14 +0800</pubDate><description><![CDATA[使用expresss创建后台框架
npm install express --save   

npm install -g express-generator 

express my-backed

-----配置外网访问-----
项目目录/bin/www/文件:
server.listen(port);
改为：
server.listen(port, '0.0.0.0');



将代码放入gitee(github)


持续集成（以下3个文件相互耦合）


docker 镜像构筑文件 node..]]></description><category></category></item><item><title><![CDATA[2021-4-28 -深层对象（数组）值获取]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/116206306</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/116206306</guid><author>doubi6</author><pubDate>Fri, 30 Apr 2021 16:13:55 +0800</pubDate><description><![CDATA[深层对象（数组）值获取
function getDeepDataFromArrOrObj(data, directArr = []) {
  if (directArr.length === 0) {
    return data;
  }
  const name = directArr.shift();
  if (!data[name]) {
    return name + "子项不存在";
  }
  if (Array.isArray(data[name]) || data[name].co]]></description><category></category></item><item><title><![CDATA[2021-4-30 -ES6]]></title><link>https://blog.youkuaiyun.com/doubi6/article/details/116302465</link><guid>https://blog.youkuaiyun.com/doubi6/article/details/116302465</guid><author>doubi6</author><pubDate>Fri, 30 Apr 2021 16:12:19 +0800</pubDate><description><![CDATA[对象
----prototype对象
Object.setPrototypeOf(object, prototype) 设置一个对象的prototype（原型）对象
Object.getPrototypeOf(obj) 用于读取一个对象的prototype对象

----获取该属性的描述对象
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
--enumerable属性，称为”可枚举性“，如果该属性为false，就表示某些]]></description><category></category></item></channel></rss>