為何捐款
API 瀏覽器
Other Utils

提示

關於 UMD 建置的使用方式,請參閱這裡

openURL

import { openURL } from 'quasar'

openURL('http://...')

// full syntax:
openURL(
  String url,
  Function rejectFn, // optional; gets called if window cannot be opened
  Object windowFeatures // optional requested features for the new window
)

它會處理在 Cordova、Electron 或瀏覽器下執行時所涉及的怪異之處,包括通知使用者他們必須確認開啟彈出視窗。

當使用 Cordova (或 Capacitor) 包裝時,如果也安裝了 InAppBrowser Cordova 插件,以便 openURL 可以掛鉤到它,那是最好的 (但不是「必須做」的)。

如果在 iOS 上執行且安裝了 cordova-plugin-safariviewcontroller,則 openURL 將首先嘗試掛鉤到它。

可選的 windowFeatures 參數應該是一個物件,其鍵來自 window.open() windowFeatures 和布林值 (如下例所述)。 請注意,當 openURL 不延遲使用 window.open() 時,將不會考慮這些功能。

具有 windowFeatures 的 openURL() 範例

openURL(
  'http://...',
  undefined, // in this example we don't care about the rejectFn()

  // this is the windowFeatures Object param:
  {
    noopener: true, // this is set by default for security purposes
                    // but it can be disabled if specified with a Boolean false value
    menubar: true,
    toolbar: true,
    noreferrer: true,
    // .....any other window features
  }
)

提示

如果您想在 Cordova 應用程式中開啟電話撥號器,請勿使用 openURL()。 相反地,您應該直接使用 <a href="tel:123456789"> 標籤或 <QBtn href="tel:123456789">

copyToClipboard

以下是將一些文字複製到剪貼簿的輔助方法。 此方法會傳回 Promise。

import { copyToClipboard } from 'quasar'

copyToClipboard('some text')
  .then(() => {
    // success!
  })
  .catch(() => {
    // fail
  })

exportFile

以下是觸發瀏覽器開始下載具有指定內容的檔案的輔助方法。

/**
 * Forces browser to download file with specified content
 *
 * @param {*} fileName - String
 * @param {*} rawData - String | ArrayBuffer | ArrayBufferView | Blob
 * @param {*} opts - String (mimeType) or Object
 *                   Object form: { mimeType?: String, byteOrderMark?: String | Uint8Array, encoding?: String }
 * @returns Boolean | Error
 */

opts 參數是選填的,可以是字串 (mimeType) 或具有以下形式的物件

範例

import { exportFile } from 'quasar'

const status = exportFile('important.txt', 'some content')

if (status === true) {
  // browser allowed it
}
else {
  // browser denied it
  console.log('Error: ' + status)
}
import { exportFile } from 'quasar'

const status = exportFile('file.csv', 'éà; ça; 12\nà@€; çï; 13', {
  encoding: 'windows-1252',
  mimeType: 'text/csv;charset=windows-1252;'
})

if (status === true) {
  // browser allowed it
}
else {
  // browser denied it
  console.error('Error: ' + status)
}

runSequentialPromises
v2.8.4+

以下是依序執行多個 Promise 的輔助方法。 選填,可在多個執行緒上執行。

/**
 * Run a list of Promises sequentially, optionally on multiple threads.
 *
 * @param {*} sequentialPromises - Array of Functions or Object with Functions as values
 *                          Array of Function form: [ (resultAggregator: Array) => Promise<any>, ... ]
 *                          Object form: { [key: string]: (resultAggregator: object) => Promise<any>, ... }
 * @param {*} opts - Optional options Object
 *                   Object form: { threadsNumber?: number, abortOnFail?: boolean }
 *                   Default: { threadsNumber: 1, abortOnFail: true }
 *                   When configuring threadsNumber AND using http requests, be
 *                       aware of the maximum threads that the hosting browser
 *                       supports (usually 5); any number of threads above that
 *                       won't add any real benefits
 * @returns Promise<Array<Object> | Object>
 *    With opts.abortOnFail set to true (which is default):
 *        When sequentialPromises param is Array:
 *          The Promise resolves with an Array of Objects of the following form:
 *             [ { key: number, status: 'fulfilled', value: any }, ... ]
 *          The Promise rejects with an Object of the following form:
 *             { key: number, status: 'rejected', reason: Error, resultAggregator: array }
 *        When sequentialPromises param is Object:
 *          The Promise resolves with an Object of the following form:
 *             { [key: string]: { key: string, status: 'fulfilled', value: any }, ... }
 *          The Promise rejects with an Object of the following form:
 *             { key: string, status: 'rejected', reason: Error, resultAggregator: object }
 *    With opts.abortOnFail set to false:
 *       The Promise is never rejected (no catch() needed)
 *       The Promise resolves with:
 *          An Array of Objects (when sequentialPromises param is also an Array) of the following form:
 *             [ { key: number, status: 'fulfilled', value: any } | { status: 'rejected', reason: Error }, ... ]
 *          An Object (when sequentialPromises param is also an Object) of the following form:
 *             { [key: string]: { key: string, status: 'fulfilled', value: any } | { key: string, status: 'rejected', reason: Error }, ... }
 */

