review

121 阅读5分钟

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) {
    // 解绑时的清理逻辑
  }
});

2023 threejs 常见面试知识点总结

threejs材质

  1. 基本材质:最简单的材质,只有一种颜色
  2. Lambert材质:需要光照,但不会产生镜面反射
  3. phong材质:与 Lambert 材质相似,但会产生镜面反射
  4. 标准材质:基于物理渲染,支持更多特性,如镜面反射、折射等
  5. Shader材质:允许使用自定义着色器进行渲染

threejs性能优化

  1. 多使用clone()方法;
  2. 模型不需要时,调用dispose();
  3. 使用 BufferGeometry对象;
  4. 图片压缩;
  5. 优化渲染时,requestAnimationFrame 中的方法,不要重复定义,注意循环;
  6. 模型减顶点、减面,使用法线贴图;
  7. 把材质精度降低,尽量共享材质
  8. 模型拆分加载,或把模型合并,合并消耗,尽量在编辑器下合并;
  9. 模型格式优化,使用 gltf 或 glb;
  10. LOD技术(Levels of Detail 多细节层次),BIM(建筑信息模型),应用场景:
  • 优化GPU:通过减少非重要物体的细节,
  1. 异步、分片、缓存,如 使用 indexedDB存取模型;
  2. 使用websocket,将一些计算放到后台执行;
  3. 不需要显示的,可使用 WebGLRenderTarget 后台渲染,需要时再加入;
  4. 阴影需要才打开;
  5. 渲染时,将执行的操作砍半;
  6. import three 会使打包后的js多出几M,使用哪个import哪个较好;
  7. 视锥体剔除不可见的物体;
  8. 场景摄像机变化时,才渲染场景,大部分大屏通常都是静止不动的,发生业务时,有时才需要人机交互;

在使用 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源码改写

那些修改node_modules源码的骚操作

  • 用于调试、监控、修改网络请求。
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');
  • 混入在小程序中的使用:例如,对onLoadready生命周期钩子进行增强。
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'
},