欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解微信小程序工程化探索之webpack實(shí)戰(zhàn)

 更新時(shí)間:2020年04月20日 09:44:48   作者:饅頭君  
這篇文章主要介紹了詳解微信小程序工程化探索之webpack實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

微信小程序因?yàn)槠浔憬莸氖褂梅绞剑詷O快的速度傳播開(kāi)來(lái)吸引了大量的使用者。市場(chǎng)需求急劇增加的情況下,每家互聯(lián)網(wǎng)企業(yè)都想一嘗甜頭,因此掌握小程序開(kāi)發(fā)這一技術(shù)無(wú)疑是一名前端開(kāi)發(fā)者不可或缺的技能。但小程序開(kāi)發(fā)當(dāng)中總有一些不便一直讓開(kāi)發(fā)者詬病不已,主要表現(xiàn)在:

  • 初期缺乏方便的npm包管理機(jī)制(現(xiàn)階段確實(shí)可以使用npm包,但是操作確實(shí)不便)
  • 不能使用預(yù)編譯語(yǔ)言處理樣式
  • 無(wú)法通過(guò)腳本命令切換不同的開(kāi)發(fā)環(huán)境,需手動(dòng)修改對(duì)應(yīng)環(huán)境所需配置(常規(guī)項(xiàng)目至少具備開(kāi)發(fā)與生產(chǎn)環(huán)境)
  • 無(wú)法將規(guī)范檢查工具結(jié)合到項(xiàng)目工程中(諸如EsLint、StyleLint的使用)

有了不少的問(wèn)題之后,我開(kāi)始思考如何將現(xiàn)代的工程化技術(shù)與小程序相結(jié)合。初期在社區(qū)中查閱資料時(shí),許多前輩都基于gulp去做了不少實(shí)踐,對(duì)于小程序這種多頁(yè)應(yīng)用來(lái)說(shuō)gulp的流式工作方式似乎更加方便。在實(shí)際的實(shí)踐過(guò)后,我不太滿意應(yīng)用gulp這一方案,所以我轉(zhuǎn)向了對(duì)webpack的實(shí)踐探索。我認(rèn)為選擇webpack作為工程化的支持,盡管它相對(duì)gulp更難實(shí)現(xiàn),但在未來(lái)的發(fā)展中一定會(huì)有非凡的效果,

實(shí)踐

我們先不考慮預(yù)編譯、規(guī)范等等較為復(fù)雜的問(wèn)題,我們的第一個(gè)目標(biāo)是如何應(yīng)用webpack將源代碼文件夾下的文件輸出到目標(biāo)文件夾當(dāng)中,接下來(lái)我們就一步步來(lái)創(chuàng)建這個(gè)工程項(xiàng)目:

/* 創(chuàng)建項(xiàng)目 */
$ mkdir wxmp-base
$ cd ./wxmp-base
/* 創(chuàng)建package.json */
$ npm init
/* 安裝依賴(lài)包 */
$ npm install webpack webpack-cli --dev

安裝好依賴(lài)之后我們?yōu)檫@個(gè)項(xiàng)目創(chuàng)建基礎(chǔ)的目錄結(jié)構(gòu),如圖所示:

上圖所展示的是一個(gè)最簡(jiǎn)單的小程序,它只包含app全局配置文件和一個(gè)home頁(yè)面。接下來(lái)我們不管全局或是頁(yè)面,我們以文件類(lèi)型劃分為需要待加工的js類(lèi)型文件和不需要再加工可以直接拷貝的wxml、wxss、json文件。以這樣的思路我們開(kāi)始編寫(xiě)供webpack執(zhí)行的配置文件,在項(xiàng)目根目錄下創(chuàng)建一個(gè)build目錄存放webpack.config.js文件。

$ mkdir build
$ cd ./build
$ touch webpack.config.js
/** webpack.config.js */
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');

const ABSOLUTE_PATH = process.cwd();

module.exports = {
 context: path.resolve(ABSOLUTE_PATH, 'src'),
 entry: {
  app: './app.js',
  'pages/home/index': './pages/home/index.js'
 },
 output: {
  filename: '[name].js',
  path: path.resolve(ABSOLUTE_PATH, 'dist')
 },
 module: {
  rules: [
   {
    test: /\.js$/,
    exclude: /node_modules/,
    use: {
     loader: 'babel-loader',
     options: {
      presets: ['@babel/preset-env'],
      plugins: ['@babel/plugin-transform-runtime'],
     },
    },
   }
  ]
 },
 plugins: [
  new CopyPlugin([
   {
    from: '**/*.wxml',
    toType: 'dir',
   },
   {
    from: '**/*.wxss',
    toType: 'dir',
   },
   {
    from: '**/*.json',
    toType: 'dir',
   }
  ])
 ]
};

在編寫(xiě)完上述代碼之后,為大家解釋一下上述的代碼究竟會(huì)做些什么:

  • 入口entry對(duì)象中我寫(xiě)了兩個(gè)屬性,意在將app.js和home/index.js作為webpack的構(gòu)建入口,它會(huì)以這個(gè)文件為起始點(diǎn)創(chuàng)建各自的依賴(lài)關(guān)系,這樣當(dāng)我們?cè)谌肟谖募幸肫渌募r(shí),被引入的文件也能被webpack所處理。
  • module中我使用了babel-loader對(duì)js文件進(jìn)行ES6轉(zhuǎn)換為ES5的處理,并且加入了對(duì)新語(yǔ)法的處理,這樣我們就解決了在原生小程序開(kāi)發(fā)中總是要反復(fù)引入regenerator-runtime的問(wèn)題。(這一步我們需要安裝@babel/core、@babel/preset-env、@babel/plugin-transform-runtime、@babel/runtime、babel-loader這幾個(gè)依賴(lài)包)
  • 使用copy-webpack-plugin來(lái)處理不需要再加工的文件,這個(gè)插件可以直接將文件復(fù)制到目標(biāo)目錄當(dāng)中。

我們了解完這些代碼的實(shí)際作用之后就可以在終端中運(yùn)行webpack --config build/webpack.config.js命令。webpack會(huì)將源代碼編譯到dist文件夾中,這個(gè)文件夾中的內(nèi)容就可用在開(kāi)發(fā)者工具中運(yùn)行、預(yù)覽、上傳。

優(yōu)化

完成了最基礎(chǔ)的webpack構(gòu)建策略后,我們實(shí)現(xiàn)了app和home頁(yè)面的轉(zhuǎn)化,但這還遠(yuǎn)遠(yuǎn)不夠。我們還需要解決許多的問(wèn)題:

  • 頁(yè)面文件增多怎么辦,組件怎么處理
  • 預(yù)期的預(yù)編譯如何做
  • 規(guī)范如何結(jié)合到工程中
  • 環(huán)境變量怎么處理

接下來(lái)我們針對(duì)以上幾點(diǎn)進(jìn)行webpack策略的升級(jí):

頁(yè)面與組件

一開(kāi)始我的實(shí)現(xiàn)方法是寫(xiě)一個(gè)工具函數(shù)利用glob收集pages和components下的js文件然后生成入口對(duì)象傳遞給entry。但是在實(shí)踐過(guò)程中,我發(fā)現(xiàn)這樣的做法有兩個(gè)弊端:

  • 當(dāng)終端中已經(jīng)啟動(dòng)了命令,這時(shí)候新增頁(yè)面或組件都不會(huì)自動(dòng)生成新的入口,也就是我們要重跑一遍命令。
  • 工具函數(shù)寫(xiě)死了匹配pages和components文件夾下的文件,不利于項(xiàng)目的延展性,如果我們需要分包或者文件夾命名需要改動(dòng)時(shí),我們就需要改動(dòng)工具函數(shù)。

本著程序員應(yīng)該是極度慵懶,能交給機(jī)器完成的事情絕不自己動(dòng)手的信條,我開(kāi)始研究新的入口生成方案。最終確定下來(lái)編寫(xiě)一個(gè)webpack的插件,在webpack構(gòu)建的生命周期中生成入口,廢話不多說(shuō)上代碼:

/** build/entry-extract-plugin.js */
const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const replaceExt = require('replace-ext');
const { difference } = require('lodash');
const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
const MultiEntryPlugin = require('webpack/lib/MultiEntryPlugin');

class EntryExtractPlugin {
 constructor() {
  this.appContext = null;
  this.pages = [];
  this.entries = [];
 }

