A. L
A. L

Reputation: 12669

vue - inserting rows and columns into a table with scoped css

So I'm trying to insert rows and columns into a table using the code below:

add_to_table(type) {
  switch (type) {
    case "row":
      let columns = this.$refs.table.rows[0].cells.length;
      let row = this.$refs.table.insertRow(-1);
      row.height = "20px";
      for (let i = 0; i < columns; i++) {
        let cell = row.insertCell(-1);
        cell.innerHTML = "&nbsp;";
      }
      break;
    case "column":
      for (let row of this.$refs.table.rows) {
        let cell = row.insertCell(-1);
        cell.innerHTML = "&nbsp;";
      }
      break;
  }
}

However, this doesn't seem to maintain the css (doesn't add the data-* stuff to it).

I'm currently working around this by using v-for:

<tr v-for="row in rows">    
    <td v-for="column in columns">
    </td>    
</tr>

https://codesandbox.io/s/8n728r5wr8

Upvotes: 2

Views: 688

Answers (1)

acdcjunior
acdcjunior

Reputation: 135832

Your created rows and columns are not getting styled because the <style> you declared is scoped.

For the elements to get the scoped style, they must have a data-v-SOMETHING attribute. The elements you create manually, not via Vue, don't have that attribute.

WARNING: Vue is data-driven, the correct, simplest, more predictable and maintainable way of achieving what you want is mutating a data attribute and letting Vue's templates react to it accordingly (using directives like v-for). Your solution is not optimal. You have been warned.

That being said, you have some options:

  • Declare an additional <style> (non-scoped) tag along the scoped one. The created elements will pick up these styles. Drawback: the styles will be global. Advantage: you don't depend on Vue internals, you don't have to always add the data-v attribute (see below).

    Example:

    <style scoped>
    ...
    </style>
    <style>
    /* EXAMPLE OF GLOBAL STYLE ALONGSIDE A SCOPED ONE */
    tr, td {
      box-shadow:inset 0px 0px 0px 1px orange;
    }
    </style>
    
  • Get a hold of the data-v-SOMETHING attribute. It is available at this.$options._scopeId. Double Warning: the prefix _ means it is internal code. It may change without notice. Your app may be forever stuck with the current Vue 2.x versions. You have been warned again.

    So, whenever you create elements, just add the attribute. Example:

    // row example
    let row = this.$refs.table.insertRow(-1);
    row.setAttribute(this.$options._scopeId, ""); // <== this adds the data-v-XYZ attr
    ...
    // cell example
    let cell = row.insertCell(-1);
    cell.setAttribute(this.$options._scopeId, ""); // <== this adds the data-v-XYZ attr
    

Here's a CodeSandbox demo containing examples for both alternatives.

Upvotes: 1

Related Questions