2024-08-13

在JavaScript中,可以使用以下几种方法来跳出循环:

  1. return:在函数中使用return可以提前退出函数,但如果在循环体内部使用,则可以跳出循环。



function loopWithReturn() {
  for (let i = 0; i < 10; i++) {
    if (i === 5) {
      return; // 当i等于5时,提前退出函数(循环)
    }
    console.log(i);
  }
}
  1. break:在循环体内部使用break可以直接跳出当前循环。



for (let i = 0; i < 10; i++) {
  if (i === 5) {
    break; // 当i等于5时,跳出循环
  }
  console.log(i);
}
  1. continue:在循环体内部使用continue可以跳过当前循环的剩余部分,并继续下一次循环。



for (let i = 0; i < 10; i++) {
  if (i % 2 === 0) {
    continue; // 当i为偶数时,跳过当前循环的剩余部分
  }
  console.log(i); // 只会在i为奇数时执行
}
  1. throw:虽然throw通常用于抛出异常,但它也可以用来终止循环。



try {
  for (let i = 0; i < 10; i++) {
    if (i === 5) {
      throw 'Loop terminated'; // 当i等于5时,抛出异常,并跳出循环
    }
    console.log(i);
  }
} catch (error) {
  console.error(error); // 打印:'Loop terminated'
}

以上方法可以在forwhiledo...while循环中使用,并且它们都可以用来立即退出循环。选择哪种方法取决于具体情况,但通常break是最直接的选择,除非你需要在函数中提前返回或者需要异常处理的情况下跳出循环。

2024-08-13

在JavaScript中,Function 是一个内置的引用类型,它是函数(方法)对象的基础。每个函数都是 Function 类型的实例。

函数可以通过多种方式进行定义,最常见的是使用函数声明或函数表达式。




// 函数声明
function myFunction(arg1, arg2) {
  // 函数体
}
 
// 函数表达式
var myFunction = function(arg1, arg2) {
  // 函数体
};

在JavaScript中,函数也是对象,所以可以像其他对象一样对其进行操作。例如,你可以将函数赋值给变量,或作为其他函数的参数。




// 函数作为值赋给变量
var add = function(a, b) {
  return a + b;
};
 
// 函数作为其他函数的参数
function applyFunc(func, arg1, arg2) {
  return func(arg1, arg2);
}
 
var result = applyFunc(add, 5, 3); // 结果为8

Function 类型的属性:

  • length:表示函数期望接收的参数个数。
  • prototype:表示函数的原型对象,用于为对象实例定义共享的属性和方法。

Function 类型的方法:

  • call()apply():用于调用函数,并以指定的 this 值和参数执行代码。
  • bind():创建一个新的函数,在调用这个函数时,将其 this 关键字设置为提供的值,在调用新函数时,遵循提供的参数序列。



function greet(greeting, punctuation) {
  return greeting + ',' + this.name + punctuation;
}
 
var greetJohn = greet.bind({ name: 'John' }, 'Hello', '!');
console.log(greetJohn()); // 输出 "Hello, John!"

Function 类型的创建和使用:




// 使用Function构造函数创建函数
var addFunc = new Function('a', 'b', 'return a + b');
console.log(addFunc(5, 3)); // 输出 8

注意:使用 Function 构造函数创建函数不推荐,因为这种方式可读性差,并且每次都会创建新的函数,影响性能。通常,推荐使用函数声明或函数表达式来创建函数。

2024-08-13

@vitejs/plugin-legacy 是 Vite 生态中的一个插件,它用于为 Vite 项目提供对旧浏览器的支持。通过该插件,你可以创建两个构建版本:现代版本和遗留版本,以确保现代浏览器能够获得最好的性能,同时还能支持旧版浏览器。

以下是如何在 Vite 项目中使用 @vitejs/plugin-legacy 的示例代码:

首先,你需要安装这个插件:




npm install @vitejs/plugin-legacy --save-dev

然后,在你的 Vite 配置文件中引入并配置该插件:




// vite.config.js
import { defineConfig } from 'vite';
import legacy from '@vitejs/plugin-legacy';
 
