skip to Main Content

I am trying to resize a DIV block using Vue3 but the button when I click it brings up an "Cannot read properties of undefined (reading ‘style’)". I know the JS part is wrong, but how do I correct it.

Here’s the HTML part of the code

<div ref="block2">
<button v-on:click="changeWidth()"></button>
</div>

Heres the JS:

methods: {
    changeWidth:function()
            this.$refs.block2.style.width = "150px";
         }     
}

And this is the CSS styling on the DIV:

#block2{
    position:absolute;
    z-index:5000;
    width:50px;
    height:50px;
    background-color: #7d7d7d;
    transition: all .3s ease-in;
}

Any help really appreciated

3

Answers


  1. Chosen as BEST ANSWER

    Silly, I just needed to add

    id="block2"
    
    All working fine....
    

  2. You are correct, the JS has the problem also the HTML.
    This is the correct code:
    HTML:

    <div ref="block2" id="block2">
      <button v-on:click="changeWidth()">Resize</button>
    </div>
    

    JS:

    methods: {
      changeWidth: function() {
        const block2 = this.$refs.block2[0]; // Access the actual DOM element
        if (block2) {
          block2.style.width = "150px"; // Set the width property
        } else {
          console.error("Element with ref 'block2' not found");
        }
      }
    }
    

    I hope it helps:)

    Login or Signup to reply.
  3. Since you want to perform the operation on button press, in my examples, there is always a variable to capture the current state and a variable for the input field. Of course, it could also be made dynamic so that resizing occurs simply when the input field changes without the need for a button press.

    In Vue 3, I recommend abandoning the use of the Options API that was popular in Vue 2 and instead follow the guidelines of the Composition API. It lends a much more dynamic coding style to Vue.

    Solution # 1: Resizing using the REF Element

    I declared the container as a ref named container. Additionally, I created a resize() function that runs on button press. At that point, I pass the value of currentValue to the style.width and style.height attributes of the ref component.

    const { createApp, ref } = Vue
    
    const app = createApp({
      setup() {
        const container = ref(null)
        const currentValue = ref(100)
        
        const resize = () => {
          container.value.style.width = `${currentValue.value}px`
          container.value.style.height = `${currentValue.value}px`
        }
        
        return { currentValue, container, resize }
      },
    }).mount('#app')
    .container {
      width: 100px;
      height: 100px;
      background: #363635;
      color: #fff;
      margin: 20px 0;
      overflow: hidden;
    <script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
    
    <div id="app">
      <div ref="container" class="container"></div>
      
      <input v-model="currentValue" type="number" min="1">
      <button @click="resize">Resize container to {{ currentValue }}px</button>
    </div>

    Solution # 2: Resizing using the CSS attributes

    I declared a variable called nowValue, in which I store the current pixel size of the container. I created a resize() function that runs on button press and copies the value of currentValue from the input into the nowValue variable. There are various ways to use nowValue in the CSS code; currently, I simply passed the values in a style HTML attribute. This way, when nowValue is updated, the DOM automatically takes on the new values.

    const { createApp, ref } = Vue
    
    const app = createApp({
      setup() {
        const nowValue = ref(100)
        const currentValue = ref(100)
        
        const resize = () => {
          nowValue.value = currentValue.value
        }
        
        return { currentValue, nowValue, resize }
      },
    }).mount('#app')
    .container {
      width: 100px;
      height: 100px;
      background: #363635;
      color: #fff;
      margin: 20px 0;
      overflow: hidden;
    <script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
    
    <div id="app">
      <div class="container" :style="{ width: `${nowValue}px`, height: `${nowValue}px` }"></div>
      
      <input v-model="currentValue" type="number" min="1">
      <button @click="resize">Resize container to {{ currentValue }}px</button>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search