为什么捐赠
API 浏览器
联系站长
升级指南

Quasar CLI 支持 Vite 和 Webpack

现在你可以在 Quasar CLI with Vite 和 Quasar CLI with Webpack 之间自由选择。

组合式 API 和选项式 API

你会注意到我们所有的文档示例都使用了 Vue 3 的组合式 API(Composition API)。但这并不意味着你不能使用 Vue 选项式 API(Options API)。恰恰相反,在升级过程中保留选项式 API 实际上会让升级之路更加轻松。升级完成后我们建议你切换到组合式 API,但这绝不是强制要求。

视频教程

点击下面的海报将打开一个 Youtube 播放列表,介绍如何将 Quasar CLI 项目从 Quasar v1 升级到 Quasar v2。随着 Quasar v2 的持续更新,视频内容可能会有些滞后,但它可以帮助你入门。

从 v2 旧版本升级到最新版本

UMD 版本

只需将引用 Quasar 的所有 CSS 和 JS 标签中的版本号替换为更新的版本即可。

Quasar CLI 版本

# 在 Quasar UI v2 项目中运行以下命令

# 检查可更新的 Quasar 相关包
$ quasar upgrade

# 执行实际升级
$ quasar upgrade --install

建议同时更新 vuevue-router 到最新版本:


# 可选但推荐
$ yarn add vue@3 vue-router@4

注意代码编辑器的终端

如果你使用代码编辑器内置的终端运行 quasar upgrade 命令时遇到 Command not found@quasar/cli 版本显示为 undefined 的错误,你需要进入代码编辑器终端的设置,取消勾选 Add ‘node_modules/.bin’ from the project root to %PATH% 选项(或类似选项),然后重启代码编辑器。

Quasar Vite 插件版本

$ yarn upgrade quasar
# 或使用其他包管理器的等效命令

可选:确保你安装了最新的 @quasar/vite-plugin 包。

建议同时更新 vue@quasar/extras


# 可选但推荐
$ yarn add vue@3 @quasar/extras@latest

从 v1 迁移到 v2

本指南针对 Quasar CLI 和 UMD 项目,但其中的信息也适用于 Vue CLI 项目。如果你已经在项目中使用了 Vue CLI,可以查看如何安装与 Quasar v2 配合使用的 vue-cli-plugin-quasar 包。你还需要对 main.js 进行一些修改(并将 Vue CLI 项目升级到支持 Vue 3)——目前最好的方式是生成一个新的 Vue 3 Vue CLI 项目,然后按照 vue-cli-plugin-quasar 的安装步骤操作,查看 /src 文件夹发生的变化,然后将同样的原则应用到你当前的 Vue CLI 项目中。

WARNING

  • Quasar CLI v1 只支持 Webpack。但现在你可以在 Quasar CLI with Vite 和 Quasar CLI with Webpack 之间选择。
  • 本指南的剩余部分将重点介绍 Quasar CLI with Webpack。

WARNING

本指南介绍的是转换/升级到 @quasar/app-webpack v3 和 @quasar/app-vite v1 的项目,但这两个版本都已不是最新版了。这意味着你需要先转换到 q/app-webpack v3,然后再升级到更新的版本。

你当前正在阅读的文档网站的其他所有页面都指向最新版本的 q/app-vite 和 q/app-webpack。旧版 q/app-webpack 或 q/app-vite 的文档在这里

升级到最新 CLI 版本的链接(在你完成本页面的所有内容之后再处理):


