Search code examples
javascriptvue.jspug

Pug hasn't access to computed properties in vue inside dynamic class attribute


So, i tried to dynamically toggle className, based on computed property, but it looks like pug doesn't have access to computed properties. I tried to manually set true to a className, then it's working.

I tried to reassign computed property to pug variable, but it still doesn't work

When using pure html, classes dynamically toggle correctly

Pug:

main#app.container
  - var isPinkDefinitely = isPink ? 'pink' : 'gray';
  div.section(
    v-bind:class=[
      'custom-section',
      {
        'custom-section--pink': isPink
      }
    ] 
    v-bind:style=[
      {
        'background-color': isPinkDefinitely
      }
    ]
  ) {{ isPink }}
    form(@submit.prevent="addItem")
      label.label Add another
      div.field.has-addons
        div.control
          input.input(required, autofocus, v-model="newItem", placeholder="Remake this in React")
        button(type="submit").button.is-info
          i.fa.fa-plus
          span Add

    transition(name="slide")
      div(v-show="items.length > 0")

        hr

        ul
          transition-group(name="slide")
            li(v-for="(item, index) in items", :key="item.id")
              button(@click="removeItem(index)").button.is-danger
                i.fa.fa-trash
              span(v-text="item.desc")

        hr

        span(v-text="'Total: ' + items.length")

JS:

new Vue({
  el: '#app',
  data: {
    items: [
      {id: 1, desc: "Lorem"},
      {id: 2, desc: "Ipsum"},
      {id: 3, desc: "Dolor"},
    ],
    newItem: '',
  },
  computed: {
    isPink() {
      return true;
    }
  },
  methods: {
    addItem () {
      const id = this.items.length + 1
      this.items.push({id, desc: this.newItem})
      this.newItem = ''
    },
    removeItem (index) {
      this.items.splice(index, 1)
    },
  },
})

https://codepen.io/itprogressuz/pen/qBoePob?editors=1010


UPD: SO the basically solution was to just write all classes in one line inside just an object. see solution of @aykut


Solution

  • I just tried to solve your problem and I think i successed. You could use variable like me. If you want change it in computed function, it will change dynamically. You could also change it in methods functions when get users events. Here, my solution.

    main#app.container
    
    div.section(
    class="default-style"
    :class="{'bg-pink': isPink }"
    
    ) {{ setIsPink }}
    form(@submit.prevent="addItem")
      label.label Add another
      div.field.has-addons
        div.control
          input.input(required, autofocus, v-model="newItem", placeholder="Remake 
    this in React")
        button(type="submit").button.is-info
          i.fa.fa-plus
          span Add
    
    transition(name="slide")
      div(v-show="items.length > 0")
    
        hr
    
        ul
          transition-group(name="slide")
            li(v-for="(item, index) in items", :key="item.id")
              button(@click="removeItem(index)").button.is-danger
                i.fa.fa-trash
              span(v-text="item.desc")
    
        hr
    
        span(v-text="'Total: ' + items.length")
    

    // css file

    .default-style{
    background-color: gray;
    }
    
    .bg-pink{
        background-color: pink;
        }
    

    // js file

    new Vue({
      el: '#app',
      data: {
       
        isPink: false,
        items: [
          {id: 1, desc: "Lorem"},
          {id: 2, desc: "Ipsum"},
          {id: 3, desc: "Dolor"},
        ],
        newItem: '',
      },
      computed: {
        setIsPink() {
          this.isPink = !this.isPink;
          return this.isPink;
        }
      },
      methods: {
        addItem () {
          const id = this.items.length + 1
          this.items.push({id, desc: this.newItem})
          this.newItem = ''
        },
        removeItem (index) {
          this.items.splice(index, 1)
        },
      },
    })