 /**
  * 收集app.json文件中注冊(cè)的pages和subpackages生成一個(gè)待處理數(shù)組
  */
 getPages() {
  const app = path.resolve(this.appContext, 'app.json');
  const content = fs.readFileSync(app, 'utf8');
  const { pages = [], subpackages = [] } = JSON.parse(content);
  const { length: pagesLength } = pages;
  if (!pagesLength) {
   console.log(chalk.red('ERROR in "app.json": pages字段缺失'));
   process.exit();
  }
  /** 收集分包中的頁(yè)面 */
  const { length: subPackagesLength } = subpackages;
  if (subPackagesLength) {
   subpackages.forEach((subPackage) => {
    const { root, pages: subPages = [] } = subPackage;
    if (!root) {
     console.log(chalk.red('ERROR in "app.json": 分包配置中root字段缺失'));
     process.exit();
    }
    const { length: subPagesLength } = subPages;
    if (!subPagesLength) {
     console.log(chalk.red(`ERROR in "app.json": 當(dāng)前分包 "${root}" 中pages字段為空`));
     process.exit();
    }
    subPages.forEach((subPage) => pages.push(`${root}/${subPage}`));
   });
  }
  return pages;
 }

 /**
  * 以頁(yè)面為起始點(diǎn)遞歸去尋找所使用的組件
  * @param {String} 當(dāng)前文件的上下文路徑
  * @param {String} 依賴(lài)路徑
  * @param {Array} 包含全部入口的數(shù)組
  */
 addDependencies(context, dependPath, entries) {
  /** 生成絕對(duì)路徑 */
  const isAbsolute = dependPath[0] === '/';
  let absolutePath = '';
  if (isAbsolute) {
   absolutePath = path.resolve(this.appContext, dependPath.slice(1));
  } else {
   absolutePath = path.resolve(context, dependPath);
  }
  /** 生成以源代碼目錄為基準(zhǔn)的相對(duì)路徑 */
  const relativePath = path.relative(this.appContext, absolutePath);
  /** 校驗(yàn)該路徑是否合法以及是否在已有入口當(dāng)中 */
  const jsPath = replaceExt(absolutePath, '.js');
  const isQualification = fs.existsSync(jsPath);
  if (!isQualification) {
   console.log(chalk.red(`ERROR: in "${replaceExt(relativePath, '.js')}": 當(dāng)前文件缺失`));
   process.exit();
  }
  const isExistence = entries.includes((entry) => entry === absolutePath);
  if (!isExistence) {
   entries.push(relativePath);
  }
  /** 獲取json文件內(nèi)容 */
  const jsonPath = replaceExt(absolutePath, '.json');
  const isJsonExistence = fs.existsSync(jsonPath);
  if (!isJsonExistence) {
   console.log(chalk.red(`ERROR: in "${replaceExt(relativePath, '.json')}": 當(dāng)前文件缺失`));
   process.exit();
  }
  try {
   const content = fs.readFileSync(jsonPath, 'utf8');
   const { usingComponents = {} } = JSON.parse(content);
   const components = Object.values(usingComponents);
   const { length } = components;
   /** 當(dāng)json文件中有再引用其他組件時(shí)執(zhí)行遞歸 */
   if (length) {
    const absoluteDir = path.dirname(absolutePath);
    components.forEach((component) => {
     this.addDependencies(absoluteDir, component, entries);
    });
   }
  } catch (e) {
   console.log(chalk.red(`ERROR: in "${replaceExt(relativePath, '.json')}": 當(dāng)前文件內(nèi)容為空或書(shū)寫(xiě)不正確`));
   process.exit();
  }
 }

 /**
  * 將入口加入到webpack中
  */
 applyEntry(context, entryName, module) {
  if (Array.isArray(module)) {
   return new MultiEntryPlugin(context, module, entryName);
  }
  return new SingleEntryPlugin(context, module, entryName);
 }