export default defineConfig({
  plugins: [
    legacy({
      targets: ['defaults', 'not IE 11'], // 指定要支持的浏览器的范围
    }),
  ],
});

在上述配置中,targets 选项指定了要为哪些浏览器提供支持。你可以根据需要调整这个选项。

使用该插件后,Vite 会生成两套 Chunk 文件:一套现代的 JavaScript 文件(无 transpile)和一套为遗留浏览器转换过的 JavaScript 文件(通过 babel-preset-env 或者其他转换器)。

为了在 HTML 中加载这两套文件,你可以使用如下的条件注释:




<!DOCTYPE html>
<html>
<head>
  <script type="module" src="/src/main.js"></script>
  <!-- 现代浏览器 -->
  <script type="module" src="/src/main.legacy.js"></script>
  <!-- 为了兼容不支持模块的浏览器 -->
  <script nomodule src="/src/main.js"></script>
  <!-- 遗留浏览器 -->
</head>
<body>
  <div id="app"></div>
</body>
</html>

在这个例子中,现代浏览器会加载 .js 文件作为模块,而遗留浏览器则会加载不支持模块的 .legacy.js 文件。这样,你就可以同时支持现代和遗留浏览器,提升了应用的兼容性。

2024-08-13



// 假设我们已经有了一个HTML页面,其中包含一个id为"canvas"的canvas元素
// 以下是实现大转盘抽奖功能的核心代码
 
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
const centerX = width / 2;
const centerY = height / 2;
const radius = Math.min(centerX, centerY);
 
// 转盘的配置项
const config = {
    itemCount: 6, // 转盘上的奖项数量
    outerRadius: radius - 100, // 转盘外半径
    innerRadius: radius - 150, // 转盘内半径
    startAngle: -Math.PI / 2, // 第一个奖项的起始角度
    endAngle: Math.PI / 2, // 最后一个奖项的结束角度
    textColor: 'white', // 文本颜色
    textFont: '20px Arial', // 文本字体
    textBaseline: 'middle', // 文本基线对齐方式
    fillStyle: ['red', 'blue', 'green', 'yellow', 'orange', 'purple'] // 每个奖项的填充颜色
};
 
// 绘制转盘
function drawRouletteWheel(config) {
    let angle = config.startAngle;
    for (let i = 0; i < config.itemCount; i++) {
        angle += Math.PI / (config.itemCount / 2);
        ctx.beginPath();
        ctx.moveTo(centerX, centerY);
        ctx.arc(centerX, centerY, config.outerRadius, angle, Math.PI / (config.itemCount / 2), false);
        ctx.arc(centerX, centerY, config.innerRadius, Math.PI / (config.itemCount / 2), angle, true);
        ctx.closePath();
        ctx.fillStyle = config.fillStyle[i];
        ctx.fill();
 
        ctx.save();
        ctx.translate(centerX, centerY);
        ctx.rotate(angle);
        ctx.fillStyle = config.textColor;
        ctx.font = config.textFont;
        ctx.textBaseline = config.textBaseline;
        ctx.fillText('Prize ' + (i + 1), -ctx.measureText('Prize ' + (i + 1)).width / 2, 0);
        ctx.restore();
    }
}
 
// 初始化转盘
drawRouletteWheel(config);

这段代码展示了如何使用Canvas API来绘制一个基本的转盘抽奖功能。在这个例子中,我们定义了一个config对象来配置转盘的外半径、内半径、开始角度、结束角度、颜色和奖项文本。然后我们定义了一个drawRouletteWheel函数来根据这些配置绘制转盘,并使用了变换操作来将奖项文本旋转以匹配它们在转盘上的位置。最后,我们调用drawRouletteWheel函数来初始化转盘。

2024-08-13

React 和 Vue 前端实现国密算法SM2、SM3、SM4的方法可以使用JavaScript或TypeScript。这里提供一个简单的JavaScript示例,展示如何实现这些算法的核心功能。

