实习知识点学习

ES Lint和Prettier结合使用

什么是eslint?
ESLint 是一个开源的 JavaScript 代码检查工具,它是用来进行代码的校验,检测代码中潜在的问题,比如某个变量定义了未使用、函数定义的参数重复、变量名没有按规范命名等等。
ESLint 的初衷是为了让程序员可以创建自己的检测规则。ESLint 的所有规则都被设计成可插入的。ESLint 的默认规则与其他的插件并没有什么区别,规则本身和测试可以依赖于同样的模式。为了便于人们使用,ESLint 内置了一些规则,当然,你可以在使用过程中自定义规则。
ESLint 使用 Node.js 编写,这样既可以有一个快速的运行环境的同时也便于安装。 (重点,使用eslint必须有package.json文件)
什么是Prettier?
它是代码格式化工具,用来做代码格式化,有了Prettier之后,它能去掉原始的代码风格,确保团队的代码使用统一相同的格式,修复规则可自定义。
建议:
ESLint的机制是首先在项目中去找是否有**.eslinntrc.js**文件,如果没找到,会去当前目录中去找还是没有的话,会去全局找,个人爱好把ESlint装到目录中,这样在这个目录中创建项目都会去使用你eslint这套规范。

.eslintrc.js //定义自定义规则 在rules中