完成本页面的内容后,我们建议你最终切换到更优秀的 Quasar CLI with Vite(q/app-vite)。步骤如下:
  1. 按照本页面操作。
  2. 升级到最新的 q/app-webpack v4(升级指南
  3. 从 q/app-webpack 转换到 q/app-vite(转换到 App CLI with Vite

简介

我们投入了大量工作,使从 Quasar v1 到 v2 的过渡尽可能轻松。不要被本页面的长度吓到,这并不反映你升级到 Quasar v2 所需的实际工作量(我们只是尽力让内容尽可能完整)。Quasar 组件、指令和插件的 API 变化很小,我们将破坏性更改控制在了最低限度。同时我们还为一些组件添加了很酷的新功能。

Quasar UI v2 基于 Vue 3,而之前的版本基于 Vue 2。这意味着你的应用代码(Vue 组件、指令等)也必须兼容 Vue 3,而不仅仅是 Quasar UI 源码。如果你在应用中使用了其他库,请确保使用它们的 Vue 3 版本。

Quasar UI v2 不仅仅是移植到 Vue 3 和组合式 API。Quasar 的算法也有大量显著的性能提升! 你一定会爱上它的!

重要!

  • 不再支持 IE11——Vue 3 也不支持 IE11。如果你的项目必须支持 IE11,请继续使用 Quasar UI v1。
  • 为了支持 Node.js v13+(以及获得诸多其他好处),我们将 Webpack 从 v4 升级到了 v5。你可能需要相应地升级你的 webpack 插件。
  • Quasar Stylus 变量不再可用(仅支持 Sass/SCSS)。但这并不意味着你不能再使用 Stylus。
  • 请确保将 Node.js 更新到至少 v22,并相应地更新系统上的 npm/yarn 以满足新的约束条件,其中包含最新已知安全问题的修复。此 Node.js 版本还包含原生 ESM 模块支持,这将帮助我们在 Quasar v2 生命周期内进一步现代化 Quasar 代码库底层,且不会造成破坏性更改。

在开始从 v1 升级到 v2 之前,你还需要了解以下几点:

  1. 在 Discord 服务器或论坛提问之前,请先阅读文档。
  2. 如果你认为发现了问题,请准备一个 CodePen 以便工作人员帮助你。
  3. 深入研究 Quasar 源代码(这将帮助你理解框架,也能学习使用 Vue 编程的最佳实践)。
  4. 除非绝对必要,否则不要将框架组件用作 mixins(如果需要,请包装它们)。
  5. 除非绝对必要,否则不要使用 CSS 选择器定位组件内部内容。
  6. 我们推荐尽可能使用 yarn,因为它速度快且高效。但是,使用全局包时,我们仍然推荐使用 npm,特别是当你使用 nvm(Node 版本管理器)时。
  7. 使用 git 进行仓库管理并定期提交——就像是给过程做笔记,让你在遇到问题时可以回退到之前的状态。
  8. 使用 Quasar boot 文件处理任何应用挂载前的初始化逻辑。
  9. 最后,成为赞助者,获得特殊 Discord 支持聊天室的访问权限以获得优先支持。这也有助于项目的持续发展。

如果你遇到困难,请查看论坛或访问我们的 Discord 服务器寻求帮助,帮助不仅来自工作人员,也来自社区。

信息

我们已经尽最大努力确保升级文档中的所有内容都是正确的。但由于这是一个手动过程,难免存在错误。如果你发现了任何问题,请大胆提交 PR 并提出修改建议。

初始步骤

你可以选择以下两条路径,选择最适合你需求的那条。不过我们推荐第一个选项。

选项 1:转换现有项目

重要!

本指南假设你当前使用的是 @quasar/app v2 项目。你将把它升级到 Quasar CLI with Webpack 的 Quasar v2 版本(包名现在是 @quasar/app-webpack,以便更好地与 Quasar CLI with Vite 区分)。

在开始之前,强烈建议你复制当前的工作项目或使用 git 创建新分支。

  1. 确保安装最新版本的 @quasar/cli

$ yarn global add @quasar/cli@latest
  1. Stylus 相关:你是否在使用 Stylus 和 Quasar Stylus 变量?如果是,请先将所有相关文件转换为 Sass/SCSS(包括 src/css/app.styl -> src/css/app.sass 或 app.scss)。如果你仍想在项目中使用 Stylus(但不使用 Quasar Stylus 变量),则需要安装 stylus 相关包(“@quasar/app” 不再默认提供):

# 仅当你仍想使用 Stylus(但不使用 Quasar Stylus 变量)时
$ yarn add stylus stylus-loader
  1. 升级 Node.js 到至少 v22,npm 到至少 v6.14.12,yarn 到至少 v1.17.3。
# 如果你已经使用 lts/erbium 版本(例如 12.14.0),请记下其版本号,它应该列在 "lts/erbium" 行
$ nvm list

# 如果你在 Linux 上使用 `nvm`(https://github.com/nvm-sh/nvm)
$ nvm install 12.22.1 && nvm alias default lts/erbium && nvm use default
# 如果你在 Windows 上使用 `nvm`(https://github.com/coreybutler/nvm-windows)
$ nvm install 12.22.1 && nvm use 12.22.1

# 卸载之前的 "lts/erbium" 版本,假设之前安装的是 12.14.0
nvm uninstall 12.14.0
  1. 删除 .quasarnode_modules 文件夹和 package-lock.jsonyarn.lock 文件。这通常不是必需的,但在某些情况下可以避免 yarn/npm 升级包时出现问题。
  2. 卸载 @quasar/app

$ yarn remove @quasar/app
  1. 安装 @quasar/app-webpack v3、quasar v2、vue v3 和 vue-router v4 包(后两个不再由 @quasar/app 提供):

$ yarn add --dev @quasar/app-webpack@3
$ yarn add quasar@2 vue@3 vue-router@4
  1. 删除 .quasarnode_modules 文件夹,以及 package-lock.json / yarn.lock / pnpm-lock.yaml / bun.lock / bun.lockb 文件,然后运行 yarn/npm/pnpm/bun install 重新生成锁文件。这会强制升级整个依赖图(包括深层依赖),避免包不匹配的问题,尤其是与 webpack 5 相关的问题。
  2. 如果你使用 ESLint,请编辑 /.eslintrc.cjs(同时将 /.eslintrc.js 重命名):
// 旧方式
parserOptions: {
  parser: 'babel-eslint'
},
extends: [
  'plugin:vue/essential' // 或等效项
]

// 新方式
parserOptions: {
  parser: '@babel/eslint-parser'
},
extends: [
  'plugin:vue/vue3-essential' // 或等效项
]

同时升级 ESLint 依赖。示例:

"@babel/eslint-parser": "^7.13.14",  // 替换 babel-eslint!
"eslint": "^8.11.0",
"eslint-plugin-vue": "^10.8.0",
"eslint-webpack-plugin": "^3.1.1", // 替换 eslint-loader!
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-n": "^15.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-quasar": "^1.0.0",
"vue-eslint-parser": "^10.2.0"

/quasar.config 文件中,在 module.exports = function (ctx) 之前添加:

import ESLintPlugin from "eslint-webpack-plugin";

在 quasar.config 文件 > build 中添加:

chainWebpack (chain) {
  chain
    .plugin('eslint-webpack-plugin')
    .use(ESLintPlugin, [{ extensions: ['js', 'vue'] }])
}
  1. 如果你使用 Vuex,需要手动安装:

$ yarn add vuex@4
  1. 编辑 quasar.config 文件 > framework > lang。这将在本页面的"Quasar 语言包"部分详细解释。
// 旧方式
framework: {
  lang: "en-us";
}

// 新方式
framework: {
  lang: "en-US";
}
  1. 检查所有手动安装的 webpack 插件是否与 Webpack 5 兼容(大多数应该已经兼容)。同时更新 quasar.config 文件 > devServer 配置以匹配 webpack-dev-server v4
  2. 按照本指南的其余部分继续操作。你需要适应 Vue 3、Vue Router 4、Vuex 4、Vue-i18n 9 以及你所使用的其他 Vue 插件的破坏性更改。
  3. 升级你的其他项目依赖(特别是 ESLint 相关的依赖)。

选项 2:创建新项目

第二个选项是创建一个全新的项目,然后逐步将代码迁移过去。我们认为这是最后的手段(当你遇到的是 Vue 3 和 Vue Router v4 的问题而非 Quasar 本身的问题时),我们仅为了本指南的完整性而提到它。

你可以按如下方式生成新的 Quasar v2 项目,然后将应用迁移到其中:


$ yarn create quasar
# 选择 "App with Quasar CLI"
# 决定是否要使用 "Quasar CLI with Vite" 或 "Quasar CLI with Webpack"

Webpack v5

为了支持 Node.js v13+(以及获得诸多其他好处),我们将 Webpack 从 v4 升级到了 v5。你可能需要相应地升级你的 webpack 插件。

Node.js polyfills

Webpack v5 移除了 Web 客户端构建的 Node.js polyfills。如果你在 Web 客户端中使用了依赖 Node.js API 的包(它们本不应该这样做!),你会收到一些包缺失的错误。例如:Buffercryptoospath

这些问题需要由包的维护者来解决。但如果你不想等待,只想让应用/网站跑起来(有一定风险),那么你可以手动安装 node-polyfill-webpack-pluginyarn add --dev node-polyfill-webpack-plugin),然后在 quasar.config 文件 > build > chainWebpack 中引用它。示例:

// quasar.config file
import nodePolyfillWebpackPlugin from 'node-polyfill-webpack-plugin'

build: {
  chainWebpack (chain) {
    chain.plugin('node-polyfill').use(nodePolyfillWebpackPlugin)
  }
}

Webpack devserver

作为升级到 Webpack 5 的一部分,Quasar CLI 现在提供 webpack-dev-server v4webpack-dev-middleware v4,它们各自带有破坏性更改。这影响了 quasar.config 文件 > devServer 选项。以下是一些最常用的属性:

属性名类型说明
devMiddlewareObject提供给 webpack-dev-middleware v4 的配置
httpsBoolean/Object与 webpack 4 时相同
onBeforeSetupMiddlewareFunction替代 “before”
onAfterSetupMiddlewareFunction替代 “after”
proxyObject/Array与 webpack 4 时相同

TIP

如果你修改过 quasar.config 文件 > devServer,那么你可能会对 webpack-dev-server v4 的所有破坏性更改列表感兴趣:发布说明。检查是否有适用于你的更改。

webpack-chain

WARNING

在撰写本文时,webpack-chain 尚未完全更新以支持 Webpack 5。这影响了所有 quasar.config 文件 > chainWebpack{…} 方法。虽然这些方法仍然可用,但 Webpack 5 中引入的较新配置部分尚不可用。对于这些部分,应使用 extendWebpack* 方法,直到 webpack-chain 完全兼容 Webpack 5。

App.vue

你需要编辑 src/App.vue 并移除外层的 <div id="q-app">。你不再需要它了(也不应该保留它)。

<!-- 旧方式 -->
<template>
  <div id="q-app">
    <router-view />
  </div>
</template>

<!-- 新方式 -->
<template>
  <router-view />
</template>

Vue 3

既然你也会切换到 Vue 3,最好在阅读完本迁移指南之后也看看 Vue 3 的迁移指南

如果你使用 .vue 文件,迁移过程大概率会比较顺利,因为:1) vue-loader(由 @quasar/app 提供)负责解析 SFC 语法并告知 Vue 3 该做什么;2) 你仍然可以使用选项式 API(不过我们建议你转换到更新更好的组合式 API)。