 apply(compiler) {
  /** 設(shè)置源代碼的上下文 */
  const { context } = compiler.options;
  this.appContext = context;

  compiler.hooks.entryOption.tap('EntryExtractPlugin', () => {
   /** 生成入口依賴(lài)數(shù)組 */
   this.pages = this.getPages();
   this.pages.forEach((page) => void this.addDependencies(context, page, this.entries));
   this.entries.forEach((entry) => {
    this.applyEntry(context, entry, `./${entry}`).apply(compiler);
   });
  });

  compiler.hooks.watchRun.tap('EntryExtractPlugin', () => {
   /** 校驗(yàn)頁(yè)面入口是否增加 */
   const pages = this.getPages();
   const diffPages = difference(pages, this.pages);
   const { length } = diffPages;
   if (length) {
    this.pages = this.pages.concat(diffPages);
    const entries = [];
    /** 通過(guò)新增的入口頁(yè)面建立依賴(lài) */
    diffPages.forEach((page) => void this.addDependencies(context, page, entries));
    /** 去除與原有依賴(lài)的交集 */
    const diffEntries = difference(entries, this.entries);
    diffEntries.forEach((entry) => {
     this.applyEntry(context, entry, `./${entry}`).apply(compiler);
    });
    this.entries = this.entries.concat(diffEntries);
   }
  });
 }
}

module.exports = EntryExtractPlugin;

由于webpack的plugin相關(guān)知識(shí)不在我們這篇文章的討論范疇,所以我只簡(jiǎn)單的介紹一下它是如何介入webpack的工作流程中并生成入口的。(如果有興趣想了解這些可以私信我,有時(shí)間的話可能會(huì)整理一些資料出來(lái)給大家)該插件實(shí)際做了兩件事:

  1. 通過(guò)compiler的entryOption鉤子,我們將遞歸生成的入口數(shù)組一項(xiàng)一項(xiàng)的加入entry中。
  2. 通過(guò)compiler的watchRun鉤子監(jiān)聽(tīng)重新編譯時(shí)是否有新的頁(yè)面加入,如果有就會(huì)以新加入的頁(yè)面生成一個(gè)依賴(lài)數(shù)組,然后再加入entry中。

現(xiàn)在我們將這個(gè)插件應(yīng)用到之前的webpack策略中,將上面的配置更改為:(記得安裝chalk replace-ext依賴(lài))

/** build/webpack.config.js */
const EntryExtractPlugin = require('./entry-extract-plugin');

module.exports = {
 ...
 entry: {
  app: './app.js'
 },
 plugins: [
  ...
  new EntryExtractPlugin()
 ]
}

樣式預(yù)編譯與EsLint

樣式預(yù)編譯和EsLint應(yīng)用其實(shí)已經(jīng)有許多優(yōu)秀的文章了,在這里我就只貼出我們的實(shí)踐代碼:

/** build/webpack.config.js */
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
 ...
 module: {
  rules: [
   ...
   {
    enforce: 'pre',
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'eslint-loader',
    options: {
     cache: true,
     fix: true,
    },
   },
   {
    test: /\.less$/,
    use: [
     {
      loader: MiniCssExtractPlugin.loader,
     },
     {
      loader: 'css-loader',
     },
     {
      loader: 'less-loader',
     },
    ],
   },
  ]
 },
 plugins: [
  ...
  new MiniCssExtractPlugin({ filename: '[name].wxss' })
 ]
}

我們修改完策略后就可以將wxss后綴名的文件更改為less后綴名(如果你想用其他的預(yù)編譯語(yǔ)言,可以自行修改loader),然后我們?cè)趈s文件中加入import './index.less'語(yǔ)句就能看到樣式文件正常編譯生成了。樣式文件能夠正常的生成最大的功臣就是mini-css-extract-plugin工具包,它幫助我們轉(zhuǎn)換了后綴名并且生成到目標(biāo)目錄中。

環(huán)境切換

環(huán)境變量的切換我們使用cross-env工具包來(lái)進(jìn)行配置,我們?cè)趐ackage.json文件中添加兩句腳本命令:

"scripts": {
 "dev": "cross-env OPERATING_ENV=development webpack --config build/webpack.config.js --watch",
 "build": "cross-env OPERATING_ENV=production webpack --config build/webpack.config.js
}

相應(yīng)的我們也修改一下webpack的配置文件,將我們應(yīng)用的環(huán)境也告訴webpack,這樣webpack會(huì)針對(duì)環(huán)境對(duì)代碼進(jìn)行優(yōu)化處理。

/** build/webpack.config.js */
const { OPERATING_ENV } = process.env;

module.exports = {
 ...
 mode: OPERATING_ENV,
 devtool: OPERATING_ENV === 'production' ? 'source-map' : 'inline-source-map'
}