module.exports = {
  root: true,
   //环境
  env: {
    node: true,
  },
  // 这里是 vue插件
  extends: ['plugin:vue/essential', 'eslint:recommended', '@vue/prettier'],
  "globals": {
  //忽略全局的变量 
    "$": true
  },
 
    parserOptions: {
      // // 检查 ES6 语法
      // parser: "babel-eslint"
    },
   // 0 代表关闭  1 代表警告  2 代表开启
  rules: {
    'no-async-promise-executor': 1, //禁止使用异步函数作为 Promise executor
    'no-await-in-loop': 1, // 禁止使用 await async
    'no-console': 1, //禁用 console
    'no-debugger': 1, //禁用 debugger
    'no-dupe-args': 2, //函数参数不能重复
    'no-regex-spaces': 2, //禁止正则表达式字面量中出现多个空格
    'default-case': 2, //switch语句最后必须有default
    'no-alert': 0, //禁止使用alert confirm prompt
    'no-array-constructor': 1, //禁止使用数组构造器
    'no-bitwise': 0, //禁止使用按位运算符
    'no-caller': 0, //禁止使用arguments.caller或arguments.callee
    'no-catch-shadow': 2, //禁止catch子句参数与外部作用域变量同名
    'no-class-assign': 0, //禁止给类赋值
    'no-cond-assign': 0, //禁止在条件表达式中使用赋值语
    'no-const-assign': 0, //禁止修改const声明的变量
    'no-constant-condition': 0, //禁止在条件中使用常量表达式 if(true) if(1)
    'no-continue': 0, //禁止使用continue
    'no-control-regex': 2, //禁止在正则表达式中使用控制字符
    'no-delete-var': 2, //不能对var声明的变量使用delete操作符
    'no-div-regex': 1, //不能使用看起来像除法的正则表达式/=foo/
    'no-dupe-keys': 2, //在创建对象字面量时不允许键重复 {a:1,a:1}
    'no-duplicate-case': 2, //switch中的case标签不能重复
    'no-else-return': 0, //如果if语句里面有return,后面不能跟else语句
    'no-empty': 2, //块语句中的内容不能为空
    'no-empty-character-class': 2, //正则表达式中的[]内容不能为空
    'no-eq-null': 1, //禁止对null使用==或!=运算符
    'no-eval': 0, //禁止使用eval
    'no-ex-assign': 2, //禁止给catch语句中的异常参数赋值
    'no-extend-native': 0, //禁止扩展native对象
    'no-extra-bind': 2, //禁止不必要的函数绑定
    'no-extra-boolean-cast': 2, //禁止不必要的bool转换
    'no-extra-parens': 2, //禁止非必要的括号
    'no-extra-semi': 2, //禁止多余的冒号
    'no-fallthrough': 1, //禁止switch穿透
    'no-floating-decimal': 2, //禁止省略浮点数中的0 .5 3.
    'no-func-assign': 2, //禁止重复的函数声明
    'no-implicit-coercion': 1, //禁止隐式转换
    'no-implied-eval': 2, //禁止使用隐式eval
    'no-inline-comments': 1, //禁止行内备注
    'no-inner-declarations': [0, 'functions'], //禁止在块语句中使用声明(变量或函数)
    'no-invalid-regexp': 2, //禁止无效的正则表达式
    'no-invalid-this': 2, //禁止无效的this,只能用在构造器,类,对象字面量
    'no-irregular-whitespace': 2, //不能有不规则的空格
    'no-iterator': 0, //禁止使用__iterator__ 属性
    'no-label-var': 2, //label名不能与var声明的变量名相同
    'no-labels': 0, //禁止标签声明
    'no-lone-blocks': 2, //禁止不必要的嵌套块
    'no-lonely-if': 1, //禁止else语句内只有if语句
    'no-loop-func': 1, //禁止在循环中使用函数(如果没有引用外部变量不形成闭包就可以)
    'no-mixed-requires': [0, false], //声明时不能混用声明类型
    'no-mixed-spaces-and-tabs': [2, false], //禁止混用tab和空格
    'linebreak-style': [0, 'windows'], //换行风格
    'no-multi-spaces': 1, //不能用多余的空格
    'no-multi-str': 2, //字符串不能用\换行
    'no-multiple-empty-lines': [1, {max: 2}], //空行最多不能超过2行
    'no-native-reassign': 0, //不能重写native对象
    'no-negated-in-lhs': 2, //in 操作符的左边不能有!
    'no-nested-ternary': 0, //禁止使用嵌套的三目运算
    'no-new': 1, //禁止在使用new构造一个实例后不赋值
    'no-new-func': 1, //禁止使用new Function
    'no-new-object': 1, //禁止使用new Object()
    'no-new-require': 1, //禁止使用new require
    'no-new-wrappers': 1, //禁止使用new创建包装实例,new String new Boolean new Number
    'no-obj-calls': 0, //不能调用内置的全局对象,比如Math() JSON()
    'no-octal': 2, //禁止使用八进制数字
    'no-octal-escape': 2, //禁止使用八进制转义序列
    'no-param-reassign': 0, //禁止给参数重新赋值
    'no-path-concat': 0, //node中不能使用__dirname或__filename做路径拼接
    'no-plusplus': 1, //禁止使用++,--
    'no-process-env': 0, //禁止使用process.env
    'no-process-exit': 0, //禁止使用process.exit()
    'no-proto': 0, //禁止使用__proto__属性
    'no-redeclare': 2, //禁止重复声明变量
    'no-restricted-modules': 0, //如果禁用了指定模块,使用就会报错
    'no-return-assign': 1, //return 语句中不能有赋值表达式
    'no-script-url': 0, //禁止使用javascript:void(0)
    'no-self-compare': 2, //不能比较自身
    'no-sequences': 0, //禁止使用逗号运算符
    'no-shadow': 2, //外部作用域中的变量不能与它所包含的作用域中的变量或参数同名
    'no-shadow-restricted-names': 2, //严格模式中规定的限制标识符不能作为声明时的变量名使用
    'no-spaced-func': 2, //函数调用时 函数名与()之间不能有空格
    'no-sparse-arrays': 2, //禁止稀疏数组, [1,,2]
    'no-sync': 0, //nodejs 禁止同步方法
    'no-ternary': 0, //禁止使用三目运算符
    'no-trailing-spaces': 1, //一行结束后面不要有空格
    'no-this-before-super': 0, //在调用super()之前不能使用this或super
    'no-throw-literal': 1, //禁止抛出字面量错误 throw "error";
    'no-undef': 1, //不能有未定义的变量
    'no-undef-init': 1, //变量初始化时不能直接给它赋值为undefined
    'no-undefined': 1, //不能使用undefined
    'no-unexpected-multiline': 2, //避免多行表达式
    'no-underscore-dangle': 1, //标识符不能以_开头或结尾
    'no-unneeded-ternary': 1, //禁止不必要的嵌套 var isYes = answer === 1 ? true : false;
    'no-unreachable': 2, //不能有无法执行的代码
    'no-unused-expressions': 2, //禁止无用的表达式
    'no-unused-vars': [2, {vars: 'all', args: 'after-used'}], //不能有声明后未被使用的变量或参数
    'no-use-before-define': 2, //未定义前不能使用
    'no-useless-call': 2, //禁止不必要的call和apply
    'no-void': 2, //禁用void操作符
    'no-var': 0, //禁用var,用let和const代替
  },
};