我们建议你先保持选项式 API 不变,将项目迁移到 Quasar v2(因为你的组件已经是选项式 API 的形式,你可能想先确保一切正常运行)。迁移完成后,你可以将所有 Vue 组件转换为组合式 API,但这绝不是强制要求。

伴随 Vue 3 而来的还有 Vue Router v4 的全新大版本,它有自己的破坏性更改需要注意。另外还有新的 Vuex v4

Vue 3 破坏性更改示例

v-model 的变化

处理 Vue 3 时最重要的破坏性更改之一就是 v-model 的工作方式变了。它现在是 model-value + @update:model-value 的别名,而不再是 value + @input。这影响了所有使用 v-model 的 Quasar 组件。如果你在 .vue 文件中编写组件,就不用担心这个问题,因为 vue-loader 会为你正确转换。

另外,如果你从 Vue 组件中触发自定义事件,你需要像下面这样显式声明它们:

<script>
  // 你的 Vue 组件;
  // 假设我们从这个组件中触发 'ok' 和 'myEvent' 事件

  export default {
    // ...
    emits: ["ok", "myEvent"],
    // ...
  };
</script>
事件总线方法

另一个破坏性更改是事件总线方法($on、$once、$off、$emit)被移除了。不过 Quasar v2(v2.8.4+)提供了原生的替代方案:EventBus 工具

