【问题标题】:How to clean up v-bind directives from html code in Vue?如何从 Vue 中的 html 代码中清理 v-bind 指令?
【发布时间】:2019-05-27 22:02:13
【问题描述】:

好的,我有一些 Vue 代码和 HTML。

例如:

Vue.component('area-selectors-box', {
  template: `
    <div class="area-selectors-box">
      <area-selector v-for="(select, index) in selects" :select="select" :key="index"></area-selector>
    </div>
  `,
  props:['selects']
});

在我的页面中:

<div is="area-selectors-box" v-bind:selects="selects"></div>

一切正常,但如果我阅读页面源代码,我会看到 v-bind:selects="selects" 部分,我猜这不符合标准。

同样,其他组件也有其他对象属性,例如:

Vue.component('area-option', {
  template: `<option :area="area" :value="area.term_id">{{area.name}}<slot></slot></option>`
  ,props: ['area']
});

在页面源上的计算结果类似于:

<option area="[object Object]" value="82">Europa</option>

这显然是不可取的。

如何绑定这些属性而不让它们作为属性出现在 DOM 中?

【问题讨论】:

  • " 这不符合标准,我猜" ????什么让你有那个想法?您将该逻辑应用于什么“标准”?我在这里看到的唯一 问题area 它不适合绑定到您的 &lt;option&gt; 标记中

标签: javascript vue.js vuejs2


【解决方案1】:

默认情况下,当v-bind 遇到与目标上的属性无关的绑定名称时,该值将转换为字符串并分配为属性。由于 &lt;option&gt; 没有名为 area 的属性,因此该对象被分配为字符串属性,您在 DOM 中观察到了这一点。

您可以使用v-bind's .prop modifier 始终将其分配为属性:

<option :area.prop="area" ...>

Vue.component('area-selectors-box', {
  template: `
    <div class="area-selectors-box">
      <area-selector v-for="(select, index) in selects" :select="select" :key="index"></area-selector>
    </div>
  `,
  props:['selects']
});

Vue.component('area-selector', {
  template: `<div>
    <select v-model="selection">
      <area-option
         v-for="option in select.options"
         :key="option.id"
         :area="option.area" />
    </select>
    <pre>{{selection}}</pre>
</div>`,
  props: ['select'],
  data() {
    return {
      selection: null,
    }
  }
})

Vue.component('area-option', {
  template: `<option :area.prop="area" :value="area.term_id">{{area.name}}<slot></slot></option>`
  ,props: ['area']
});

new Vue({
  el: '#app',
  data: () => ({
    selects: [
      { id: 1, options: [
                { id: 10, area: { term_id: 100, name: 'Europe' } },
                { id: 11, area: { term_id: 101, name: 'Asia' } },
              ]
      },
      { id: 2, options: [
                { id: 20, area: { term_id: 200, name: 'North America' } },
                { id: 21, area: { term_id: 201, name: 'South America' } },
              ]
      },
    ]
  }),
})
<script src="https://unpkg.com/vue@2.6.10"></script>

<div id="app">
  <area-selectors-box :selects="selects"></area-selectors-box>
</div>

【讨论】:

    【解决方案2】:

    我自己的回答是:调用组件时传递props,而不是组件本身。此代码将工作并生成干净的 html:

    页内 HTML:

    <!-- pass selects to area-selectors-box -->
    <div is="area-selectors-box" :selects="selects"></div>
    

    JS:

    Vue.component('area-selectors-box', { // pass select to area-selector
      template: `
        <div class="area-selectors-box">
          <area-selector v-for="(select, index) in selects" :select="select" :key="index"></area-selector> 
        </div>
      `,
      props:['selects']
    });
    
    Vue.component('area-selector', { // pass area to area-option
      template: `
        <select @change="selected" >
          <option disabled selected value="">Seleziona continente</option>
          <area-option v-for="area in select.areas" :area="area" :key="area.term_id"></area-option>
        </select>
      `
      ,props:['select']
    });
    
    Vue.component('area-option', { // pass nothing
      template: `<option :value="area.term_id">{{area.name}}<slot></slot></option>`
      ,props: ['area']
    });
    

    【讨论】:

      猜你喜欢
      • 2021-04-23
      • 1970-01-01
      • 2022-07-14
      • 2022-09-19
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多