feyen01
feyen01

Reputation: 417

Dynamic CSS property of inline style in Vue

I'm looping through elements and I'm positioning div using top and left CSS properties:

<div
v-for="coord in coords"
:style="{ top: coord.y + 'px', left: coord.x + 'px' }"
></div>

Sometimes instead of top property I need to use bottom (this depends on one of my Vuex store values). How can I dynamically define if I should use top or bottom CSS property?

I tried to used computed prop isTopOrBottom which would return 'top' or 'bottom: :style="{ isTopOrBottom: coord.y + 'px', left: coord.x + 'px' }". But this is not working in Vue.

Upvotes: 1

Views: 9363

Answers (4)

Julio Peguero
Julio Peguero

Reputation: 180

You can also use a Vuejs custom directive for this! https://v2.vuejs.org/v2/guide/custom-directive.html

Check this out:

In your template:

 <p v-position="expressionThatMakesItTop" v-if="isSignedIn">Welcome back {{user.email}}</p>

If you want to register a directive locally, components also accept a directives option, check that out on the documentation I linked. I am going to show you how to do it globally so in your main.js file, before constructing the Vue instance of course:

I left the console.log that displays the objects that you can use in your directive so you can explore them on your console and tailor this to your needs.

Vue.directive("position", {
  bind: function(el, binding, vnode) {
    console.log(el, binding, vnode);
    el.style.left = `${vnode.context.coord.x}px`;
    if (binding.value) {
      el.style.top = `${vnode.context.coord.y}px`;
      return;
    }
    el.style.bottom = `${vnode.context.coord.y}px`;
  }
});

Upvotes: 0

Niklesh Raut
Niklesh Raut

Reputation: 34924

It should be like JavaScript string concatenation

<div
v-for="coord in coords"
:style="'top: '+coord.y + 'px;left: '+coord.x + 'px'"
></div>

Vue.config.productionTip = false;
Vue.config.devtools=false;

var app = new Vue({
  el: '#app',
  data:{
    coords:[{y:10,x:10},{y:20,x:20},{y:30,x:30}]
  }
});
.border-line{
  border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<div id="app">
<div class="border-line"
    v-for="coord in coords"
    :style="'margin-top: '+coord.y + 'px;margin-left: '+coord.x + 'px'"
    >Test</div>
 </div>

Upvotes: 3

iamimran
iamimran

Reputation: 110

You can use the ternary operator (in case computed properties are not working) For example:

<span
class="description"
:class="darkMode ? 'dark-theme' : 'light-theme'"

>

Hope this help.

Upvotes: 4

kattapillar
kattapillar

Reputation: 136

You could do something like this:

:class="{ is-top: isTop, is-bottom: isBottom }"

And in your script:

computed() {
    isTop() {
        // return top condition
    },
    isBottom() {
        // return bottom condition
    }
}

Handle css:

.is-top {
    ...
}
.is-bottom {
    ...
}

Upvotes: 0

Related Questions