prettier.config.js // 编辑代码时结束后,点击保存会自动修复代码中的规范 比如:缩进、分号、引号等等

//prettier.config.js
module.exports = {
  printWidth: 100, // 每行代码长度(默认80)
  tabWidth: 2, // 每个tab相当于多少个空格(默认2)ab进行缩进(默认false)
  useTabs: false, // 是否使用t
  singleQuote: true, // 使用单引号(默认false)
  semi: true, // 声明结尾使用分号(默认true)
  trailingComma: 'all', // 多行使用拖尾逗号(默认none)
  bracketSpacing: true, // 对象字面量的大括号间使用空格(默认true)
  jsxBracketSameLine: false, // 多行JSX中的>放置在最后一行的结尾,而不是另起一行(默认false)
  // 箭头函数参数括号 默认avoid 可选 avoid| always
  // avoid 能省略括号的时候就省略 例如x => x
  // always 总是有括号
  arrowParens: 'avoid',
};

.eslintignore // 忽略文件夹不检测eslint规范

/node_modules/
vue.js
vue.min.js
jquery.js
jquery.min.js

CI CD流程

CI 代表持续集成(Continuous Integration),就是提交代码。CD 代表持续交付(Continuous Delivery)和持续部署(Continuous Deployment)。

vue3 ref和reactive区别

reactive 接受入参必须是对象形式,而 ref 可以是对象形式,也可以是一个单值。
读取/赋值不一样,ref 必须从.value 属性中读取值
ref存在异步问题、
双向绑定的变量在setup中定义时要加ref,修改变量的值时要加value
ref本质上还是reactive,只不过reactive需要传入一个对象,但是有时候我们需要一个基本类型作为响应式,如果用reactive的话就需要reactive({value:xxx})这样传进去,所以vue就提供了ref这种写法,让你不需要手动包装成对象。所以这也是为什么ref包装的响应式对象需要.value才能拿到值的原因。

toRefs的使用

http://www.manongjc.com/detail/24-jbmucsyptuaoosk.html

query和params的区别

https://blog.csdn.net/G_Z_X/article/details/123487587

非空类型断言

//类型断言,将el定义为img元素,as就是用于大范围转具体类型
var el = document.querySelector('wyh') as HTMLImageElement;
el.src = 'xxx';
type Method = 'GET'| 'POST';
function request(url: string, method: Method) {
}
const o = {
    url: 'xxx',
    method:'GET'
}
//第二个参数会报错,需使用as
// request(o.url, o.method);
request(o.url, o.method as Method);

Vue 3 强制刷新组件的三种必会方法总结

Vue 是基于响应式的,自动挡操作,当数据发生改变,与之相对应的视图也会刷新。但开发过程中,我们有时候会遇到一些额外的状况,例如动态赋值后,对应的数据发生了变换,但 DOM 却没有及时更新,因此我们此时就处于一个很尴尬的境地,值已经修改成功,但双向绑定的 DOM 节点我们却获取不到。这时候我们就需要来手动更新组件来更新数据。

重新加载整个页面

但是这种方法是最容易实现的,我们只需借用路由 route 即可。

route.go(0);

v-if 方法和nextTick结合

