随遇随记篇

devtools/2025/1/21 21:17:30/

vue 函数

unref() 获取原始值

ref 定义的属性 需要 .value 才能拿到值,unref 直接返回原始值;若属性不是ref 定义的,也是直接返回原始值;

 /* @description: 是否必填*/required?: boolean | Ref<boolean>.....let value = unref(required)

toRefs 为属性添加响应

具体场景:解构方式会使响应式丢失,通过toRefs 添加响应式

````
/*** @description: 接收父组件参数* @param { RouteRecordRaw[] }  value  路由列表* @param { boolean } collapsed   是否展开-收起*/
const props = defineProps({value: {type: Object as PropType<RouteRecordRaw[]>,required: true,},collapsed: {type: Boolean as PropType<boolean>,required: true,default: () => true,},
})````` 解构会响应式丢失,使用toRefs 为属性添加响应式
// 父组件参数传递给子组件
const { value } = toRefs(props)console.log(value.value)

useSlots()获取组件的插槽

// 获取插槽的名称
const slots = useSlots()
let slotsList: string[] = []
for (const key in slots) {slotsList.push(key)
}

vue3中$attrs对象获取非props定义的所有属性

vue3中组件定义了props,但是父组件传了 非 props 定义的属性,可以使用 $attrs 获取

``` 父组件传值调用
<table-listrow-key="id"class="customerManagement-table":columns="columns"size="small":data-source="tableDataList":pagination="pagination":row-selection="{selectedRowKeys: selectedRowKey,onChange: onSelectChange,}"@change="pagination.change"/>``` 子组件定义的props
const props = defineProps({/*** @description: 接收父组件参数* @param { Array } columns 表头标题*/columns: {type: Array as PropType<Array<ColumnType>>,required: true,default: () => [],},pagination: {type: [Object, Boolean] as PropType<Pagination | false>,default: false,}
})``` 获取 父组件传过来的 data-source 属性,这属性,没有在props上定义
const attrs = useAttrs()
const data = attrs['data-source']
<!-- ParentComponent.vue -->
<template><child-component custom-attr="value"></child-component>
</template><!-- ChildComponent.vue -->
<script>
export default {mounted() {console.log(this.$attrs); // { custom-attr: 'value' }}
};
</script>

v-model 为啥能传值给组件

当v-model 传值时,组件内部默认会接收一个value 的值;

vue3组件通信

Vue 组件实例之间通过 props、events、provide/inject、$parent/$children、$attrs/$listeners 等方式进行通信,具体取决于组件的关系和需求。这些机制允许组件在不同层级之间传递数据和响应用户交互。

emit 方式自动更新父组件的数据,不用方法触发

当传入

 props: {importFile: {type: Object,default: () => {},},importLoading: {type: Boolean,default: false,},},

使用 emit的方式可以自动更新父组件的数据

emits: ['update:importLoading', 'update:importFile']通过emit update 的方式可以自动更新父组件的值
// 这里子组件会给父组件的 importLoading 传值 false, 父组件不需要特别接收处理
emit('update:importLoading', false)````
// 子组件更新 父组件的 importFile 的值为 file,
emit('update:importFile', file)
<ImportModalv-if="importVisible"v-model="importVisible"v-model:import-loading="importLoading"v-model:import-file="importFile"template@import="handleImportFile"@template="handleTemplate"/>

defineExpose 编译宏命令,暴露子组件方法或属性

vue3 中 当使用<script setup>语法糖时,组件默认不会自动暴露内部的任何属性或方法给外部,为了显示地暴露属性或方法,可以使用 defineExpose

defineProps 获取父组件传过来的值

defineEmits 子通过方法传给父

vite

import.meta.glob 

这是vite 提供的特殊功能, 用于动态导入多个模块。

import.meta.glob('./**/*.ts', { eager: true }) 动态导入 当前的 所有 ts 文件,eager:true 是立即导入

import { createApp } from 'vue'
import { ObjectExtends } from '@/model/common'/*** @description 加载所有 Plugins (以_开头的文件名不被加载)* @param  { ReturnType<typeof createApp> } app 整个应用的实例*/
export default function loadAllPlugins(app: ReturnType<typeof createApp>): void {const files: ObjectExtends = import.meta.glob('./**/*.ts', { eager: true })Object.keys(files).forEach((key: string) => {if (typeof files[key].default === 'function') {const fileName = key.replace('./', '') // Remove './' prefixif (!fileName.startsWith('_') && fileName !== 'index.ts') {files[key].default(app)}}})
}

css 预处理器

当引入antd 组件,但是需要修改主题风格,需要全局修改变量,例如在variables.less 中定义字体和颜色变量

/*** antd*/
@primary-color: #13c2c2; // 全局主色
@danger-color: #f96868; // 危险色
@link-color: #41a3fd; // 链接色
@success-color: #13c2c2; // 成功色
@warning-color: #ff972f; // 警告色
@error-color: #f96868; // 错误色
@font-size-base: 14px; // 主字号
@heading-color: #333333; // 标题色
@text-color: #333333; // 主文本色
@text-color-secondary: #999999; // 次文本色
@disabled-color: #cccccc; // 失效色
@border-radius-base: 2px; // 组件/浮层圆角
@border-color-base: #d9d9d9; // 边框色
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15); // 浮层阴影
@table-header-bg: #f5f5f5; // 表格头部背景色
@divider-color: #f0f0f0; // 分割线
@component-background: #ffffff; // 底色/背景色
@table-selected-row-bg: #f5f7fa; // 表格选中
@table-selected-row-hover-bg: #f5f7fa; // 表格悬停状态
@border-color: #f0f0f0; // 边框颜色
@border-radius: 2px; // 边框圆角
@border-radius-panel: 4px; // 面板圆角
@success-border-color: #7cdddd; // 成功色边框色
@success-background-color: #e7f9f9; // 成功色背景色
@error-border-color: #fbabab; // 错误色边框色
@error-background-color: #feefef; // 错误色背景色
@warning-border-color: #fec78e; // 警告色边框色
@warning-background-color: #fef8ef; // 警告色背景色/*** 层级*/
@heder-z-index: 1070;
@sideBar-z-index: 1070;
@progress-z-index: 1085;
@tabs-z-index: 1060;
@tabs-content-z-index: 1065;/*** 常用*/
@white: #fff;
@gray-1: #9b9b9b;
@gray-2: #e7e7e7;
@gray-3: #3a3a3a;
@gray-4: #4a4a4a;
@gray-5: #cccccc;
@gray-6: #5e5e5e;
@gray-7: #666666;
@gray-8: #999999;
@gray-9: #333333;
@gray-10: #d9d9d9;

以下代码配置:

  1. 将 variables.less 文件作为参考导入,使其变量可用于其他 Less 文件。

  2. 导入 index.less 文件,并将其编译为 CSS 构建过程的一部分。

  3. 启用 Less 中的 JavaScript 支持,允许更动态和灵活的 CSS 代码。

css: {preprocessorOptions: {less: {// modifyVars:这个选项允许你在 Less 编译过程中修改变量;// @import (reference) "./src/assets/css/variables.less" 将一个 Less 文件作为参考导入,而不是直接编译它;modifyVars: {hack: `true; @import (reference) "./src/assets/css/variables.less";`,},// additionalData:这个选项允许你添加额外的数据到 Less 编译过程中;additionalData: `@import "./src/assets/css/index.less";`,javascriptEnabled: true,},},},

插件

postCss 转换css 代码工具
module.exports = {plugins: [require('postcss-preset-env'),require('postcss-flexbugs-fixes'),require('tailwindcss'),require('autoprefixer'),],
}

1、autoprefixer 自动添加兼容不同浏览器的前缀

2、cssnext 把css新特性转译成当前浏览器中可使用的语法

3、css 模块化,css类名在使用时会被转换成带有唯一标识的形式,避免名称冲突

4、postcss-preset-env‌:支持最新的 CSS 语法并自动转换

5、cssnano‌:压缩和优化 CSS

6、postcss-flexbugs-fixes 尝试解决flex 布局问题的插件

7、tailwindcss 与 post-flexbugs-fixes 结合使用,确保flexbox 布局获得最佳的兼容性

vite:preloadError

vite:preloadError 是 Vite 构建工具在预加载资源时遇到的错误。

预加载是 Vite 的一个特性,用于在应用启动时预加载资源,以提高应用的性能。预加载错误通常是由于资源文件不存在、资源文件格式不正确或资源文件无法被解析等原因引起的。

对错误的处理:

<script type="text/javascript">//  设置cookiefunction setCookie(name, value, seconds) {const date = new Date()date.setTime(date.getTime() + seconds * 1000)const expires = 'expires=' + date.toUTCString()document.cookie = name + '=' + value + ';' + expires + ';path=/'}//  获取cookiefunction getCookie(name) {const nameEQ = name + '='const ca = document.cookie.split(';')for (let i = 0; i < ca.length; i++) {let c = ca[i]while (c.charAt(0) === ' ') c = c.substring(1, c.length)if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length)}return null}window.addEventListener('vite:preloadError', (event) => {// 检查 cookie 中是否存在标记const firstVisit = getCookie('viteFirstVisit')if (!firstVisit) {// 第一次进入页面,强制浏览器重新加载setCookie('viteFirstVisit', 'true', 30) // 设置 cookie 有效期为30秒window.location.reload()} else {alert('请尝试清除浏览器缓存(Ctrl + Shift + Del)后重新加载页面,或联系我们的技术支持以获取帮助。')}})</script>

nginx.conf.js

是一个用于配置 Nginx 的 JavaScript 文件,它通常在以下情况下被调用:

  1. Vite 开发模式:当你运行 vite 命令启动开发服务器时,Vite 会自动调用 nginx.conf.js 文件来配置 Nginx。

  2. Vite 构建模式:当你运行 vite build 命令构建应用时,Vite 会调用 nginx.conf.js 文件来配置 Nginx,以便在生产环境中使用。

  3. Nginx 启动时:如果你手动启动 Nginx 服务,Nginx 会自动调用 nginx.conf.js 文件来加载配置。

在 nginx.conf.js 文件中,你可以定义 Nginx 的配置,例如:

  • 设置端口号和监听地址

  • 配置静态资源服务

  • 配置代理服务器

  • 配置 SSL/TLS 加密

  • 等等

const fs = require('fs')const env = process.env.VUE_APP_MODE || 'production'function parseApiJsonAndGenerateNginxConfig() {let apiJsontry {apiJson = JSON.parse(fs.readFileSync('./api.json').toString('utf-8'))} catch (ex) {console.error('读取api.json错误', ex)return}if (!apiJson) {console.error('api.json为空')return}if (!apiJson[env]) {console.error(`读取api配置错误, env: ${env}`)return}const nginxContent = generateNginxConfig(apiJson, env)let filePathif (env === 'production') {filePath = './nginx.prod.conf'} else {filePath = './nginx.test.conf'}fs.writeFileSync(filePath, nginxContent)
}/*** @description: 跨域配置*/
const crossDomainConfig = `add_header 'Access-Control-Allow-Origin' '*' always;add_header 'Access-Control-Allow-Headers' '*' always;add_header 'Access-Control-Expose-Headers' '*' always;
`/*** @description: 请求预检配置*/
const requestOptionsConfig = `if ($request_method = 'OPTIONS') {${crossDomainConfig}## Tell client that this pre-flight info is valid for 20 days#add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain; charset=utf-8';add_header 'Content-Length' 0;return 204;}
`/*** @description: 请求方法配置*/
const requestMethodConfig = `${requestOptionsConfig}if ($request_method = 'POST') {${crossDomainConfig}}if ($request_method = 'GET') {${crossDomainConfig}}
`/*** 根据api代理配置生成 nginx 配置* @param {*} apiJson* @param {*} env* @returns*/
const generateNginxConfig = (apiJson, env) => {let tplList = Object.keys(apiJson[env]).map((k) => {return makeNginxProxy(k, apiJson[env][k])}).join('\n\n')return `server {# 端口listen 80;server_name localhost;root /app/dist;index index.html index.htm;include /etc/nginx/default.d/*.conf;# 上传文件大小限制client_max_body_size 200M;   # 静态资源缓存600秒location ~* .(css|js|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff)$ {${requestMethodConfig}add_header    Cache-Control  max-age=600;}# 静态资源location / {index index.html;try_files $uri $uri/ /index.html;add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";${requestOptionsConfig}${crossDomainConfig}}# 代理配置${tplList}}`
}const makeNginxProxy = (apiPath, proxyHttpHost) => `location /${apiPath}/ {${requestMethodConfig}proxy_pass ${proxyHttpHost}/;proxy_set_header X-Real-IP $remote_addr;proxy_set_header REMOTE-HOST $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}`parseApiJsonAndGenerateNginxConfig()

vite.config.ts

1、alias 设置别名

在Node.js中,当你使用ES Modules时,import.meta.url提供了一个当前模块的绝对URL。通过结合使用new URL()构造函数和fileURLToPath()函数,可以动态地获取当前脚本所在目录下的特定文件的实际文件系统路径。这种方法特别适用于需要动态解析文件路径的场景,例如读取或修改文件内容‌。

import { fileURLToPath, URL } from 'node:url'resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url)),'~': fileURLToPath(new URL('./', import.meta.url)),},},

css 属性

选择器选中 placeholder 

::placeholder 是一个伪元素

input::placeholder {color: #666; /* 更改 placeholder 文本颜色 */font-size: 12px; /* 更改 placeholder 文本大小 */
}
input::-webkit-input-placeholder {color: #666; /* 更改 WebKit 浏览器中的 placeholder 文本颜色 */
}
input:-moz-placeholder {color: #666; /* 更改 Mozilla 浏览器中的 placeholder 文本颜色 */
}
input:-ms-input-placeholder {color: #666; /* 更改 Microsoft 浏览器中的 placeholder 文本颜色 */
}

更改特定 input 元素的 placeholder 文本样式

input[type="text"]::placeholder {color: #666; /* 更改文本输入框 placeholder 文本颜色 */
}

字体颜色渐变 

线性渐变 linear-gradient(),第一个参数是方向 to left | right | top | bottom

background-clip 剪切文字,扣字

background: linear-gradient(to right, #13c2c2, #f96868);
background-clip: text;
-webkit-background-clip: text;
color: transparent;

CSS 多列布局属性解析:column-count 和 column-gap

column-count 属性用于设置元素的列数,而 column-gap 属性用于设置元素之间的间隔。

column-count 属性确定了元素要分割成的列数。它接受一个整数值,表示要分成的列数。值得注意的是,由于 column-count 只是设定了列数,并没有设定列宽,实际列宽会根据父元素的宽度和列数自动计算得出。

效果如下:

box-sizing 属性

border-box, 元素总宽度和总高度包括了元素的border 边框和padding 内边距,而不仅仅是 content 内容。

content-box,默认值,宽度和高度仅包含内容区域。

cursor css样式-鼠标指针

cursor: w-resize 水平双箭头

鼠标指针形状为水平双箭头,(表示可以左右拉动边界)

cursor: s-resize 垂直双箭头

鼠标指针形状为垂直双箭头,(表示可以向上或向下拉动边界)

resize 属性允许用户拖拉界面

resize: none | both | horizontal | vertical | inherit;

  • none: 不允许用户调整元素的大小

  • both: 允许用户调整元素的宽度和高度

  • horizontal: 允许用户调整元素的宽度

  • vertical: 允许用户调整元素的高度

  • inherit: 从父元素继承 resize 属性值

注意:resize 属性必须与 overflow 属性一起使用,且 overflow 的值不能为 visible

示例:

eval() 函数

javascript 内置的函数,用于计算字符串表达式的值,即 把字符串转成代码 执行 返回 运算值。例如: eval("3+5"); // 值: 8;不接受return, 会抛出异常。

JSON 转换器

JSON.parse() 是将JSON代码转换成 Javascript 的解析器。JSON.stringfy() 将Javascript对象转换成 JSON字符串。

JS 刷新本页面: window.location.reload()

HTTP

HTTP中常见的 ContentType

HTTP协议是以 ASCll 码传输的,HTTP请求主要有三个部分:状态行、请求头、消息主体。消息主题没有规定必须使用什么编码方式,所以需要在请求头里面设置 content-type 编码方式,消息主体满足这里设定的编码方式即可。服务器端根据 请求头的 Content-Tyoe字段获知 请求中的消息主体使用何种编码方式,再对主体进行解析。

  1. application / x-www-form-urlencoded
    1. 这是表单提交 post 请求常用的 content-type, 提交的数据按照key1=val1&key2=val2&key3=val3&key4=val4 的方式编码,其中 key和val 都会进行 url 转码。
  2. multipart / form-data
  3. applicetion / json
  4. text / xml

responseType 响应类型

如果返回的数据是 文件流,要设置响应头格式为 arraybuffer

/*** 接口返回一个导出的文件流,* 请求方法里面加上响应请求头类型 arraybuffer */
export const customerApiExport = (data: PaginationReq<AdvancedQueryReq>
): Promise<AxiosResponse> => {return request.post(`${apiProxy}/sc/consumer-account/exportList`, data, {responseType: 'arraybuffer',})
}

文件流数据处理,使用new Blob() 存储二进制数据,

 // 获取导出的文件流customerApiExport(tableDataReq.value).then((res) => {const blob = new Blob([res.data], { type: res.headers['content-type'] })const url = window.URL.createObjectURL(blob)const a = document.createElement('a')a.href = urla.download = '客户信息'a.click()window.URL.revokeObjectURL(url)}).finally(() => {exportBntLoading.value = false})

responseType值的类型

数据类型

‘’

DOMString(默认类型)

arraybuffer

ArrayBuffer对象

blob

Blob对象

document

Documnet对象

json

JavaScript object, parsed from a JSON string returned by the server

text

DOMString

http1 、http2、http3

http1.0

非持久性连接,每次请求都要重新建立连接;

浏览器客户端在同一时间针对同一域名下的请求有一定的数量限制,超出数目的请求会被堵塞;

数据是文本形式传输;

http1.1

引入了更多缓存控制策略

优化了宽带

新增状态响应码

头部压缩

服务端推送

支持使用 HTTPS 进行加密传输

http2.0 采用多路复用、二进制分帧传输

http3.0 基于 UDP 协议的 QUIC 协议

  1. 线头阻塞问题更加彻底

    1. 基于TCP的Http2,尽管在逻辑上相互独立,不会相互影响,但在实际中,数据是 一帧一帧发送和接收,但是一旦某一个流的数据有丢包,则同样会阻塞在它之后的传输流数据传输。而基于UDP的Http3.0就没有这个问题,能够让不同的流之间实现真正的独立。

  2. 网络切换时连接保持

    1. 在当前移动端的应用环境,用户网络会经常切换,基于TCP的协议,由于切换网络之后,IP会改变,所以说之前建立的连接会断开。而基于UDP的Http3.0,则可以内建与TCP中不同的连接标识方法,从而在网络完成切换后,恢复之前的服务器连接

other

如果一个字段 为 undefined,则不会上传到接口

...(formData.value?.configInfo?.length? { configInfo: formData.value.configInfo.join(',') }: {}),
const params: UpdateConfigReq = {id: formData.value.id,isNewSystem: formData.value.isNewSystem,configInfo: formData.value.configInfo?.join(',') || undefined,}

?? 和 || 的区别

用法相似:两者都是二元运算符,前后各有一个值,并根据前面的值决定返回哪个值

如:

  • a ?? b

  • a || b

?? 空值合并运算符

如果前面的变量是 null 或者 undefined ,则会执行 ?? 后面的代码。

仅在前面的值为 null 或 undefined 时返回后面的值。

|| 逻辑或运算符

如果前面的变量是 假值,则会执行 || 后面的代码

当前面的值为任何“假值”(如 false0NaN、空字符串 ""null 或 undefined)时返回后面的值。


http://www.ppmy.cn/devtools/152426.html

相关文章

JavaScript 拖拽与观察者模式的实现及应用

前言 本文将通过几个具体的代码片段&#xff0c;深入探讨 JavaScript 中的拖拽功能和观察者模式&#xff08;发布-订阅模式&#xff09;的实现及其应用场景。 这些代码片段不仅展示了如何实现这些功能&#xff0c;还解释了其背后的原理和实际用途。通过阅读本文&#xff0c;读…

小程序疫苗预约网站系统ssm+论文源码调试讲解

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…

为什么相关性不是因果关系?人工智能中的因果推理探秘

目录 一、背景 &#xff08;一&#xff09;聚焦当下人工智能 &#xff08;二&#xff09;基于关联框架的人工智能 &#xff08;三&#xff09;基于因果框架的人工智能 二、因果推理的基本理论 &#xff08;一&#xff09;因果推理基本范式&#xff1a;因果模型&#xff0…

纯 Python、Django、FastAPI、Flask、Pyramid、Jupyter、dbt 解析和差异分析

一、纯 Python 1.1 基础概念 Python 是一种高级、通用、解释型的编程语言&#xff0c;以其简洁易读的语法和丰富的标准库而闻名。“纯 Python” 在这里指的是不依赖特定的 Web 框架或数据分析工具&#xff0c;仅使用 Python 原生的功能和标准库来开发应用程序或执行任务。 1.…

MySQL(七)MySQL和Oracle、PostgreSQL的区别

文章目录 一、MySQL和Oracle 1.1 基本差别*1.2 使用区别 二、MySQL和PostgreSQL 2.1 基本差别*2.2 使用差别 本系列文章&#xff1a; MySQL&#xff08;一&#xff09;SQL语法、数据类型、常用函数、事务 MySQL&#xff08;二&#xff09;MySQL SQL练习题 MySQL&#xff08;…

路由器缓冲区如何调节的指南说明

调整路由器缓冲区大小是一个复杂且需要细致操作的过程&#xff0c;涉及到对网络流量、设备性能以及缓冲区类型的深入理解。本位作为一篇详尽的指南&#xff0c;提供调整路由器缓冲区的具体方法。 一、前期准备与评估 1. 了解路由器型号与操作系统&#xff1a; 不同品牌和型号…

VSCODE SSH远程连接报错或无法联网安装.vscode-server

问题 问题1:"无法与 SSH 建立连接&#xff1a;XHR Failed"解决篇 在有网得情况下ssh连接总是提示如下&#xff1a; 问题2&#xff1a;远程linux环境无法联网&#xff0c;不能在线下载 解决办法 ​​​​​​​分析&#xff1a;根据报错显示&#xff0c;正在下载 “…

mongoose 支持https踩坑纪实

简述 mongoose是C编写的嵌入式web服务&#xff0c;它能够支持https协议&#xff0c;可以简单的部署&#xff0c;但要做到完美部署&#xff0c;不是那么容易。 部署方法 本人使用的是最新的7.16版&#xff0c;以前版本似乎是要通过修改 头文件中的 MG_ENABLE_SSL 宏定义&…