Remove jQuery from Vue Component method

I have the following function in a Vue component:

<template>
    <div class="module-container" ref="moduleContainer" :id="`module-${moduleInstance.id}`">
        <div class="module" :style="styleObject">
....
methods: {
            moduleStylePosition: function() {
              let style = this.moduleInstance.getPosition(this.cellSize, this.currentProject[`width${this.platform}`])

              if (this.moduleInstance.isFullWidth && this.moduleInstance.moduleMaxWidth) {
                style['display'] = 'flex'
                style['justify-content'] = this.moduleInstance.moduleAlign
              } else {
                style['text-align'] = this.moduleInstance.moduleAlign
              }

              $(this.$refs.moduleContainer).css(style)
            },

and I am trying to convert the last line into a non jQuery piece of code. I tried with

document.querySelector(this.$refs.moduleContainer).setAttribute(style, "");

but I got errors that I could not use querySelector due to what I am loading here:

Vue warn]: Error in mounted hook: "SyntaxError: Failed to execute 'querySelector' on 'Document': '[object HTMLDivElement]' is not a valid selector."

Same result with querySelectorAll

Any ideas how this jQuery replacement can be done?

I am testing getComputedStyle(this.$refs.moduleContainer)[style] now with a rule I found at https://youmightnotneedjquery.com/

The query selector isn’t necessary because this is already what ref is intended for.

You should simply need to write:

this.$refs.moduleContainer.style = '';

to clear the styling.

Or if you want to use setAttribute:

this.$refs.heading.setAttribute('style', 'color: green')

1 Like

Thanks for that @JamesThomson . Did not know I could skip usage of query selector because of it being included in ref

I basically wanted to replace

$(this.$refs.moduleContainer).css(style)

so I do not want to clear the styling but finish it up and have all added like with the original code. So using

this.$refs.heading.setAttribute('style', 'color: green')

won’t work because I used jQuery .css() before to add all to same variable set at the beginning of the method moduleStylePosition which is mounted With getAttribute it seems I need two parameters while I only really have one…

That is why I came up with

getComputedStyle(this.$refs.moduleContainer)[style]`

So I can do what (this.$refs.moduleContainer).css(style) did. Just not sure it is correct. Just had no errors anymore.

fyi

For another similar piece of code where I remove the same style I am trying out:

// $('body').removeAttr('style');
document.querySelector('body').removeAttribute('style');

I used document.querySelector and removeAttribute()

the $.css() is a jquery method, but document.querySelector params need a string as selector

maybe you can use

this.$refs.moduleContainer.style = { ...this.$refs.moduleContainer.style, ...style}

ps: this is a wrong answer

1 Like

style however here is a variable containing data. It is using .css( properties ) with the property being a plain Object. Though odd again that getComputedStyle(this.$refs.moduleContainer)[style] did not cause any errors then as getComputedStyle uses the element in question…

When I tried your code I got these errors:

Property ‘style’ does not exist on type ‘Vue | Element | (Vue | Element)[]’.Property ‘style’ does not exist on type ‘Vue’.Vetur(2339)

ERROR in ./resources/js/components/publish/PublishedModule.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib/index.js??clonedRuleSet-5[0].rules[0].use[0]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./resources/js/components/publish/PublishedModule.vue?vue&type=script&lang=js&)
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/jasperfrumau/code/site.com/app-v3/resources/js/components/publish/PublishedModule.vue: Unexpected keyword 'this'. (110:47)

  108 |           // $(this.$refs.moduleContainer).css(style)
  109 |           // getComputedStyle(this.$refs.moduleContainer)[style]
> 110 |           this.$refs.moduleContainer.style = { this.$refs.moduleContainer.style, ...style}

and current method with the line adjusted using your code:

...
methods: {
    moduleStylePosition: function() {
        let style = this.moduleInstance.getPosition(this.cellSize, this.currentProject[`width${this.platform}`])

        if (this.moduleInstance.isFullWidth && this.moduleInstance.moduleMaxWidth) {
        style['display'] = 'flex'
        style['justify-content'] = this.moduleInstance.moduleAlign
        } else {
        style['text-align'] = this.moduleInstance.moduleAlign
        }

        // $(this.$refs.moduleContainer).css(style)
        // getComputedStyle(this.$refs.moduleContainer)[style]
        this.$refs.moduleContainer.style = { this.$refs.moduleContainer.style, ...style}

    },
...

Oh it’s my fault, HTMLElement.style can’t use simple merge

maybe you can use

for (key in style){
this.$refs.moduleContainer.style[key] = style[key]
}

example run in console

let body = $$("body")[0]
let style = { background:"red",color:"blue"}
for(key in style) { 
  body.style[key]  = style[key]
}
1 Like

As @gausszhou illustrates, you just need to assign the properties within a loop.

Fiddle: https://jsfiddle.net/jamesbrndwgn/t4ckzxf3/

1 Like

Thanks for that example @JamesThomson . The loop indeed looks like the way to go. Will test this this morning. When I go through this all it all seems very logical all of the sudden. Still so much for me to learn. Looked up Object.entries() at MDN some more as well

By the way. I see you added constan const instead of local let. Any reason for that? Just to keep the value fixed / constant / non-updatable? Do not think we need it updated elsewhere and that is I guess why we had let. But makes you realize we may need to use const more often than we do.

Pretty much. It signals that the variable can’t be reassigned. Reassigned being the key word. e.g. a primitive value cannot be mutated, however an object’s properties can.

1 Like

I added changes to the code including using styles instead of style to work in the loop properly and following your suggestion @JamesThomson :

 moduleStylePosition: function() {
  const styles = this.moduleInstance.getPosition(this.cellSize, this.currentProject[`width${this.platform}`])

  if (this.moduleInstance.isFullWidth && this.moduleInstance.moduleMaxWidth) {
    styles['display'] = 'flex'
    styles['justify-content'] = this.moduleInstance.moduleAlign
  } else {
    styles['text-align'] = this.moduleInstance.moduleAlign
  }

  // $(this.$refs.moduleContainer).css(style)
  // getComputedStyle(this.$refs.moduleContainer)[style]

  // moduleContainer
  const moduleContainer = this.$refs.moduleContainer

  Object.entries(styles).forEach(([key, value]) => moduleContainer.style[key] = value);

},

and this seems to work. I reduced current errors from 27 to 9 and can move on to other issues with jQuery $ leftovers. However I still see a Vetur in VS Code warning me about this:

Property ‘style’ does not exist on type ‘Vue | Element | (Vue | Element)[]’.
Property ‘style’ does not exist on type ‘Vue’.Vetur(2339)
any

about this line

Object.entries(styles).forEach(([key, value]) => moduleContainer.style[key] = value);

Perhaps a setting I need to change. But perhaps an issue in my code still?

I want to add some more points based on this so eause while I