请注意,这些示例并不是完整的实现,而是提供了核心函数的样板代码。实际应用中,你需要使用专业的密码学库,如JSEncrypt,或者自行实现这些算法。




// SM2 示例
class SM2 {
  // 假设有公钥、私钥生成、加密、解密等方法
}
 
// SM3 示例
function sm3(message) {
  // 假设有SM3哈希函数的实现
  // 返回消息的哈希值
}
 
// SM4 示例
class SM4 {
  // 假设有加密、解密等方法
}
 
// 使用示例
const message = '需要加密的消息';
const sm3Hash = sm3(message);
console.log('SM3哈希值:', sm3Hash);
 
// 如果有专业库,可以直接调用库提供的API

在实际开发中,你需要使用现有的密码学库,如JSEncrypt,以保证算法的正确性和安全性。如果库不支持国密算法,你可能需要自行实现或找专业的密码学工程师协助实现。

请注意,这些代码只是示例,并不能直接在生产环境中使用。实际应用中,你需要考虑安全性、性能和兼容性等多个方面。

2024-08-13



<template>
  <div>
    <img
      v-for="(img, index) in imgList"
      :key="index"
      :src="img"
      @click="previewImage(index)"
    />
    <vue-photo-preview
      :preview-src-list="imgList"
      :current="currentIndex"
      @close="currentIndex = null"
    />
  </div>
</template>
 
<script>
import VuePhotoPreview from 'vue-photo-preview';
import 'vue-photo-preview/dist/skin.css';
 
export default {
  components: {
    VuePhotoPreview
  },
  data() {
    return {
      imgList: [
        'path/to/image1.jpg',
        'path/to/image2.jpg',
        'path/to/image3.jpg'
      ],
      currentIndex: null
    };
  },
  methods: {
    previewImage(index) {
      this.currentIndex = index;
    }
  }
};
</script>

这个代码示例展示了如何在Vue应用中使用vue-photo-preview组件来实现图片列表的预览功能。它包括了图片列表的渲染和点击图片时的预览逻辑。当用户点击某个图片时,previewImage方法会被调用,并将当前图片的索引设置为currentIndex,从而触发图片预览组件的显示。当用户关闭预览时,@close事件处理器会将currentIndex重置为null,以关闭预览状态。

2024-08-13

在Vue.js中,v-model是一个指令,它创建了一个双向绑定,它可以用在表单类元素(如input, textarea, select)上创建双向数据绑定。

v-model实质上是一个语法糖,它在内部为不同的输入类型自动处理不同的方法,如文本输入框使用value属性和input事件,复选框使用checked属性和change事件。

以下是一个简单的例子,展示如何使用v-model来创建一个双向绑定:




<template>
  <div>
    <input v-model="message" placeholder="edit me">
    <p>Message is: {{ message }}</p>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      message: ''
    }
  }
}
</script>

在这个例子中,v-model绑定了message变量,无论输入框中的值如何变化,message变量都会实时更新,同时如果message变量发生变化,输入框中的内容也会更新。

如果你希望自定义v-model的行为,可以使用.lazy修饰符,它可以改变事件从输入框触发的时机为失去焦点时:




<input v-model.lazy="message">

还可以使用.trim修饰符,自动过滤输入框的首尾空格:




<input v-model.trim="message">

最后,你可以直接在组件上使用v-model,这样可以避免在每个子组件上都使用$emit$on




<custom-input v-model="message"></custom-input>

custom-input组件内部,你需要使用this.$emit('input', value)来更新值,并且确保在组件被创建时this.$emit('input', this.value)被调用,以确保父组件可以接收到初始值。

以下是一个使用了上述工具的Node.js项目的简化版package.json文件示例:




