自定义元素交互

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-04-15

自主定制元素

如果我们想添加在 Vue 外部定义的自定义元素,例如在微信环境下使用微信开放标签组件:

<template>
  <div>
    <wx-open-launch-weapp
      id="launch-btn"
      username="原始小程序id"
      path="小程序路径/page/index/index.html"
      @launch="handleLaunchFn"
      @error="handleErrorFn"
    />
  </div>
</template>

就需要将其标记为自定义元素白名单:

Vue.config.ignoredElements = ['wx-open-launch-weapp']

在3.0 中,此检查在模板编译期间执行指示编译器将 <wx-open-launch-weapp> 视为自定义元素:

如果使用生成步骤:将 isCustomElement 传递给 Vue 模板编译器,如果使用 vue-loader,则应通过 vue-loadercompilerOptions 选项传递:

// webpack 中的配置
rules: [
  {
    test: /\.vue$/,
    use: 'vue-loader',
    options: {
      compilerOptions: {
        isCustomElement: tag => tag === 'wx-open-launch-weapp'
      }
    }
  }
  // ...
]

如果使用动态模板编译,请通过 app.config.isCustomElement 传递:

const app = Vue.createApp({})
app.config.isCustomElement = tag => tag === 'wx-open-launch-weapp'

定制内置元素

自定义元素规范提供了一种将自定义元素用作自定义内置模板的方法,方法是向内置元素添加 is 属性:

<button is="plastic-button">点击我!</button>

Vue 对 is 特殊 prop 的使用是在模拟 native attribute 在浏览器中普遍可用之前的作用。但是,在 2.x 中,它被解释为渲染一个名为 plastic-button 的 Vue 组件,这将阻止上面提到的自定义内置元素的原生使用。

在 3.0 中,我们仅将 Vue 对 is 属性的特殊处理限制到 <component> tag。

1、在保留的 <component> tag 上使用时,它的行为将与 2.x 中完全相同

<!-- 组件会在 组件名变量 改变时改变 -->
<component :is="组件名变量"></component>

2、在普通组件上使用时,它的行为将类似于普通 prop,如下:

<foo is="bar" />

<!-- 2.x 行为:渲染 bar 组件。 -->
<!-- 3.x 行为:通过 is prop 渲染 foo 组件。 -->

3、在普通元素上使用时,它将作为 is 选项传递给 createElement 调用,并作为原生 attribute 渲染,这支持使用自定义的内置元素

<button is="plastic-button">点击我!</button>

<!-- 2.x 行为:渲染 plastic-button 组件。 -->

<!-- 3.x 行为:通过回调渲染原生的 button -->
<script>
document.createElement('button', { is: 'plastic-button' })
</script>

v-is 用于 DOM 内模板解析解决方案

在 DOM 模板中使用时,模板受原生 HTML 解析规则的约束。一些 HTML 元素,例如 <ul><ol><table><select> 对它们内部可以出现的元素有限制,和一些像 <li><tr>,和 <option> 只能出现在某些其他元素中。

总所周知,ul里面嵌套li的写法是html语法的固定写法:

<ul>
  <my-component></my-component>
  <my-component></my-component>
</ul>

my-component是我们自己写的组件,但是html在渲染dom的时候,my-component对ul来说并不是有效的dom,甚至会报错。

正是因为html模板的限制,于是就诞生了is。接下来我们就用is解决上面的问题~

<ul>
  <li is='my-component'></li>
</ul>
<!--  <li is='my-component'></li>其实就相当于<my-component></my-component> -->
<!--  语义上是一样一样的,就是解决了html模板的限制。 -->

在3.0中,随着 is 的行为变化,我们引入了一个新的指令 v-is,用于解决这些情况

<table>
  <tr v-is="'blog-post-row'"></tr>
</table>

需要注意的是其值是一个 JavaScript 字符串文本, v-is="blog-post-row" 是不正确的,而是 v-is="'blog-post-row'",双引号包裹单引号字符串。