雖然我們也可以通過(guò)命令為webpack設(shè)置mode,這樣也可以在項(xiàng)目中通過(guò)process.env.NODE_ENV訪問(wèn)環(huán)境變量,但是我還是推薦使用工具包,因?yàn)槟憧赡軙?huì)有多個(gè)環(huán)境uat test pre等等。

針對(duì)JS優(yōu)化

小程序?qū)Π拇笮∮袊?yán)格的要求,單個(gè)包的大小不能超過(guò)2M,所以我們應(yīng)該對(duì)JS做進(jìn)一步的優(yōu)化,這有利于我們控制包的大小。我所做的優(yōu)化主要針對(duì)runtime和多個(gè)入口頁(yè)面之間引用的公共部分,修改配置文件為:

/** build/webpack.config.js */
module.exports = {
 ...
 optimization: {
  splitChunks: {
   cacheGroups: {
    commons: {
     chunks: 'initial',
     name: 'commons',
     minSize: 0,
     maxSize: 0,
     minChunks: 2,
    },
   },
  },
  runtimeChunk: {
   name: 'manifest',
  },
 },
}

webpack會(huì)將公共的部分抽離出來(lái)在dist文件夾根目錄中生成common.js和manifest.js文件,這樣整個(gè)項(xiàng)目的體積就會(huì)有明顯的縮小,但是你會(huì)發(fā)現(xiàn)當(dāng)我們運(yùn)行命令是開(kāi)發(fā)者工具里面項(xiàng)目其實(shí)是無(wú)法正常運(yùn)行的,這是為什么?

這主要是因?yàn)檫@種優(yōu)化使小程序其他的js文件丟失了對(duì)公共部分的依賴(lài),我們對(duì)webpack配置文件做如下修改就可以解決了:

/** build/webpack.config.js */
module.exports = {
 ...
 output: {
  ...
  globalObject: 'global'
 },
 plugins: [
  new webpack.BannerPlugin({
   banner: 'const commons = require("./commons");\nconst runtime = require("./runtime");',
   raw: true,
   include: 'app.js',
  })
 ]
}

小小解惑

許多讀者可能會(huì)有疑惑,為什么你不直接使用已有的框架進(jìn)行開(kāi)發(fā),這些能力已經(jīng)有許多框架支持了。選擇框架確實(shí)是一個(gè)不錯(cuò)的選擇,畢竟開(kāi)箱即用為開(kāi)發(fā)者帶來(lái)了許多便利。但是這個(gè)選擇是有利有弊的,我也對(duì)市面上的較流行框架做了一段時(shí)間的研究和實(shí)踐。較為早期的騰訊的wepy、美團(tuán)的mpvue,后來(lái)者居上的京東的taro、Dcloud的uni-app等,這些在應(yīng)用當(dāng)中我認(rèn)為有以下一些點(diǎn)不受我青睞:

  • 黑盒使我們有時(shí)很難定位問(wèn)題究竟是出在自身的代碼當(dāng)中還是在框架的編譯流程中(這讓我踩了不少坑)
  • 圍繞框架展開(kāi)的可以使用的資源有限,例如UI的使用基本依賴(lài)于官方團(tuán)隊(duì)進(jìn)行配套開(kāi)發(fā),如果沒(méi)有社區(qū)也極難找到需要的資源(這一點(diǎn)我認(rèn)為uni-app的社區(qū)做得挺不錯(cuò))
  • 與已有的一些原生的資源無(wú)法結(jié)合,這些框架基本都是基于編譯原理提供了以react或者vue為開(kāi)發(fā)語(yǔ)言的能力,這使得原生的資源要無(wú)縫接入很難實(shí)現(xiàn)(假如你們公司已經(jīng)積淀了一些業(yè)務(wù)組件那你會(huì)很頭疼)。
  • 最后一點(diǎn),也是我擔(dān)心的最重要的一點(diǎn),框架的升級(jí)速度是否能跟得上官方的迭代速度,如果滯后了已有的項(xiàng)目該如何處理

以上基本是我為什么要自己探索小程序工程化的理由(其實(shí)還有一點(diǎn)就是求知欲,嘻嘻)

寫(xiě)在最后