{
  "name": "your-project",
  "version": "1.0.0",
  "scripts": {
    "format": "prettier --write .",
    "lint": "eslint .",
    "lint:staged": "lint-staged"
  },
  "husky": {
    "hooks": {
      "pre-commit": "npm run lint && npm run format",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "lint-staged": {
    "*.js": "eslint --fix",
    "*.ts": "eslint --fix"
  },
  "devDependencies": {
    "eslint": "^7.20.0",
    "prettier": "^2.2.1",
    "husky": "^6.0.0",
    "lint-staged": "^10.0.7",
    "commitlint": "^11.0.0",
    "commitizen": "^4.2.4"
  },
  "eslintConfig": {
    "extends": ["some-eslint-config"]
  },
  "prettier": {
    "singleQuote": true,
    "trailingComma": "es5",
    "printWidth": 80
  },
  "commitlint": {
    "extends": ["@commitlint/config-conventional"]
  },
  "config": {
    "commitizen": {
      "path": "cz-conventional-changelog"
    }
  }
}

这个配置文件定义了项目的基本信息,包括脚本命令,husky钩子,lint-staged配置,以及所需依赖的版本。同时,它也包含了eslintConfigprettiercommitlintconfig部分,用于配置ESLint、Prettier、Commitlint和Commitizen。这样的配置文件提供了一个结构化的方式来管理代码质量和版本控制提交规范。




// 导入所需的配置
const { defineConfig } = require('eslint-define-config')
 
// 导入Vue 3的推荐配置
const vue3 = require('eslint-plugin-vue').configs.recommended
 
// 导入TypeScript的推荐配置
const typescript = require('@typescript-eslint/conf').default
 
// 定义ESLint规则
module.exports = defineConfig({
  // 使用Vue 3的推荐配置作为基础
  ...vue3,
  // 扩展规则
  rules: {
    // 示例:禁用单行间隔
    'vue/singleline-html-element-content-newline': 'off',
    'vue/multiline-html-element-content-newline': 'off',
    // 示例:启用函数前要求或禁止空行
    'function-call-argument-newline': ['error', 'consistent'],
    // 启用更严格的类型检查
    '@typescript-eslint/no-explicit-any': 'error',
    // 更多规则...
  },
  // 使用TypeScript解析器
  parser: typescript.parser,
  // 扩展TypeScript的规则
  parserOptions: {
    ...typescript.parserOptions,
    // 示例:项目使用的JavaScript版本
    ecmaVersion: 2022,
    // 示例:启用额外的语言特性
    ecmaFeatures: {
      jsx: true,
      // 更多特性...
    },
  },
  // 使用TypeScript的插件
  plugins: ['vue', '@typescript-eslint'],
  // 配置文件的扩展名
  extraFileExtensions: ['.vue', '.ts', '.tsx'],
  // 示例:配置环境
  env: {
    browser: true,
    node: true,
    // 更多环境...
  },
  // 示例:配置全局变量
  globals: {
    globalThis: 'readonly',
    // 更多全局变量...
  },
  // 示例:配置处理器
  processors: {
    '.ts': typescript.processors['.ts'],
    // 更多处理器...
  },
})

这个代码实例展示了如何从现有的配置中导入和扩展ESLint规则,以及如何定制ESLint规则,使其更适合特定项目的需求。它还演示了如何将Vue 3和TypeScript的推荐配置作为基础,并根据项目的具体需求进行调整。

2024-08-13



const http = require('http');
const url = process.argv[2];
 
// 检查命令行参数是否提供了URL
if (!url) {
  console.log('请提供要测试的URL作为命令行参数');
  process.exit(1);
}
 
// 检查URL格式是否正确
if (!url.match(/^http:\/\/|https:\/\//)) {
  console.log('URL必须以http://或https://开头');
  process.exit(1);
}
 
// 发起对URL的GET请求
http.get(url, (res) => {
  console.log(`状态码: ${res.statusCode}`);
  console.log(`响应头: ${JSON.stringify(res.headers)}`);
  res.on('data', (d) => {
    process.stdout.write(d);
  });
}).on('error', (e) => {
  console.error(`请求出错: ${e.message}`);
  process.exit(1);
});

这段代码使用Node.js内置的http模块来发起一个简单的GET请求到指定的URL。它检查命令行参数是否提供了URL,并验证了URL的格式是否正确。如果请求成功,它会打印状态码和响应头;如果有错误,它会打印错误信息。这是一个简单的外部连接测试示例,适用于教育目的。