z-index不生效 原因
- 只对定位元素生效,position属性
- 父元素的z-index层级更高 111
使用自定义指令绑定dom元素
因为vue自定义指令的生命周期与vue的生命周期相同,能稳定的获取到绑定的dom节点
Vue.directive('my-directive', {
bind(el, binding, vnode) {
// 绑定时的初始化逻辑
},
inserted(el, binding, vnode) {
// 元素插入到父节点时的逻辑
},
update(el, binding, vnode, oldVnode) {
// 元素所在模板更新时的逻辑
},
componentUpdated(el, binding, vnode, oldVnode) {
// 元素所在模板完成一次更新周期时的逻辑
},
unbind(el, binding, vnode) {
// 解绑时的清理逻辑
}
});
threejs材质
- 基本材质:最简单的材质,只有一种颜色
- Lambert材质:需要光照,但不会产生镜面反射
- phong材质:与 Lambert 材质相似,但会产生镜面反射
- 标准材质:基于物理渲染,支持更多特性,如镜面反射、折射等
- Shader材质:允许使用自定义着色器进行渲染
threejs性能优化
- 多使用clone()方法;
- 模型不需要时,调用dispose();
- 使用 BufferGeometry对象;
- 图片压缩;
- 优化渲染时,requestAnimationFrame 中的方法,不要重复定义,注意循环;
- 模型减顶点、减面,使用法线贴图;
- 把材质精度降低,尽量共享材质;
- 模型拆分加载,或把模型合并,合并消耗,尽量在编辑器下合并;
- 模型格式优化,使用 gltf 或 glb;
- LOD技术(Levels of Detail 多细节层次),BIM(建筑信息模型),应用场景:
- 优化GPU:通过减少非重要物体的细节,
- 异步、分片、缓存,如 使用 indexedDB存取模型;
- 使用websocket,将一些计算放到后台执行;
- 不需要显示的,可使用 WebGLRenderTarget 后台渲染,需要时再加入;
- 阴影需要才打开;
- 渲染时,将执行的操作砍半;
- import three 会使打包后的js多出几M,使用哪个import哪个较好;
- 视锥体剔除不可见的物体;
- 场景摄像机变化时,才渲染场景,大部分大屏通常都是静止不动的,发生业务时,有时才需要人机交互;
在使用 GLTF 模型快速渲染车辆时,如果遇到渲染精度不足
的问题,可以尝试使用 渲染器中logarithmicDepthBuffer
属性来解决
当相机远离物体时,由于浮点数精度的限制,可能会出现 Z-缓冲精度不足的问题,导致深度缓冲的精度不够,从而产生 Z-fighting 等渲染问题;对数深度缓冲(Logarithmic Depth Buffer)技术,以提高相机远近处的深度精度。提高GPU渲染精度,同时会消耗更多性能。
typescript修饰器
- 修饰器是一种函数,可以附着在类定义、方法、访问器、属性或参数声明之前。
- 可修改类or类成员(属性+方法)。
- 它可以接受一至三个参数,分别是目标对象、成员的名称和成员的描述符。
- 修饰器可以分为类修饰器、方法修饰器、访问器修饰器、属性修饰器和参数修饰器。
- 修饰器可以用来实现诸如日志记录、缓存、验证、权限控制等功能,它是一种更优雅的方式来扩展类的功能。
// 类修饰器示例
function logClass(target: any) {
console.log('Class decorator called on:', target);
}
// 方法修饰器示例
function logMethod(target: any, key: string, descriptor: PropertyDescriptor) {
console.log('Method decorator called on:', key);
}
// 属性修饰器示例
function logProperty(target: any, key: string) {
console.log('Property decorator called on:', key);
}
// 参数修饰器示例
function logParameter(target: any, key: string, index: number) {
console.log('Parameter decorator called on:', key, 'index:', index);
}
@logClass // 类修饰器,用来打印目标类
class MyClass {
@logProperty // 属性修饰器,用来打印目标属性
prop: string;
// @logParameter 参数修饰器,用来打印目标方法的参数
constructor(@logParameter arg1: string, @logParameter arg2: number) {}
@logMethod // 方法修饰器,用来打印目标方法
myMethod() {}
}
const instance = new MyClass('arg1', 2);
instance.myMethod();
Vue挂载到$el属性上解决场景
- 在Vue3 中,可通过 $el 访问组件的根DOM元素。
- 在Vue3中,若想将Vue组件的内容作为信息窗口的内容。先创建一个Vue应用实例,将其挂载到一个临时DOM元素上,
const mapCard = createApp({
data, //定义数据
infoWindow, // 要渲染的DOM模板字符串
methods:{} // 定义方法
})
// 创建一个临时的DOM元素
const tempDiv = document.createElement('div');
//挂载Vue应用到临时元素
mapCard.mount(tempDiv);
// 可在适当时候销毁Vue实例
mapCard.unmount();
挂载全局属性和方法在Vue上
在Vue3中,app.config.globalProperties
用于定义全局的属性和方法。可通过app
实例来访问。
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
// 添加全局属性
app.config.globalProperties.$myGlobalProperty = 'hello world';
// 全局方法
app.config.globalProperties.$myGlobalMethod = () => {
console.log('this is a global method');
}
app.mount('#app');
- 在组件中使用
<template>
<div>
<p>{{ $myGlobalProperty }}</p>
<button @click="$myGlobalMethod()">Call Global Method</button>
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$myGlobalProperty); // 访问全局属性
},
};
</script>
XMLHttpRequest源码改写
- 用于调试、监控、修改网络请求。
const originOpen = XMLHttpRequest.prototype.open; // 原始open方法
XMLHttpRequest.proptotype.open = function(method, url, ...arg) {
// 检查URL是否以特定字符串结尾
if(url.endsWith('/api/fs/put')) {
console.log('Intercepted XMLHttpRequest:', method, url, argument);
url = 'xxx'; // 替换URL
}
// 调用原始open方法
originOpen.call(this, method, url, ...arg);
}
注意:
- 性能:在高频请求中,频繁console.log打印可能会影响性能,在生产环境中适当控制。
全局混入的方式改写生命周期API执行内容
- 在Vue中,利用
Vue。mixin()
定义一个全局混入,可在所有组件中使用。
import {createApp } from 'vue';
import store from './store';
const app = createApp({
// 根组件选项
})
// 全局混入
app.mixin({
computed: {
userInfo() {
return this.$store.userInfo;// 从 Vuex store获取用户信息
}
},
mounted() {
console.log('页面mounted用户信息:', this.userInfo);
},
// 可添加Vue中使用类似onLoad钩子
});
// 挂载应用
app.use(store);
app.mount('#app');
- 混入在小程序中的使用:例如,对
onLoad
和ready
生命周期钩子进行增强。
function mixin(config, key, type, callback) {
if (config[key] && config[key][type]) {
let original = config[key][type];
config[key][type] = function(args) {
console.log(`=====================${type} 前=====================`);
callback.call(this, args);
original.call(this, args);
console.log('this.$vm', this.$vm); // 输出上下文
console.log(`=====================${type} 后=====================`);
}
} else {
callback.call(this);// 若没有原始方法,直接调用回调
}
}
export default (function() {
let originalComponent = Component;// 保存原始Component函数
Component = function(config) {
// 在组件配置中增加 mixin
mixin(config, 'methods', 'onLoad', function() {
this.$vm.isIphoneX = getApp().globalData.isIphoneX; //在 onLoad 中设置isIphoneX
});
mixin(config, 'lifetimes', 'ready', function() {
this.$vm.isIphoneX = getApp().globalData.isIphoneX;// 在 ready 中设置
});
originalComponent(config); // 调用原始 Component函数
}
})()
使用rpx单位进行响应式布局,css提效
// 方向映射
const directionMap = {
t: 'top',
r: 'right',
b: 'bottom',
l: 'left',
m: 'margin',
p: 'padding'
};
//样式规则
rules: [
// 把 margin 和 padding 的样式单位改为 rpx
//匹配 margin 和 padding:将如 m10 或 p20 的类转换为 { margin: '10rpx' } 或 { padding: '20rpx' }。
[/^([mp])-?(\d*)$/, ([name, direction, d]) => ({ [directionMap[direction]]: ${d}rpx })],
//匹配方向性 margin 和 padding: 类如 p-r10 会被转换为 { padding-right: '10rpx' }。
[/^([mp])([trlb])-?(\d*)$/, ([name, key, direction, d]) => ({ [${directionMap[key]}-${directionMap[direction]}]: ${d}rpx })],
//匹配 y 和 x 方向 例如,m-y10 会被转换为 { margin-top: '10rpx', margin-bottom: '10rpx' }。
[/^([mp])y-?(\d*)$/, ([name, direction, d]) => ({ [${directionMap[direction]}-top]: ${d}rpx, [${directionMap[direction]}-bottom]: ${d}rpx })],
[/^([mp])x-?(\d*)$/, ([name, direction, d]) => ({ [${directionMap[direction]}-left]: ${d}rpx, [${directionMap[direction]}-right]: ${d}rpx })],
//边框圆角:类如 bdr10 会转换为 { border-radius: '10rpx' }。
[/^bdr-?(\d*)$/, ([, d]) => ({ 'border-radius': ${d}rpx })]
],
//快捷方式
shortcuts: {
fc: 'flex justify-center',
fyc: 'flex items-center',
fcc: 'flex justify-center items-center',
fyb: 'flex items-center justify-between',
't-hide': 'truncate',
tac: 'text-center'
},