以上是我對(duì)原生小程序工程化的探索,在我所在的團(tuán)隊(duì)中還應(yīng)用了一些相關(guān)的樣式規(guī)范,在這篇文章中我沒(méi)有具體的說(shuō),有興趣的話可以查看我的專(zhuān)欄中《團(tuán)隊(duì)規(guī)范之樣式規(guī)范實(shí)踐》一文。其實(shí)還有靜態(tài)資源的管理,項(xiàng)目的目錄的補(bǔ)充這些細(xì)節(jié)可以依照?qǐng)F(tuán)隊(duì)的需要去完善補(bǔ)充。本文希望對(duì)有需要做這方面實(shí)踐的團(tuán)隊(duì)有所幫助,如有觀點(diǎn)不正確或需要改進(jìn)的地方,望可以評(píng)論告知我。

到此這篇關(guān)于詳解微信小程序工程化探索之webpack實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)小程序 webpack 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • javascript 星級(jí)評(píng)分效果(手寫(xiě))

    javascript 星級(jí)評(píng)分效果(手寫(xiě))

    今天上午抽空隨手寫(xiě)了個(gè)星級(jí)評(píng)分的效果,給大家分享下。由于水平有限,如有問(wèn)題請(qǐng)指出;首先要準(zhǔn)備一張星星的圖片,灰色是默認(rèn)狀態(tài),黃色是選擇狀態(tài),需要的朋友可以參考下
    2012-12-12
  • js 本地預(yù)覽的簡(jiǎn)單實(shí)現(xiàn)方法

    js 本地預(yù)覽的簡(jiǎn)單實(shí)現(xiàn)方法

    本篇文章主要是對(duì)js本地預(yù)覽的簡(jiǎn)單實(shí)現(xiàn)方法進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2014-02-02
  • 微信小程序 網(wǎng)絡(luò)通信實(shí)現(xiàn)詳解

    微信小程序 網(wǎng)絡(luò)通信實(shí)現(xiàn)詳解

    這篇文章主要介紹了微信小程序 網(wǎng)絡(luò)通信實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • JavaScript中判斷變量是數(shù)組、函數(shù)或是對(duì)象類(lèi)型的方法

    JavaScript中判斷變量是數(shù)組、函數(shù)或是對(duì)象類(lèi)型的方法

    這篇文章主要介紹了JavaScript中判斷變量是數(shù)組、函數(shù)或是對(duì)象類(lèi)型的方法,需要的朋友可以參考下
    2015-02-02
  • OpenLayer學(xué)習(xí)之自定義測(cè)量控件

    OpenLayer學(xué)習(xí)之自定義測(cè)量控件

    這篇文章主要為大家詳細(xì) 介紹了OpenLayer學(xué)習(xí)之自定義測(cè)量控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • 史上最全JavaScript數(shù)組去重的十種方法(推薦)

    史上最全JavaScript數(shù)組去重的十種方法(推薦)

    這篇文章主要介紹了JavaScript數(shù)組去重的十種方法,利用元素的屬性和特性進(jìn)行不同的去重方法,并實(shí)例演示如何測(cè)試去重超大數(shù)組,具體操作步驟大家可查看下文的詳細(xì)講解,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • 在微信小程序中使用iconfont的最新圖文教程

    在微信小程序中使用iconfont的最新圖文教程

    由于微信小程序線上的資源限制了各種接口安全域名,所以在小程序里如果想使用iconfont字體圖標(biāo)就會(huì)稍有不同,下面這篇文章主要給大家介紹了關(guān)于在微信小程序中使用iconfont的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • 關(guān)于JavaScript 的事件綜合分析

    關(guān)于JavaScript 的事件綜合分析

    js下比較常用的方法,事件函數(shù)代碼。
    2010-08-08
  • uniapp組件uni-popup彈出層的使用

    uniapp組件uni-popup彈出層的使用

    彈出層組件用于彈出一個(gè)覆蓋到頁(yè)面上的內(nèi)容,本文主要介紹了uniapp組件uni-popup彈出層的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • json字符串對(duì)象轉(zhuǎn)換代碼實(shí)例

    json字符串對(duì)象轉(zhuǎn)換代碼實(shí)例

    這篇文章主要介紹了json字符串對(duì)象轉(zhuǎn)換代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09

最新評(píng)論