Marcius Leandro
Marcius Leandro

Reputation: 789

The prototype is returning my function instead of the return value

I want to create the subtitle of my pages similar to the image enter image description here

And I want to do this by calling my prototype from main.js

Vue.prototype.subtitlePage = function () {
  var path = this.$route.path;
  var array_path = path.split('/');
  var subtitle = "<ul class='subtitle'>";
  var index;
  for (index = 1; index < array_path.length - 2; index++) {
    subtitle += "<li>" + array_path[index] + "</li> >>";
  }
  subtitle += "<li>" + array_path[index] + "</li><ul>";
  return subtitle;
}

I'm calling my function that way in the construction of my screen

<p class="indextitle">Subir Nova Redação</p>
<p v-html="subtitlePage"></p>

However the text that appears on the screen is not the html return mounted in the function, but the code of my function

function () { var path = this.$route.path; var array_path = path.split('/'); var subtitle = "
"; var index; for (index = 1; index < array_path.length - 2; index++) { subtitle += "
" + array_path[index] + "
>>"; } subtitle += "
" + array_path[index] + "
"; return subtitle; }

Does anyone know what I'm doing wrong and what I have to change in my code to appear in the subtitle what I set up in the function?

Upvotes: 1

Views: 64

Answers (2)

Estus Flask
Estus Flask

Reputation: 222498

v-html expects a string, while a function is given, this results in stringified function output. It should be:

<p v-html="subtitlePage()"></p>

This should never be done in practice with user-defined data.

Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to XSS attacks. Only use v-html on trusted content and never on user-provided content.

URL is user-defined data here. It can be tailored by a culprit to evaluate arbitrary JS on user side.

A correct way to do this is to create a component for a breadcrumb and output it with:

<li v-for="pathSegment in pathSegments">{{pathSegment}}</li>

In case a segment may contain URL-encoded symbols (spaces and non-ASCII characters in this example), segments need to be additionally transformed with decodeURIComponent (this isn't covered in original code and will be a primary hazard for v-html).

Upvotes: 1

Marcius Leandro
Marcius Leandro

Reputation: 789

I managed to do it as follows

Vue.mixin({
  computed: {
    subtitlePage: {
      get: function () {
        var path = this.$route.path;
        var array_path = path.split('/');
        var subtitle = "<ul class='subtitle'>";
        var index;
        for (index = 1; index < array_path.length - 2; index++) {
          subtitle += "<li>" + array_path[index] + "</li> >>";
        }
        subtitle += "<li>" + array_path[index] + "</li><ul>";
        return subtitle; 
      }
    }
  }
})

Upvotes: 0

Related Questions