請注意

  • sequentialPromises 參數是一個函數陣列 (每個函數都會傳回 Promise)
  • sequentialPromises 中的每個函數都會接收一個參數,即 resultAggregator,因此基本上您可以使用先前 Promise 的結果來決定如何處理目前的 Promise; resultAggregator 中尚未解決的每個條目都會標記為 null
  • opts 參數是選填的。

通用範例 (使用陣列形式的 sequentialPromises 參數)

import { runSequentialPromises } from 'quasar'

runSequentialPromises([
  (resultAggregator) => new Promise((resolve, reject) => { /* do some work... */ }),
  (resultAggregator) => new Promise((resolve, reject) => { /* do some work... */ })
  // ...
]).then(resultAggregator => {
  // resultAggregator is ordered in the same way as the promises above
  console.log('result from first Promise:', resultAggregator[0].value)
  console.log('result from second Promise:', resultAggregator[1].value)
  // ...
}).catch(errResult => {
  console.error(`Error encountered on job #${ errResult.key }:`)
  console.error(errResult.reason)
  console.log('Managed to get these results before this error:')
  console.log(errResult.resultAggregator)
})

通用範例 (使用物件形式的 sequentialPromises 參數)

import { runSequentialPromises } from 'quasar'

runSequentialPromises({
  phones: (resultAggregator) => new Promise((resolve, reject) => { /* do some work... */ }),
  laptops: (resultAggregator) => new Promise((resolve, reject) => { /* do some work... */ })
  // ...
}).then(resultAggregator => {
  console.log('result from first Promise:', resultAggregator.phones.value)
  console.log('result from second Promise:', resultAggregator.laptops.value)
  // ...
}).catch(errResult => {
  console.error(`Error encountered on job (${ errResult.key}):`)
  console.error(errResult.reason)
  console.log('Managed to get these results before this error:')
  console.log(errResult.resultAggregator)
})

使用先前結果的範例

import { runSequentialPromises } from 'quasar'

runSequentialPromises({
  phones: () => new Promise((resolve, reject) => { /* do some work... */ }),
  vendors: (resultAggregator) => {
    new Promise((resolve, reject) => {
      // You can do something with resultAggregator.phones.value here...
      // Since are using the default abortOnFail option, the result is guaranteed to exist,
      // so you don't have to guard resultAggregator.phones against "null"
    })
  }
  // ...
})

使用 Axios 的範例

import { runSequentialPromises } from 'quasar'
import axios from 'axios'

const keyList = [ 'users', 'phones', 'laptops' ]

runSequentialPromises([
  () => axios.get('https://some-url.com/users'),
  () => axios.get('https://some-other-url.com/items/phones'),
  () => axios.get('https://some-other-url.com/items/laptops')
]).then(resultAggregator => {
  // resultAggregator is ordered in the same way as the promises above
  resultAggregator.forEach(result => {
    console.log(keyList[ result.key ], result.value) // example: users {...}
  })
}).catch(errResult => {
  console.error(`Error encountered while fetching ${ keyList[ errResult.key ] }:`)
  console.error(errResult.reason)
  console.log('Managed to get these results before this error:')
  console.log(errResult.resultAggregator)
})

// **equivalent** example with sequentialPromises as Object:

runSequentialPromises({
  users: () => axios.get('https://some-url.com/users'),
  phones: () => axios.get('https://some-other-url.com/items/phones'),
  laptops: () => axios.get('https://some-other-url.com/items/laptops')
}).then(resultAggregator => {
  console.log('users:', resultAggregator.users.value)
  console.log('phones:', resultAggregator.phones.value)
  console.log('laptops:', resultAggregator.laptops.value)
}).catch(errResult => {
  console.error(`Error encountered while fetching ${ errResult.key }:`)
  console.error(errResult.reason)
  console.log('Managed to get these results before this error:')
  console.log(errResult.resultAggregator)
})

將 abortOnFail 設定為 false 的範例

import { runSequentialPromises } from 'quasar'
import axios from 'axios'