Vue Router v4

这是 Vue 3 生态的上游破坏性更改。你需要更新 src/router 文件以匹配 Vue Router v4 的 API。Vue Router v4 有自己的破坏性更改。请特别注意下面我们如何处理 404 错误。

Default src/router/index.js content:

import {
  createRouter,
  createMemoryHistory,
  createWebHistory,
  createWebHashHistory,
} from "vue-router";
import routes from "./routes";

export default function (/* { store, ssrContext } */) {
  const createHistory = process.env.SERVER
    ? createMemoryHistory
    : process.env.VUE_ROUTER_MODE === "history"
      ? createWebHistory
      : createWebHashHistory;

  const Router = createRouter({
    scrollBehavior: () => ({ left: 0, top: 0 }),
    routes,

    // 保持原样,在 quasar.config 文件中修改!
    // quasar.config file -> build -> vueRouterMode
    // quasar.config file -> build -> publicPath
    history: createHistory(process.env.VUE_ROUTER_BASE),
  });

  return Router;
}
Default src/router/routes.js content:

const routes = [
  {
    path: "/",
    component: () => import("layouts/MainLayout.vue"),
    children: [{ path: "", component: () => import("pages/Index.vue") }],
  },

  // 始终将此路由放在最后,
  // 但你也可以移除它
  {
    path: "/:catchAll(.*)*",
    component: () => import("pages/Error404.vue"),
  },
];

export default routes;

如果你使用 TypeScript,必须将 RouteConfig 接口替换为 RouteRecordRaw

Vuex v4

第一步是手动将 Vuex 安装到你的应用中。


$ yarn add vuex@4

这是 Vue 3 生态的上游破坏性更改。你需要更新 src/store 文件以匹配 Vuex v4 的 API。请注意下面示例中从 vuex 导入的 “createStore” 及其用法。参考资料:Vuex 从 3.x 迁移到 4.0

Default src/store/index.js content:

import { createStore } from "vuex";
// import example from './module-example'

export default function (/* { ssrContext } */) {
  const Store = createStore({
    modules: {
      // example
    },

    // 启用严格模式(会增加开销!)
    // 仅在开发模式和 --debug 构建中使用
    strict: process.env.DEBUGGING,
  });

  return Store;
}

Vue-i18n v9

这是 Vue 3 生态的上游破坏性更改。更新 src/boot/i18n.js 文件以匹配 Vue-i18n v9 的 API。Vue-i18n 有自己的破坏性更改

由于此包不由 @quasar/app 提供,你必须通过 yarn add vue-i18n 更新项目中的依赖。

Default src/boot/i18n.js content:

import { createI18n } from "vue-i18n";
import messages from "src/i18n";
// 你还需要创建 src/i18n/index.js/.ts 文件

export default ({ app }) => {
  // 创建 I18n 实例
  const i18n = createI18n({
    locale: "en-US",
    globalInjection: true,
    messages,
  });

  // 让应用使用 I18n 实例
  app.use(i18n);
};

如果你使用 TypeScript,请移除已有的 ‘vue/types/vue’ 类型扩展声明,因为它已经集成到上游包中了。

