openURL(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 或浏览器上运行时可能遇到的问题,包括通知用户需要确认是否打开了弹窗。
¥It will take care of the quirks involved when running under Cordova, Electron or on a browser, including notifying the user he/she has to acknowledge opening popups.
使用 Cordova(或 Capacitor)打包时,最好(但不是 “一个必须执行的操作”)同时安装 InAppBrowser Cordova 插件,以便 openURL 可以挂载到该插件。
¥When wrapping with Cordova (or Capacitor), it’s best (but not “a must do”) if InAppBrowser Cordova plugin is also installed, so that openURL can hook into that.
如果在 iOS 上运行并且安装了 cordova-plugin-safariviewcontroller,则 openURL 将首先尝试挂载到它。
¥If running on iOS and cordova-plugin-safariviewcontroller is installed, then openURL will first try to hook into it.
可选的 windowFeatures
参数应该是一个包含 window.open() windowFeatures 键和布尔值的对象(如下例所示)。请注意,当 openURL 不遵循使用 window.open()
时,这些功能将不被考虑。
¥The optional windowFeatures
parameter should be an Object with keys from window.open() windowFeatures and Boolean values (as described in the example below). Please note that these features will not be taken into account when openURL does not defers to using window.open()
.
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">
标签。
¥If you want to open the telephone dialer in a Cordova app, don’t use openURL()
. Instead you should directly use <a href="tel:123456789">
tags or <QBtn href="tel:123456789">
copyToClipboard(copyToClipboard)
以下是一个辅助程序,用于将一些文本复制到剪贴板。该方法返回一个 Promise。
¥The following is a helper to copy some text to Clipboard. The method returns a Promise.
import { copyToClipboard } from 'quasar'
copyToClipboard('some text')
.then(() => {
// success!
})
.catch(() => {
// fail
})
exportFile(exportFile)
以下是用于触发浏览器开始下载具有指定内容的文件的辅助方法。
¥The following is a helper to trigger the browser to start downloading a file with the specified content.
/**
* 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)或具有以下形式的对象:
¥The opts
parameter is optional and can be a String (mimeType) or an Object with the following form:
mimeType(可选)
¥mimeType (optional)
示例:‘application/octet-stream’(默认)、‘text/plain’、‘application/json’、‘text/plain;charset=UTF-8’、‘video/mp4’、‘image/png’、‘application/pdf’ https://web.nodejs.cn/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
¥Examples: ‘application/octet-stream’ (default), ‘text/plain’, ‘application/json’, ‘text/plain;charset=UTF-8’, ‘video/mp4’, ‘image/png’, ‘application/pdf’ https://web.nodejs.cn/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
byteOrderMark(可选)
¥byteOrderMark (optional)
(BOM)示例:‘\uFEFF’ https://en.wikipedia.org/wiki/Byte_order_mark
¥(BOM) Example: ‘\uFEFF’ https://en.wikipedia.org/wiki/Byte_order_mark
编码(可选)
¥encoding (optional)
对 rawData 执行 TextEncoder.encode();示例:‘windows-1252’(ANSI,ISO-8859-1 的子集)https://web.nodejs.cn/en-US/docs/Web/API/TextEncoder
¥Performs a TextEncoder.encode() over the rawData; Example: ‘windows-1252’ (ANSI, a subset of ISO-8859-1) https://web.nodejs.cn/en-US/docs/Web/API/TextEncoder
示例:
¥Examples:
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+(runSequentialPromises v2.8.4+)
以下是用于按顺序运行多个 Promise 的辅助方法。可选,在多个线程上执行。
¥The following is a helper to run multiple Promises sequentially. Optionally, on multiple threads.
/**
* 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 }, ... }
*/
注意:
¥Note that:
sequentialPromises
参数是一个函数数组(每个函数返回一个 Promise)。¥the
sequentialPromises
param is an Array of Functions (each Function returns a Promise)sequentialPromises
中的每个函数都接收一个参数,即resultAggregator
,因此基本上你可以使用先前promise的结果来决定如何处理当前promise;resultAggregator 中每个尚未完成的条目都标记为null
¥each function in
sequentialPromises
receives one param which is theresultAggregator
, so basically you can use the results of the previous promises to decide what to do with the current promise; each entry in the resultAggregator that hasn’t been settled yet is marked asnull
opts
参数是可选的。¥the
opts
parameter is optional.
通用示例(sequentialPromises
参数为数组):
¥Generic example (with sequentialPromises
param as Array):
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
参数为对象):
¥Generic example (with sequentialPromises
param as Object):
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)
})
使用先前结果的示例:
¥Example using previous results:
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 的示例:
¥Example with 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
的示例:
¥Example with abortOnFail set to 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)
}
})
})
配置线程数 (opts > threadsNumber
) 并使用 http 请求时,请注意托管浏览器支持的最大线程数(通常为 5)。超过此数量的线程不会带来任何实际好处。
¥When configuring threadsNumber (opts > 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.
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(debounce)
如果你的应用使用 JavaScript 来完成繁重的任务,那么防抖动功能对于确保给定任务不会过于频繁地触发而导致浏览器性能下降至关重要。去抖动功能会限制函数的触发频率。
¥If your App uses JavaScript to accomplish taxing tasks, a debounce function is essential to ensuring a given task doesn’t fire so often that it bricks browser performance. Debouncing a function limits the rate at which the function can fire.
去抖动功能会强制要求函数在一段时间内未被调用后才会再次被调用。与 “仅当 100 毫秒内未调用此函数时才执行此函数。” 相同
¥Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in “execute this function only if 100 milliseconds have passed without it being called.”
快速示例:你在窗口上有一个调整大小的监听器,它可以执行一些元素尺寸计算,并(可能)重新定位一些元素。这本身并不是一项繁重的任务,但在多次调整大小后反复触发会严重拖慢你的应用速度。那么为什么不限制函数的触发频率呢?
¥A quick example: you have a resize listener on the window which does some element dimension calculations and (possibly) repositions a few elements. That isn’t a heavy task in itself but being repeatedly fired after numerous resizes will really slow your App down. So why not limit the rate at which the function can fire?
// 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 文件中调用方法:
¥Or calling as a method in a .vue file:
methods: {
myMethod () { .... }
},
created () {
this.myMethod = debounce(this.myMethod, 500)
}
警告
使用类似 myMethod: debounce(function () { // Code }, 500)
的方法声明来对函数进行去抖动处理,意味着已去抖动处理的方法将在该组件的所有渲染实例之间共享,因此去抖动处理也将共享。此外,this.myMethod.cancel()
无法工作,因为 Vue 将每个方法用另一个函数封装,以确保正确的 this
绑定。可以通过遵循上面的代码片段来避免这种情况。
¥Debouncing your functions using a method declaration like myMethod: debounce(function () { // Code }, 500)
will mean that the debounced method will be shared between all rendered instances of this component, so debouncing is also shared. Moreover, this.myMethod.cancel()
won’t work, because Vue wraps each method with another function to ensure proper this
binding. This should be avoided by following the code snippet above.
还有一个可用的 frameDebounce
指令,它会将调用你的函数延迟到下一个浏览器框架计划运行(阅读有关 requestAnimationFrame
的信息)。
¥There’s also a frameDebounce
available which delays calling your function until next browser frame is scheduled to run (read about requestAnimationFrame
).
import { frameDebounce } from 'quasar'
(Debounced Function) frameDebounce(Function fn)
// Example:
window.addEventListener(
'resize',
frameDebounce(function() {
.... things to do ...
})
)
throttle(throttle)
节流会强制执行函数在一段时间内被调用的最大次数。与 “最多每 X 毫秒执行一次此函数。” 相同
¥Throttling enforces a maximum number of times a function can be called over time. As in “execute this function at most once every X milliseconds.”
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 文件中调用方法:
¥Or calling as a method in a .vue file:
methods: {
myMethod () { .... }
},
created () {
this.myMethod = throttle(this.myMethod, 500)
}
警告
使用像 myMethod: throttle(function () { // Code }, 500)
这样的方法声明来节流函数意味着被节流的方法将在该组件的所有渲染实例之间共享,因此节流也会被共享。可以通过遵循上面的代码片段来避免这种情况。
¥Throttling your functions using a method declaration like myMethod: throttle(function () { // Code }, 500)
will mean that the throttled method will be shared between all rendered instances of this component, so throttling is also shared. This should be avoided by following the code snippet above.
extend - (深度)复制对象(extend - (Deep) Copy Objects)
¥extend - (Deep) Copy Objects
jQuery.extend()
的基本重生。采用相同参数:
¥A basic respawn of jQuery.extend()
. Takes same parameters:
import { extend } from 'quasar'
let newObject = extend([Boolean deepCopy], targetObj, obj, ...)
注意对象中的方法。
¥Watch out for methods within objects.
uid - 生成 UID(uid - Generate UID)
¥uid - Generate UID
生成唯一标识符:
¥Generate unique identifiers:
import { uid } from 'quasar'
let uid = uid()
// Example: 501e7ae1-7e6f-b923-3e84-4e946bff31a8
testPattern(testPattern)
针对特定模式进行测试。
¥Test against particular patterns.
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
查看 此处 模式的完整列表。
¥See the full list of patterns here.