微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Vue 将任何标签中的“open”属性替换为“open”值

如何解决Vue 将任何标签中的“open”属性替换为“open”值

我在 laravel 刀片模板中使用 vue.js (v2.6.12) 组件。 对于该项目,我还使用了 MathML,其中我需要使用 open 标记<mfenced> 属性设置为一些自定义值。以下是用 mathml 表示的数学示例。

<math xmlns="http://www.w3.org/1998/Math/MathML">
    <mi>f</mi>
    <mfenced close="]" open="[">
        <mrow><mi>a</mi><mo>,</mo><mi>b</mi></mrow>
    </mfenced>
</math>

但是一旦页面呈现,open 属性就会转换为这个 open="open"。我 100% 确定没有其他库或脚本被加载像这样更新,只是普通的 vue。这实际上打破了数学表达式。所以它看起来像这样:

<math xmlns="http://www.w3.org/1998/Math/MathML">
    <mi>f</mi>
    <mfenced close="]" open="open">
        <mrow><mi>a</mi><mo>,</mo><mi>b</mi></mrow>
    </mfenced>
</math>

后来我意识到不仅在数学表达式中,任何标签,无论是 <div open="anything">...</div>,<span open="anything">...</span>,<custom-element open="something">...</custom-element> 具有 open 属性的行为都是一样的。即使我使用 v-pre 属性将其从 vue js 模板编译器中排除。

这不会发生,一旦我禁用了 vue 应用程序初始化。


这里的问题是:

  1. 为什么 vue 像这样改变 open 属性
  2. 如何在 vue 应用程序区域内的整个页面或至少在我选择的位置(例如使用 v-pre)停止这种行为,是否有 ary 配置或任何其他方式?

解决方法

为什么

在 HTML 规范中有一些称为 boolean attributes 的属性。规范规定了此类属性的值可以是什么:

如果该属性存在,则其值必须是空字符串,或者是与该属性的规范名称不区分大小写的 ASCII 匹配值,且没有前导或尾随空格。

布尔属性不允许使用值“true”和“false”。要表示假值,必须完全省略该属性。

open 是布尔属性之一 - 它是为 <details> element

定义的

Vue 2 的问题在于,它将大部分 boolean attributes 视为全局 - 没有考虑放置它的元素。结果是 open 属性总是以值“open”呈现,或者如果值为假(当 v-binding 时)被移除。这在 Vue 3 中已修复,如第二个示例所示...

如何

使用 v-pre 是可行的方法,但不幸的是您有一个错误。
this issue。该错误已通过此 commit(2020 年 9 月 21 日)修复,但尚未发布...

  1. 示例 - “With v-pre”应该适用于 Vue 版本 > 2.6.12

    const vm = new Vue({
      el: '#app',data() {
        return {
          message: 'Hi!',html: `<div open="[" close="]">Hi from html</div>`
        }
      },})
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.12/vue.js"></script>
    <div id="app">
      <div open="[" close="]">{{ message }}</div>
      <div v-html="html"></div>
      <div v-pre>
        <p open="[" close="]">With v-pre</p>
      </div>
    </div>

  2. 示例 - 它适用于 Vue 3 - open 仅在放置在 <details> 上时才被视为布尔属性

    const app = Vue.createApp({
      data() {
        return {
          message: 'This works in Vue 3!',}
      },})
    
    app.mount('#app')
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.11/vue.global.js" integrity="sha512-1gHWIGJfX0pBsPJHfyoAV4NiZ0wjjE1regXVSwglTejjna0/x/XG8tg+i3ZAsDtuci24LLxW8azhp1+VYE5daw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    
    <div id="app">
      <div open="[" close="]">{{ message }}</div>
      <details open="[">
        <summary>Details</summary>
        open attribute on details element is treated as boolean (renders empty value)
      </details>
    </div>

,

一种解决方法是创建一个设置属性的 directive(名为 "attr"):

Vue.directive('attr',(el,binding) => el.setAttribute(binding.arg,binding.value || ''))

然后在您的模板中使用它,如 v-bind,但与 v-attr 一起使用:

<mfenced v-attr:open="'['">

Vue.directive('attr',binding.value || ''))

new Vue({ el: '#app' })
<script src="https://unpkg.com/vue@2.6.12"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"></script>

<div id="app">
  <math xmlns="http://www.w3.org/1998/Math/MathML">
    <mi>f</mi>
    <mfenced close="]" v-attr:open="'['">
      <mrow><mi>a</mi><mo>,</mo><mi>b</mi></mrow>
    </mfenced>
  </math>
</div>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。