@vue/composition-api

如果你之前在 Vue 2 中使用了 Composition API 包,你需要将所有导入改为指向 Vue 包。

// 旧方式,@vue/composition-api
- import { ref } from '@vue/composition-api'

// Vue 3 新方式
+ import { ref } from 'vue'

如果你使用了已弃用的 context.root 对象,必须重构代码以避免使用它,因为它已不再可用。

删除 src/boot/composition-api 引导文件以及 /quasar.config 文件中对应的条目。然后卸载 @vue/composition-api 包:


$ yarn remove @vue/composition-api

如果你使用 TypeScript,请准备好多次重新加载 VSCode,因为所有升级都会导致类型缓存问题。

Quasar 组件

Vue 3 和 v-model

v-model 现在是 model-value + @update:model-value 的别名,而不再是 value + @input。这影响了所有使用 v-model 的 Quasar 组件。如果你在 .vue 文件中编写组件,就不用担心这个问题,因为 vue-loader 会为你正确转换。

建议:你可能需要全局搜索并替换 :value@input。替换 :value 时请注意,某些组件(QLinearProgress、QCircularProgress)并未绑定到 v-model,仍然使用 value 作为属性。

Vue 3 和作用域插槽

所有插槽现在的行为方式与 Vue 2 中的作用域插槽一致。如果你使用选项式 API,可以全局搜索并替换 this.$scopedSlots(替换为 this.$slots)。

QDrawer/QDialog/QMenu/QTooltip

上述 Quasar 组件请使用 “class” 和 “style” 属性代替 “content-class” / “content-style” props。

QBtn/QItem/QBreadcrumbs/QRouteTab

新增 props:href、target。

对于 QBtn,使用 href prop 时不再需要指定 type="a"

href prop 对于 UMD 用户尤其有用——当你没有注入 Vue Router 时可以使用它。

QBtn/QRouteTab

如果你之前使用 to prop 并在 @click 处理函数中延迟导航:

function onClick (e, go) {
-  e.navigate = false // 旧方式
+  e.preventDefault() // 新方式
   // ...之后可能调用 go()?
}

QBreadcrumbsEl

移除了 “append” prop,因为 Vue Router v4 也移除了它。 新增了 “tag” 和 “ripple” 属性。

QColor

新增 “no-header-tabs” prop。

QChatMessage

现在默认情况下,“label”、“name”、“text” 和 “stamp” 都受到 XSS 攻击防护。这意味着所有 *-sanitize props 都已被移除,因为这种行为现在已成为 Quasar 的标准。如果你希望将 HTML 作为这些 props 的内容显示,现在需要通过新的 Boolean props(*-html)显式指定。

已移除的 Boolean prop新的对应 Boolean prop
label-sanitizelabel-html
name-sanitizename-html
text-sanitizetext-html
stamp-sanitizestamp-html

QDate

@update:model-value 事件(相当于旧的 @input)被触发时,第一个参数的内容不再包含(已弃用的)changed 属性。

QDialog

新增 “no-shake”、“transition-duration”。 使用 “class” 和 “style” 属性代替 “content-class” / “content-style” props。

QExpansionItem

移除了 “append” 属性,因为 Vue Router v4 也移除了它

(New) 连接到 QForm

如果你想创建自己的 Vue 组件并需要连接到父级 QForm(用于表单验证),我们让这件事变得更简单了:

Composition API variant

import { useFormChild } from "quasar";

useFormChild({
  validate, // 返回 Boolean 的函数(或解析为 Boolean 的 Promise)
  resetValidation, // 可选的重置验证函数
  requiresQForm, // Boolean -> 如果为 "true" 且你的组件
  //   没有被 QForm 包裹,则会显示
  //   错误信息
});

// 某个组件
export default {
  setup() {
    // 必需!应返回 Boolean
    function validate() {
      console.log("called my-comp.validate()");
      return true;
    }

    function resetValidation() {
      // ...
    }

    useFormChild({ validate, resetValidation, requiresQForm: true });
  },
};
Options API variant

import { QFormChildMixin } from "quasar";

// 某个组件
export default {
  mixins: [QFormChildMixin],

  methods: {
    // 必需!应返回 Boolean
    validate() {
      console.log("called my-comp.validate()");
      return true;
    },

    // 可选
    resetValidation() {
      // ...
    },
  },

  // ...
};

QInnerLoading

新增 “label”、“label-class” 和 “label-style” props。

QImg

此组件已从头重新设计,采用了更现代的 API。直接效果是内存占用更少,运行速度更快。

新增属性:“loading”、“crossorigin”、“fit”、“no-spinner”、“no-native-menu”、“no-transition”。 移除属性:“transition”、“basic”(现在等同于 “no-spinner” + “no-transition”) 属性 “no-default-spinner” 更名为 “no-spinner”。

详细更改请查看 QImg 页面上的 API 卡片。

