2

我是 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 更改页面时,文本字段未初始化。

有谁知道如何让材料设计为每个加载的组件加载初始化函数?

提前致谢 !

4

1 回答 1

0

我可以看到你正在使用mdcAutoInit. 请参阅有关此实用程序的Material Design 文档。特别注意提到多次运行和新的 DOM 元素。

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

看来您需要在包含材料设计组件的每个自​​定义组件中运行window.mdc.autoInit(/* root */ document, () => {});和挂钩,以确保根据需要附加适当的事件侦听器(请记住,这将是一个潜在的updated()公平mounted()昂贵的操作取决于运行时的总 DOM 大小)。

或者,如果您想完全避免头痛,请使用现有的材料设计框架或组件库,并使用您的插件简单地导出您想要的组件。您可以在awesome-vue GitHub 存储库中找到这些框架和插件的列表。

于 2020-01-13T04:24:25.757 回答