arraysvue.jscustom-data-attribute

Enforce format of data-attribute in vuejs, especially arrays


Is there a way to enforce the format of data-attributes?

Considering the following situation, the returned value is often a string – not an array. splitting is not always desirable, for instance, if the values contain commata. There is a way (see "day3"), but you usually have a variable to pass and not a literal string.

<script setup>
const as_variable = ["Lunes", "Martes", "Miercoles", "Jueves"];

const test_read_all_da_data = ( ev ) => {
  const el = ev.currentTarget;
  console.log(JSON.parse(el.dataset.days1));
  console.log(JSON.parse(el.dataset.days2));
  console.log(JSON.parse(el.dataset.days3)); // only this one is array of strings, as desired.
  console.log(JSON.parse(el.dataset.days4));
};
</script>

<template>
    <button 
        :data-days1="['Lunes', 'Martes', 'Miercoles', 'Jueves']"
        :data-days2='["Lunes", "Martes", "Miercoles", "Jueves"]'
        data-days3='["Lunes", "Martes", "Miercoles", "Jueves"]'
        :data-days4="as_variable"
        @click="test_read_all_da_data">data-attributes</button>
</template>

Solution

  • I just realized that this is due to Array's toString method. You can just write a custom one.

    <script setup>
    Array.prototype.toDataString = function() {
      return `[${this.map((item) => typeof item === 'string' ? `"${item}"` : item)}]`;
    };
    </script>
    
    <template>
      <button :data-days4="problematic_list.toDataString()" …>success!</button>
    </template>
    

    … or an extra method for that purpose

    const toDataString = ( list ) => {
      if (!Array.isArray(list)) { return list; }
      return `[${list.map((item) => typeof item === 'string' ? `"${item}"` : item)}]`;
    };