QPagination

新增 “gutter” prop。

QPopupEdit

对此组件进行了一些性能优化,因此你现在需要使用默认插槽。

The OLD way

<q-popup-edit content-class="bg-primary text-white" buttons color="white" v-model="myModel">
  <q-input type="textarea" dark color="white" v-model="myModel" autofocus />
</q-popup-edit>

新方式如下。注意 v-slot="scope" 直接应用在 <q-popup-edit> 上,并且内部的 <q-input> 组件使用 scope.value 而不是 myModel

The NEW way

<q-popup-edit class="bg-primary text-white" buttons color="white" v-model="myModel" v-slot="scope">
  <q-input
    type="textarea"
    dark
    color="white"
    v-model="scope.value"
    autofocus
    @keyup.enter="scope.set"
  />
</q-popup-edit>

更多用法详情请阅读 QPopupEdit 页面。

QLayout

@scroll 事件参数的内容略有变化:

{
  (position, // Number(距顶部的像素数)
    direction, // String("top"、"bottom")
    directionChanged, // Boolean
    inflectionPoint, // 方向改变时的最后位置(距顶部)- Number(像素)
    delta); // 与上次 @scroll 更新的差值 - Number(像素)
}

QOptionGroup

新增 “label” 和 “label-N” 插槽。

QRouteTab

新增 “ripple” 属性。

QScrollArea