// notice no "catch()"; runSequentialPromises() will always resolve
runSequentialPromises(
  {
    users: () => axios.get('https://some-url.com/users'),
    phones: () => axios.get('https://some-other-url.com/items/phones'),
    laptops: () => axios.get('https://some-other-url.com/items/laptops')
  },
  { abortOnFail: false }
).then(resultAggregator => {
  Object.values(resultAggregator).forEach(result => {
    if (result.status === 'rejected') {
      console.log(`Failed to fetch ${ result.key }:`, result.reason)
    }
    else {
      console.log(`Succeeded to fetch ${ result.key }:`, result.value)
    }
  })
})

當設定 threadsNumber (opts > threadsNumber) 且使用 http 請求時,請注意託管瀏覽器支援的最大執行緒數 (通常為 5)。 超過該數量的執行緒不會增加任何實際好處。

import { runSequentialPromises } from 'quasar'

runSequentialPromises([ /* ... */ ], { threadsNumber: 3 })
  .then(resultAggregator => {
    resultAggregator.forEach(result => {
      console.log(result.value)
    })
  })
  .catch(errResult => {
    console.error(`Error encountered:`)
    console.error(errResult.reason)
    console.log('Managed to get these results before this error:')
    console.log(errResult.resultAggregator)
  })

debounce

如果您的應用程式使用 JavaScript 來完成繁重的工作,則 debounce 函數對於確保給定任務不會過於頻繁地觸發以致於損壞瀏覽器效能至關重要。 Debounce 函數會限制函數可以觸發的速率。

Debounce 強制要求在經過一定時間而未再次呼叫函數之前,不得再次呼叫該函數。 例如「僅在未呼叫函數的情況下經過 100 毫秒後才執行此函數」。

一個快速範例:您在視窗上具有一個 resize 監聽器,它會執行一些元素尺寸計算並 (可能) 重新定位一些元素。 這本身並不是繁重的工作,但是如果在一連串調整大小後重複觸發,確實會降低應用程式的速度。 那麼為什麼不限制函數可以觸發的速率呢?

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
import { debounce } from 'quasar'

(Debounced Function) debounce(Function fn, Number milliseconds_to_wait, Boolean immediate)

// Example:
window.addEventListener(
  'resize',
  debounce(function() {
    // .... things to do ...
  }, 300 /*ms to wait*/)
)

或在 .vue 檔案中作為方法呼叫

methods: {
  myMethod () { .... }
},

created () {
  this.myMethod = debounce(this.myMethod, 500)
}

警告

使用方法宣告 (例如 myMethod: debounce(function () { // Code }, 500)) debounce 您的函數,表示 debounce 方法將在元件的所有已呈現執行個體之間共用,因此 debounce 也會共用。 此外,this.myMethod.cancel() 將無法運作,因為 Vue 會使用另一個函數包裝每個方法,以確保正確的 this 繫結。 應避免這種情況,方法是遵循上面的程式碼片段。

還有一個 frameDebounce 可用,它會延遲呼叫您的函數,直到排定執行下一個瀏覽器畫面 (請參閱 requestAnimationFrame)。

import { frameDebounce } from 'quasar'

(Debounced Function) frameDebounce(Function fn)

// Example:
window.addEventListener(
  'resize',
  frameDebounce(function() {
    .... things to do ...
  })
)

throttle

Throttle 強制執行函數在一段時間內可以呼叫的最大次數。 例如「最多每 X 毫秒執行此函數一次」。

import { throttle } from 'quasar'

(Throttled Function) throttle(Function fn, Number limit_in_milliseconds)

// Example:
window.addEventListener(
  'resize',
  throttle(function() {
    .... things to do ...
  }, 300 /* execute at most once every 0.3s */)
)

或在 .vue 檔案中作為方法呼叫

methods: {
  myMethod () { .... }
},

created () {
  this.myMethod = throttle(this.myMethod, 500)
}

警告

使用方法宣告 (例如 myMethod: throttle(function () { // Code }, 500)) throttle 您的函數,表示 throttle 方法將在元件的所有已呈現執行個體之間共用,因此 throttle 也會共用。 應避免這種情況,方法是遵循上面的程式碼片段。

extend - (深度) 複製物件

jQuery.extend() 的基本重新產生。 採用相同的參數

import { extend } from 'quasar'

let newObject = extend([Boolean deepCopy], targetObj, obj, ...)

注意物件內的方法。

uid - 產生 UID

產生唯一識別碼

import { uid } from 'quasar'

let uid = uid()
// Example: 501e7ae1-7e6f-b923-3e84-4e946bff31a8

testPattern

針對特定模式進行測試。

import { patterns } from 'quasar'

const { testPattern } = patterns

testPattern.email('foo@bar.com') // true
testPattern.email('foo') // false

testPattern.hexColor('#fff') // true
testPattern.hexColor('#ffffff') // true
testPattern.hexColor('#FFF') // true
testPattern.hexColor('#gggggg') // false

在此處查看完整的模式列表