常用的一些code fragment


一、JavaScript & ES6+

1. MapObject

const legSelectedMap = new Map();
legSelectedMap.set('业务量1', true)
legSelectedMap.set('业务量2', false)
legSelectedMap.set('业务量3', false)

console.log([...legSelectedMap.entries()]);
// 输出:Array [Array ["业务量1", true], Array ["业务量2", false], Array ["业务量3", false]]
let legSelected = [...legSelectedMap.entries()].reduce((obj, [key, value]) => (obj[key] = value, obj), {})

console.log(legSelected); // 输出:Object { 业务量1: true, 业务量2: false, 业务量3: false }

二、TS

1.类型:指定object类型

private userData : { [key: string]: any }

三、常见场景

1.订阅机制原理:宽屏状态检测

以 折叠屏的折叠和展开状态检测为例,是一个典型的观察者模式(Observer Pattern)实现

src/utils/wideScreen.ts

//  定义订阅者类型:订阅者函数类型,接收布尔值参数(宽屏状态)
type WideScreenSubscriber = (isWideScreen: boolean) => void;
let __ISWIDESCREEN__: boolean // 全局状态变量: 存储当前宽屏状态
// 订阅者数组: 存储所有订阅宽屏状态变化的回调函数
const subscribers: WideScreenSubscriber[] = [];

// 通知所有订阅者的函数
function notifySubscribers() {
  subscribers.forEach(callback => {
    try {
      callback(__ISWIDESCREEN__);
    } catch (err) {
      console.error('宽屏状态变化通知失败:', err);
    }
  });
}

(function flexible (window, document) {
    const docEl = document.documentElement
    
    function checkIsWideScreenStatus () {
      const { clientWidth } = docEl
      const oldValue = __ISWIDESCREEN__;
      __ISWIDESCREEN__ = clientWidth > 430
      
      // 仅当状态发生变化时才通知订阅者
      if (oldValue !== __ISWIDESCREEN__) {
        // 双重通知渠道
        // 方式1:触发自定义事件,方便其他组件响应宽屏状态变化
        // const event = new CustomEvent('wideScreenChange', { 
        //   detail: { isWideScreen: __ISWIDESCREEN__ } 
        // })
        // window.dispatchEvent(event)
        
        // 方式2:通知所有订阅者
        notifySubscribers();
      }
    }
  
    checkIsWideScreenStatus() // 初始检测
    window.addEventListener('resize', checkIsWideScreenStatus) // 监听窗口大小变化
    window.addEventListener('orientationchange', checkIsWideScreenStatus) // 监听屏幕方向变化(对折叠屏有帮助)
    // 页面显示时重新检测
    window.addEventListener('pageshow', (e) => {
      if (e.persisted) {
        checkIsWideScreenStatus()
      }
    })
    
    // 监听可折叠屏幕状态变化 (使用标准视口API)
    if (window.visualViewport) {
      window.visualViewport.addEventListener('resize', checkIsWideScreenStatus)
    }
    // 添加 MutationObserver 以捕获DOM变化可能导致的屏幕尺寸变化
    const observer = new MutationObserver((mutations) => {
      // 只在可能影响布局的变化时检查
      if (mutations.some(mutation => 
        mutation.type === 'attributes' && 
        ['style', 'class'].includes(mutation.attributeName || '')
      )) {
        checkIsWideScreenStatus()
      }
    })
    
    // 观察文档根元素的属性变化
    observer.observe(docEl, { attributes: true })
}(window, document))

/**
 * 获取当前是否为宽屏状态
 * @returns 当前是否为宽屏状态
 */
export function isWideScreen(): boolean {
  return __ISWIDESCREEN__
}

/**
 * 订阅宽屏状态变化
 * @param callback 状态变化时的回调函数
 * @returns 取消订阅的函数
 */
export function subscribeWideScreenChange(callback: WideScreenSubscriber): () => void {
  subscribers.push(callback);
  
  // 立即执行一次回调,传入当前状态
  callback(__ISWIDESCREEN__);
  
  // 清理:在不再需要监听时(比如组件卸载时)清理订阅,防止内存泄漏
  return () => {
    const index = subscribers.indexOf(callback);
    if (index !== -1) {
      subscribers.splice(index, 1);
    }
  };
}

组件外部调用xxx.vue

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { subscribeWideScreenChange } from './path-to-your-module'


const isWideScreen = ref(false) // 响应式状态
let unsubscribe = null // 保存取消订阅函数的引用

onMounted(() => {  // 组件挂载时订阅
  unsubscribe = subscribeWideScreenChange((isWide) => {
    isWideScreen.value = isWide
    // 处理屏幕变化逻辑
  })
})
onUnmounted(() => { // 组件卸载前取消订阅
  if (unsubscribe) {
    unsubscribe()
  }
})
</script>

<template>
  <div>
    当前是{{ isWideScreen ? '宽屏' : '窄屏' }}模式
  </div>
</template>

四、配置类问题

1.报错模块"xxx"没有导出的成员"ZNavigator"(TS

详细报错:
在ts的项目中,通过import { ZNavigator } from '@lianpf/native-sdk-plus'引入,但报错 模块"@lianpf/native-sdk-plus"没有导出的成员"ZNavigator"。ts(2305)

原因
原因是@lianpf/native-sdk-plus内部为js库,那么要如何配置,可以忽略这些ts错误提示呢

解决办法
tsconfig.json

{
  "extends":"./src/.zmi/tsconfig.json",
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false,
    // 其他编译选项
    "typeRoots": ["src/@types/native-sdk-plus.d.ts"],
  }
}

src/@types/native-sdk-plus.d.ts

declare module '@zto/zt-sdk-plus' {
    // 库的导出类型和函数声明  
    // ... 其他类型和函数声明  
    // const lib: {  
    //     // 允许任意方法名,但这不是一个好的做法,因为它会失去类型安全性  
    //   [methodName: string]: (...args: any[]) => any;  
    // };  
      
    // export = lib;  
    export const ZNavigator: any;
}

最后, 希望大家早日实现:成为编程高手的伟大梦想!
欢迎交流~

微信公众号

本文版权归原作者曜灵所有!未经允许,严禁转载!对非法转载者, 原作者保留采用法律手段追究的权利!
若需转载,请联系微信公众号:连先生有猫病,可获取作者联系方式!