材料设计辅助集成

时间:2019-05-02 09:13:08

标签: vue.js material-design nuxt.js material nuxt

我是Nuxt框架的新手,我想将材料设计库集成到我的项目中(正式的库是https://material.io/develop/web/)。

我用以下内容制作了一个插件:

import Vue from "vue"
import mdcAutoInit from "@material/auto-init"
import { MDCTextField } from "@material/textfield"
import { MDCTextFieldIcon } from "@material/textfield/icon"
import { MDCSelect } from "@material/select"
import { MDCFormField } from "@material/form-field"
import { MDCRadio } from "@material/radio"

function init() {
  /** Select */
  mdcAutoInit.register("select", MDCSelect)

  /** TextField */
  mdcAutoInit.register("textfield", MDCTextField)
  mdcAutoInit.register("textfieldIcon", MDCTextFieldIcon)

  /** Radio */
  mdcAutoInit.register("formfield", MDCFormField)
  mdcAutoInit.register("radio", MDCRadio)

  // /** Auto Init */
  mdcAutoInit.apply()
}

const plugin = {
  install(vm) {
    console.log("Installing")

    vm.component(MDCTextFieldIcon)
    vm.component(MDCTextField)
    vm.component(MDCSelect)
    vm.component(MDCFormField)
    vm.component(MDCRadio)

    init()
  }
}

if (typeof window !== "undefined" && window.Vue) {
  window.Vue.use(plugin)
} else {
  Vue.use(plugin)
}

我已将其添加到nuxt.config.js的插件部分。

当我加载页面(例如,文本字段动画正在工作)时,它似乎起作用,但是当我使用nuxt-link更改页面时,文本字段未初始化。

有人知道如何使材料设计加载每个加载的组件的init函数吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我可以看到您正在使用mdcAutoInit。请参阅Material Design documentation有关此实用程序的信息。特别要注意多次运行和新的DOM元素的提及。

为什么?由于您使用的是Nuxt,因此很可能会构建SPA,这意味着您的网站不是静态的。为什么网站不是静态的?因为自动初始化将普通的非反应式事件侦听器附加到现有DOM元素。当Vue通过重新渲染替换这些DOM元素(例如,v-if条件更改)时会发生什么?现有DOM元素及其附加的事件侦听器已被销毁,并且任何新的DOM元素尚未通过自动初始化进行初始化。为什么不?由于香草材料设计库是非反应性的,因此Vue不知道该怎么做,而自动初始化假定它仅会运行一次。

您似乎需要在包含材料设计组件的每个自​​定义组件的window.mdc.autoInit(/* root */ document, () => {});updated()钩子中运行mounted(),以确保适当的事件侦听器会根据需要进行附加(请记住,根据运行时DOM的总大小,此操作可能会非常昂贵)。

或者,如果您想完全避免头痛,请使用现有的材料设计框架或组件库,然后将所需的组件随插件一起导出。您可以在awesome-vue GitHub存储库中找到这些框架和插件的列表。