0

I created a "box" component that I re-use several times. Each element has a @mouseenter event that the parent listens to. My goal is to change the border-color of the child element. Because I declared the from the parent with a loop I can't change only one of the childs properties but they all change

<template>
<div>
  <div id="container">
    <div id="row" v-for="i in 11" :key="i">
      <div>
        <box-component v-for="j in 7" :key="j" :color="getColor(i, j)" v-bind:borderColor="getBorder(i, j)" :row="i" :col="j" v-on:changeBorder="highlightBorder($event)"></box-component>
      </div>
    </div>
  </div>
</div>
</template>

The problem is with this part:

v-bind:borderColor="getBorder(i, j)"

Because i and j have changed I don't know how to only affect one child.

I know that I could remove the loop and copy paste the same code but there must be another solution to this. I also know that this particular example could be implemented directly on the child component but I need to be able to do it from the parent.

1 Answer 1

2

You can do it this way:

<box-component v-on:change-border="highlightBorder(i, j)"></box-component>

From the docs:

Unlike components and props, event names will never be used as variable or property names in JavaScript, so there’s no reason to use camelCase or PascalCase. Additionally, v-on event listeners inside DOM templates will be automatically transformed to lowercase (due to HTML’s case-insensitivity), so v-on:myEvent would become v-on:myevent – making myEvent impossible to listen to.

For these reasons, we recommend you always use kebab-case for event names.

Interactive demo

Vue.component('parent-component', {
  template: '#parent-component',
  data() {
    return {
      defaultStyles: {
        color: '#555',
        borderColor: '#bbb'
      },
      highlightedStyles: {
        color: '#f50',
        borderColor: 'orange'
      },
      highlighted: {x: null, y: null}
    };
  },
  methods: {
    isHighlighted(x, y) {
      return x === this.highlighted.x && y === this.highlighted.y;
    },
    getStyles(x, y) {
      return this.isHighlighted(x, y) ? this.highlightedStyles : this.defaultStyles;
    },
    getColor(x, y) {
      return this.getStyles(x, y).color;
    },
    getBorder(x, y) {
      return this.getStyles(x, y).borderColor;
    },
    highlightBorder(x, y) {
      this.highlighted = {x, y};
    }
  }
});

Vue.component('box-component', {
  template: '#box-component',
  props: ['color', 'borderColor']
});


var vm = new Vue({
  el: '#app'
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.row:after {
  content: '';
  display: block;
  clear: both;
}

.box {
  float: left;
  padding: .5em;
  border-width: 4px;
  border-style: solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.min.js"></script>
<div id="app">
  <parent-component></parent-component>
</div>

<template id="parent-component">
  <div>
    <div id="container">
      <div class="row" v-for="y in 11" :key="`row-${y}`">
        <div>
          <box-component
            v-for="x in 7"
            :key="`cell-${x}`"
            :color="getColor(x, y)"
            :border-color="getBorder(x, y)"
            :col="x" :row="y"
            @change-border="highlightBorder(x, y)"
          ></box-component>
        </div>
      </div>
    </div>
  </div>
</template>

<template id="box-component">
  <div
    class="box"
    :style="{background: color, borderColor: borderColor}"
    @mouseenter="$emit('change-border')"
  ></div>
</template>

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer, it helped me a ton! I was not aware that I could do that with the keys, now I will be able to move forward with the project. Sorry for not posting the rest of the code it could have saved you a bit of time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.