Search code examples
javascriptvue.jssanitizationvue-props

Is it possible to sanitize a prop without creating a computed or data property


Let's say I have a vue component defined like this:

TestSelect.vue
<template>
  <v-select
    v-model="selectValue"
    :items="items"
    item-text="name"
    item-value="id"
    @change="changed"
  >
  </v-select>
</template>

<script>
export default {
  props: {
    link: String,
    items: Array,
    value: Number,
  },
  data: (props) => ({
    selectValue: props.value,
    saneLink: props.link.slice(-1) == "/" ? props.link : `${props.link}/`,
  }),
  methods: {
    changed(value) {
      document.location = this.saneLink + value;
    },
  },
};
</script>

This works fine and can be used either like:

<test-select
    link="test"
    :value="1"
    :items="[
    { id: 1, name: 'dogbert' },
    { id: 2, name: 'pointy' },
    ]"

></test-select>

or, like

<test-select
    link="test/"
    :value="1"
    :items="[
    { id: 1, name: 'dogbert' },
    { id: 2, name: 'pointy' },
    ]"

></test-select>

While this is fine, but out of curiosity and a desire to simplify my code I was wondering if there is a way to sanitize a prop without defining a new data or computed property.


Solution

  • Unfortunately now you can only validate props in Vue directly, not sanitise them.

    The ability to sanitise props was intentionally removed to reduce Vue bundle size and because the same effect can be achieved using computed properties like you touched on.

    That's the preferred approach, unfortunately.

    You can however, write a custom plugin that allows you to implement prop sanitising.

    From a cursory google search (please don't blindly use this plugin without auditing the code first), I've found this Vue plugin intended to allow you to coerce a prop into a different value.

    https://github.com/posva/vue-coerce-props

    I can't vouch for the efficacy of that code, or any issues it may have but it is an alternative approach to using the recommended computed properties.