QScrollArea 已重新设计,现在同时支持垂直和水平滚动。

  • 新增 props:“vertical-bar-style” 和 “horizontal-bar-style”(在 “bar-style” 之上,后者同时应用于垂直和水平滚动条)
  • 新增 props:“vertical-thumb-style” 和 “horizontal-thumb-style”(在 “thumb-style” 之上,后者同时应用于垂直和水平滚动条滑块)
  • 移除 prop:“horizontal”(因为 QScrollArea 现在同时支持垂直和水平滚动,所以已废弃)
  • “getScrollPosition” 方法现在返回一个对象,形如 { top, left }(例如:{ top: 5, left: 0 }
  • “setScrollPosition” 和 “setScrollPercentage” 方法现在需要一个新的第一个参数(名为 “axis”,值为 “horizontal” 或 “vertical”):(axis, offset[, duration])

QScrollObserver

属性 “horizontal” 替换为 “axis”(String:“vertical”、“horizontal”、“both”;默认值:“vertical”)。

@scroll 事件参数的内容略有变化:

{
  position: {
    top, left // Numbers(像素)
  },
  direction, // String("top"、"right"、"bottom" 或 "left")
  directionChanged, // Boolean
  inflectionPoint: { // 方向改变时的最后位置
    top, left // Numbers(像素)
  },
  delta: { // 与上次 @scroll 更新的差值
    top, left // Numbers(像素)
  }
}

QSelect

  • “option” 插槽中的 “itemEvents” prop 已被移除。该信息现在包含在 “itemProps” 中。这是 Vue 3 将渲染函数第二个参数扁平化(“on”、“props” 等合并为单个对象)的逻辑结果。
  • 新增方法:“blur()”

QSlider/QRange

新增 props:track-size、thumb-size、marker-labels、marker-labels-class、switch-label-side、switch-marker-labels-side、inner-min、inner-max、 thumb-color、track-color、track-img、inner-track-color、inner-track-img、selection-color、selection-img。

QRange 特有的新增 props:left-thumb-color、right-thumb-color

新增插槽:marker-label、marker-label-group

QTable

“data” 属性重命名为 “rows”(为了解决 TS 冲突问题——“data” 被错误推断为 Vue 组件的 “data()” 方法)。

新增 prop:“column-sort-order”。新增 “columns” 定义中的 prop(“sortOrder”),现在 “style” 和 “classes” 也可以是函数了。

由于 Vue 3 的新 v-model 特性取代了 “.sync” 修饰符,:pagination.sync="..." 现在需要改为 v-model:pagination="..."

QTable/QTree

由于 Vue 3 的新 v-model 特性取代了 “.sync” 修饰符,以下属性的使用方式需要更改:

旧方式新方式
pagination.sync=“varName”v-model:pagination=“varName”
selected.sync=“varName”v-model:selected=“varName”
expanded.sync=“varName”v-model:expanded=“varName”

QTabs

新增 “active-class” prop。

QBtnDropdown/QCarousel/QTooltip/QMenu/QDialog/QStepper/QTabPanels

新增 “transition-duration” 属性。

QSkeleton

新增 “animation-speed” prop。

QUploader

QUploaderBase 组件已被移除,取而代之的是 createUploaderComponent 工具函数。

Quasar 指令

本节唯一的破坏性更改是我们移除了 GoBack 指令。请改用 router 引用来调用 push/replace/go(-1)。

// 组合式 API 写法
import { useRouter } from 'vue-router'

setup () {
  const $router = useRouter()

  // 后退一条记录,等同于 $router.back()
  $router.go(-1)
}
// 选项式 API 写法(在组件内部)
this.$router.go(-1);

Quasar 插件

AppFullscreen 插件

request() 方法现在可以在已处于全屏状态时接受另一个节点。

Loading 插件

  • 新增 “boxClass” 属性
  • 默认情况下,消息内容受到 XSS 攻击防护。如果你希望通过 “message” prop 显示 HTML 内容,需要同时指定 “html: true”。这与 Quasar v1 的行为完全相反——在 v1 中你使用 “sanitize” prop(现已不可用;默认启用)来阻止 HTML 显示。

Dialog 插件

有以下几个变更:

  1. 如果你在 Dialog 插件中使用自定义组件,现在必须将组件属性放在 “componentProps” 下:
// 旧的 v1 方式(已弃用)
const dialog = this.$q.dialog({ // 或 Dialog.create({...})
  component: MyVueComponent,
  someProp: someValue,
  // ...
})

// v2 新方式(组合式 API)
import { useQuasar } from 'quasar'

setup () {
  const $q = useQuasar()
  // ...
  const dialog = $q.dialog({ // 或 Dialog.create({...})
    component: MyVueComponent,
    componentProps: {
      someProp: someValue,
      // ...
    }
  })
}

// v2 新方式(选项式 API)
const dialog = this.$q.dialog({ // 或 Dialog.create({...})
  component: MyVueComponent,
  componentProps: {
    someProp: someValue,
    // ...
  }
})
  1. parentroot props 已被移除。由于 Vue 3 的架构,我们不再能使用 “parent” 组件来实现 provide/inject 功能。但你仍然可以在自定义组件内部使用 Vue Router/Vuex 等。
  2. 如果使用自定义组件调用 Dialog 插件,你需要在组件中添加 emits: [ 'ok', 'hide' ],因为 Vue 3 现在要求显式列出组件可能触发的事件。你也可以将组件转换为组合式 API。详细信息请参阅调用自定义组件
// 被调用的组件代码
export default {
  // ...
  emits: ["ok", "hide"],
  // ...
};
  1. 如果使用内置组件调用 Dialog,现在有了新的方式来提供原生属性:
// 旧方式
prompt: {
  // 或 "options"
  // ...
  attrs: {
    someattribute: "value";
  }
}

// v2 新方式
prompt: {
  // 或 "options"
  // ...
  someattribute: "value";
}

Meta 插件

// v1 方式(旧的,已弃用)
// 某个 .vue 文件
export default {
  meta: {
    // ...定义
  },
};

新方式(组合式 API 或选项式 API):

// 组合式 API 写法
// 某个 .vue 文件
import { useMeta } from "quasar";

export default {
  setup() {
    // 需要直接在 setup() 方法下调用!
    useMeta({
      // ...定义
    });
  },
};
// 选项式 API 写法
// 某个 .vue 文件
import { createMetaMixin } from 'quasar'

export default {
  mixins: [
    createMetaMixin({ /* ...定义 */})
    // 或动态方式:
    createMetaMixin(function () {
      // 这里的 "this" 指向 vue 组件
      return {
        /* ...定义... */
      }
    })
  ]
}

详细信息请参阅 Meta 插件

Quasar 工具函数

date 工具

“addToDate” 和 “subtractFromDate” 方法的对象字面量属性名已被规范化:#7414

旧名称新名称是否更改?
yearyears
monthmonths
daysdays-
hourshours-
minutesminutes-
secondsseconds-
millisecondsmilliseconds-

exportFile 工具

exportFile() 工具(强制浏览器下载包含指定内容的文件)增强了新功能:你可以指定 bom(字节序标记)和/或文本编码。更多信息

scroll 工具

旧方法名新方法名
getScrollPositiongetVerticalScrollPosition
animScrollToanimVerticalScrollTo
setScrollPositionsetVerticalScrollPosition

color 工具

从 color 工具中移除了 “getBrand” 和 “setBrand”。它们被 “getCssVar” 和 “setCssVar” 替代:

// 旧的 v1 方式(已弃用):
import { colors } from "quasar";

const { getBrand, setBrand } = colors;
const primaryColor = getBrand("primary");
setBrand("primary", "#f3c");

// v2 新方式:
import { getCssVar, setCssVar } from "quasar";

const primaryColor = getCssVar("primary");
setCssVar("primary", "#f3c");

EventBus 工具

Vue 3 移除了事件总线方法($on、$once、$off、$emit)。不过 Quasar v2(v2.8.4+)提供了原生的替代方案:EventBus 工具

Quasar 语言包

我们更改了语言包文件名以反映浏览器使用的标准命名规范。这样你就可以在需要动态导入 Quasar 语言包文件时使用 $q.lang.getLocale()

完整的更改列表:

旧名称新名称
en-usen-US
en-gben-GB
az-latnaz-Latn
fa-irfa-IR
kzkk
ko-krko-KR
kur-CKBkur-CKB
nb-nonb-NO
pt-brpt-BR
zh-hanszh-CN
zh-hantzh-TW

如果你在 /quasar.config 文件中配置了默认的 Quasar 语言包,需要修改它:

framework: {
-  lang: 'en-us' // 旧方式
+  lang: 'en-US' // 新方式
}

你还需要修改所有从 quasar/lang/ 动态导入的代码以匹配新的语法。

Quasar CSS

颜色 CSS 变量名(所有品牌相关的变量)已更改:

// 旧的
--q-color-primary, --q-color-secondary, ...

// 新的
--q-primary, --q-secondary, ...

Quasar UMD

  • 由于 Vue 3 的新架构,应用引导代码已更改,你需要相应地进行适配
  • script 和 css 标签的命名方案已更改,以包含分发类型。例如,压缩后的资源文件名现在以 .prod.js / .prod.css 结尾。这是为了与 Vue 3 自身的文件命名方案保持一致。

TIP

要深入了解所需的 UMD 脚本和标签,请使用我们的生成器工具

Quasar App CLI

本节涉及支持 Vue 3 和 Quasar UI v2 的 “@quasar/app” v3 包。

  • 不再支持 src/css/quasar.variables.styl。此外,如果你仍想使用 Stylus 作为预处理器(但不使用 Quasar Stylus 变量),则需要手动将 stylusstylus-loader 作为开发依赖安装到项目中(“@quasar/app” 不再提供它们)。
  • 新增 quasar.config 文件 > build > vueLoaderOptions 属性
  • 移除 quasar.config 文件 > framework > importStrategy。自动导入效果非常好,现在已成为默认且唯一的选项。
  • url-loader 配置已增强,现在还开箱支持 “ico” 文件
  • 如果你之前以对象形式使用 quasar.config 文件 > build > rtl,那么你现在必须匹配这些选项,因为我们已从不再维护的 postcss-rtl 切换到了 postcss-rtlcss 包。

如果你有引导文件(boot files)通过 Vue.prototype.$q 访问和修改 $q 对象,你需要做如下调整:

// 引导文件中的旧方式
Vue.prototype.$q.iconSet.chip.remove = "fas fa-times-circle";

// 新方式
export default ({ app }) => {
  app.config.globalProperties.$q.iconSet.chip.remove = "fas fa-times-circle";
};

App Extensions 的工作方式没有变化。请注意,并非所有的 App Extensions 都兼容 Quasar UI v2。我们正在努力发布兼容的新版本。

TypeScript

更新 src/shims-vue.d.ts 以匹配 Vue3 版本

创建 src/quasar.d.ts 文件并将此处的内容复制进去。

如果你使用 ESLint,请更新 /quasar.config 文件中的属性:

// 旧方式
supportTS: {
  tsCheckerConfig: { eslint: true },
},

// 新方式
supportTS: {
  tsCheckerConfig: {
    eslint: {
      enabled: true,
      files: './src/**/*.{ts,tsx,js,jsx,vue}',
    },
  },
},

这是由于 fork-ts-checker-webpack-plugin 的上游破坏性更改所致。

Quasar App CLI Electron 模式

WARNING

如果你的项目使用了 Quasar Electron 模式,请务必阅读其专门的 Electron 模式升级指南

现在开箱即支持 TypeScript

你还可以为主线程和预加载脚本启用 ESLint:

electron: {
  chainWebpackMain (chain) {
    chain.plugin('eslint-webpack-plugin')
      .use(ESLintPlugin, [{ extensions: [ 'js' ] }])
  },

  chainWebpackPreload (chain) {
    chain.plugin('eslint-webpack-plugin')
      .use(ESLintPlugin, [{ extensions: [ 'js' ] }])
  }
}

Quasar App CLI PWA 模式

如果你使用 Workbox 的 InjectManifest 模式,需要知道 /src-pwa/custom-service-worker.js 现在也会被编译。这意味着你的代码中现在也可以使用相对路径导入了。

由于升级到 Webpack 5,你还需要将 workbox-webpack-plugin 升级到 v6+。

你现在也可以为自定义 service worker 启用 ESLint。并且它开箱即支持 TypeScript(在这种情况下,将扩展名重命名为 .ts)。

/quasar.config 文件中编辑以为自定义 service worker 启用 ESLint:

pwa: {
  chainWebpackCustomSW (chain) {
    chain.plugin('eslint-webpack-plugin')
      .use(ESLintPlugin, [{ extensions: [ 'js' ] }])
  }
}

Quasar App CLI SSR 模式

如果你的项目使用了 Quasar SSR 模式,请务必阅读其专门的 SSR 模式升级指南

现在开箱即支持 TypeScript

Quasar Extras

没有变化。你可以像 Quasar UI v1 一样使用它。

Quasar Icon Genie

没有变化。你可以像 “@quasar/app” v1 或 v2 项目一样使用它。