<template>
  <div class="force-refresh">
    <h1>vue3 组件强制刷新的四种方式</h1>
    <h2>卡拉云——低代码开发工具,1 秒搭建上传后台</h2>
    <tag-kala v-if="renderComponent" :tag="tag"></tag-kala>
    <el-button @click="toggleTag" type="primary" class="btn">切换tag</el-button>
  </div>
</template>

然后再 script 中,使用 nextTick 方法:

import { nextTick } from "vue";
import TagKala from "./components/TagKala.vue";
export default {
  components: {
    TagKala,
  },
  data() {
    return {
      tag: "tag1",
      renderComponent: true,
    };
  },
  methods: {
    forceRerender() {
      this.renderComponent = false;
      nextTick(() => {
        this.renderComponent = true;
      });
    },
    toggleTag() {
      this.tag = this.tag === "tag1" ? "tag2" : "tag1";
      // 在需要强制刷新的时机,调用 forceRender
      this.forceRerender();
    },
  },
};

利用 key 值的变化触发组件更新

Vue 的虚拟 DOM 算法在比对 Vnode 时会用到 key 作为唯一标识,key 值改变该元素就会被重新渲染。修改 key 值也是 Vue 官方支持和推荐的做法,并且实现起来也非常简单。修改 key 值 方法与 v-if 都是切换元素,那为什么会推荐修改 key 值的方法呐? 这里一定要注意到 key 值是作用于虚拟 DOM 的,因此它的性能会远远优于 v-if。

<tag-kala :tag="tag" ref="tag" :key="keyNum"></tag-kala>
toggleTag() {
  this.tag = this.tag === 'tag1' ? 'tag2' : 'tag1';
  this.keyNum++;
},

项目git流程

首先git clone
然后git checkout -b一个分支
然后写代码
然后review
然后git add .
然后 git cz
选择类型回车
写commit然后回车
然后vscode左下角点击提交
请添加图片描述

vue3异步传props问题

当父组件在给子组件传递一个props时,当由于请求这个props会发生变化,这时子组件需要用这个最新的props去请求数据。
父组件

<template>
  <div>
    <button @click="btn">点击后两秒改变props</button>
    <bb :name="data.name" :age="data.age"></bb>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import bb from "./b.vue";
const data = ref({ name: "123", age: "123" });
function btn() {
  setTimeout(function () {
    data.value.name = "111";
    data.value.age = "222222";
  }, 2000);
}
</script>

<style></style>

子组件

<template>
  <div>
    <h1>111</h1>
    <h2>{{ props.name }}</h2>
    <h2>{{ props.age }}</h2>
  </div>
</template>

<script setup lang="ts">
import { defineProps, watch, onMounted } from "vue";
const props = defineProps({
  name: {
    type: String,
    required: false,
  },
  age: {
    type: String,
    required: false,
  },
});
watch(
  () => props.name,
  (v1, v2) => {
    a();
  }
);
function a() {
  if (props.name == "111") {
    console.log("成功");
  }else{
    console.log('失败')
  }
}
console.log(props);
onMounted(() => {
  a();
});
</script>

<style></style>

如何完全卸载node?

完全卸载node

时间格式化ts文件

export function formatDate(str) {
  const oDate = new Date(str);
  const oYear = oDate.getFullYear();
  const oMonth = oDate.getMonth() + 1;
  const oDay = oDate.getDate();
  const oHour = oDate.getHours();
  const oMin = oDate.getMinutes();
  const oSen = oDate.getSeconds();
  function addZero(num: any) {
    const data = parseInt(num, 10);
    return data < 10 ? `0${num}` : num;
  }
  const oTime = `${oYear}-${addZero(oMonth)}-${addZero(oDay)} ${addZero(oHour)}:${addZero(oMin)}:${addZero(oSen)}`;
  return oTime;
}

业务逻辑

a组件中有一个createmodel弹出表单组件和一个列表,当弹出表单组件编辑完成后要点自己的确定按钮,那么怎么让列表刷新呢
需要createmodel暴露一个编辑方法,将原先配置导入,然后emit一个方法submit(const emit = defineEmits([‘cancel’, ‘submit’]); emit(‘submit’);),当点击确定按钮后emit(‘submit’); 然后a组件中调用submit即可刷新

微服务和微前端

请添加图片描述
微服务
从思路和理念上来讲,微服务就是要倡导大家尽量将功能进行拆分,将服务粒度做小,使之可以独立承担对外服务的职责,沿着这个思路开发和交付的软件服务实体就叫作“微服务“
微前端
从上面不难看出微前端能够带来的一些好处:独立开发、独立部署、各个系统自治、单一职责、技术栈无关,甚至于能够解决遗留系统的迁移。防止一个普通应用演变为一个不可维护的巨石应用。
需要明确得是微前端不是框架、不是工具/库,而是一套架构体系,它包括若干库、工具、中心化治理平台以及相关配套设施

服务治理概念

应用从单体架构向微服务架构演进的过程中,由于细粒度的微服务应用数量大幅增长,微服务之间的服务发现、负载均衡、熔断限流等服务治理需求显著提高。
重试:
微服务中自动重试也是服务间调用的一项常见配置,当上游服务返回特定类型的错误代码时可重新尝试调用。由于错误可能是暂时的环境抖动引起,一般很快恢复,所以重试是一个有用的策略。重试是解决一些异常请求的直接、简单的方法,尤其是网络质量不稳定的场景下,可提高服务质量。但是重试使用不当也会有问题,特定情况下重试可能一直不成功,反而增加延迟和性能开销。
熔断:
多个服务之间存在依赖调用,如果某个服务无法及时响应请求,故障向调用源头方向传播,可能引发集群的大规模级联故障,造成整个系统不可用。为应对这种情况,可以引入熔断策略。为了防止故障范围的扩大,熔断的基本逻辑就是隔离故障。
限流:
熔断的主要目的是隔离故障,而引起故障的原因除了系统服务内部的问题外,还有可能是请求量超过了系统处理能力的极限,后续新进入的请求会持续加重服务负载,导致资源耗尽发生服务出错。限流的目的就是拒绝过多的请求流量,保证服务整体负载处于合理水平。

全链路灰度技术

什么是全链路灰度

全链路灰度治理策略主要专注于整个调用链,它不关心链路上经过具体哪些微服务,流量控制视角从服务转移至请求链路上,仅需要少量的治理规则即可构建出从网关到整个后端服务的多个流量隔离环境,有效保证了多个亲密关系的服务顺利安全发布以及服务多版本并行开发,进一步促进业务的快速发展。提高整个系统的维护性和稳定性

全链路灰度的解决方案

如何在实际业务场景中去快速落地全链路灰度呢?目前,主要有两种解决思路,基于物理环境隔离和基于逻辑环境隔离。
1.物理环境隔离
物理环境隔离,顾名思义,通过增加机器的方式来搭建真正意义上的流量隔离。
物理环境隔离,顾名思义,通过增加机器的方式来搭建真正意义上的流量隔离。
在这里插入图片描述
这个方案一般用于企业的测试、预发开发环境的搭建,对于线上灰度发布引流的场景来说其灵活性不够。况且,微服务多版本的存在在微服务架构中是家常便饭,需要为这些业务场景采用堆机器的方式来维护多套灰度环境。如果您的应用数目过多的情况下,会造成运维、机器成本过大,成本和代价远超收益;如果应用数目很小,就两三个应用,这个方式还是很方便的,可以接受的。

2.逻辑环境隔离
另一种方案是构建逻辑上的环境隔离,我们只需部署服务的灰度版本,流量在调用链路上流转时,由流经的网关、各个中间件以及各个微服务来识别灰度流量,并动态转发至对应服务的灰度版本。如下图:
请添加图片描述
需要用到的技术:
标签路由
节点打标
流量染色
分布式链路追踪

逻辑环境隔离——基于 SDK和基于 Service Mesh

请添加图片描述

#内容提炼于深入刨析全链路灰度技术文章

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值