简体   繁体   中英

How to disable conversion of Vue component properties to special characters?

I have a string containing the character "  " (non-breaking space).

I pass the string to the component like this:

<name-component test='Paper black'></name-component>

The component name-component in the property test = Paper&nbsp;black .

How to get the string 'Paper black' in its original form?

This is only a problem with in-DOM templates. If you use single-file components or strings to define your templates then this won't happen.

When you pass el: '#app' or equivalent to Vue it grabs the template from inside the element using innerHTML . See:

https://github.com/vuejs/vue/blob/9fbd416635eb3d7b32cd73b7c29f8377003c4dc8/src/platforms/web/entry-runtime-with-compiler.js#L14

The innerHTML value returned by the browser contains &nbsp; instead of a non-breaking space character.

The example code below illustrates a few different cases and what happens. The key thing to notice is that the problem only occurs when the non-breaking space is included directly inside the template in the HTML. I have included various bits of console logging to illustrate what is going on and to confirm that the spaces really are non-breaking space (character 190 in decimal, a0 in hex).

 const NameComponent = { template: `<div>{{ test }}</div>`, props: ['test'], mounted () { console.log('In mounted:') console.log(this.test) console.log(this.test.charCodeAt(5)) } } // This component uses a string template, // not an in-DOM template. All is well. const WrappedComponent = { template: ` <div> <name-component test="Paper black"/> </div> `, components: { NameComponent } } // This shows the value of `innerHTML` // that Vue sees for the template. console.log(document.getElementById('app').innerHTML) new Vue({ el: '#app', components: { NameComponent, WrappedComponent }, data () { return { test: 'Paper black' } } })
 <script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script> <div id="app"> <name-component :test="test"></name-component> <name-component test="Paper black"></name-component> <wrapped-component></wrapped-component> </div>

Of course it could be argued that the correct way for Vue's template parser to interpret test="Paper&nbsp;black" would be to treat the &nbsp; as a non-breaking space character. To my mind it should. However, it does not. Only a small subset of HTML entities are decode correctly:

https://github.com/vuejs/vue/blob/9fbd416635eb3d7b32cd73b7c29f8377003c4dc8/src/compiler/parser/html-parser.js#L42

Yes:
<template>
  <div v-html="test"></div>
<template>

No:
<template>
  <div>
    {{ test }}
  </div>
<template>

You need to replace with non-break space code \\xa0 .

<div id="app">
  <my-component name="custom   space"></my-component>
</div>
-----------------------
Vue.component('my-component', {
  template: `
    <div>
      {{ nameWithSpaces }}
    </div>
  `,
  props: {
    name: {
      type: String,
      required: true,
    },
  },
  computed: {
    nameWithSpaces() {
      return this.name.replace(/ /g, '\xa0');
    }
  }
})

Here's the codepen .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM