skip to Main Content

I have a Vue component ‘FullCart’ with a default slot like so:

<template>
  <div>
    <slot></slot>
  </div>
</template>

This is only used to wrap the cart of a Woocommerce site.

<full-cart :key="componentKey">
  <form>
    <!-- woocommerce cart -->
  </form>
</full-cart>

After updating an item in the cart the view updates through AJAX and the old form gets replaced with the contents of the new form. This behaviour is provided by Woocommerce and out of my hands.

By changing the ‘componentKey’ property, after the new HTML is inserted, the FullCart component is re-rendered and all child components present in the new HTML are rendered by Vue. So far so good. 👍

The problem is that, as soon the component re-renders, any input elements (like item quantities) reset to the values before the AJAX call was made. As if Vue wants to reset to the old state. The values of those input elements is non-reactive data, not present in my app.

So to summarize:

  1. Change item quantity from 2 to 3
  2. Cart refreshes through AJAX
  3. New HTML is inserted into the DOM (not the “Vue-way”)
  4. Change componentKey to re-render the component
  5. Old inputs values are visible.

Does anyone know how to fix this or a way around this?

2

Answers


  1. Chosen as BEST ANSWER

    The thing is, Vue doesn't only reset the value of the input, it resets the entire HTML to the previous state. So the entire new markup gets overwritten by the old markup. I've decided that this is just not the way to go.

    I've recreated the entire Woocommerce cart as a Vue component and now everything is working as expected. No more AJAX calls, everything changes on the fly.


  2. Based on your response in the comments, I think you have a few options.

    The most correct way would probably be to implement a Vuex store and update the variables there before refreshing the form and re-rendering the component. Then pull the variables from the store in either the mounted() or created() method.

    The easier option would be to store the variables in a parent or root component. All Vue instances can access the root data object via this.$root.data. So you could update this.$root.data.quantity, then update and re-render your form component, and then update your quantity field with the value from this.$root.data.quantity.

    Go with the second option if it’s a small or short term project, but the first would likely be considered proper.

    Edit – I’ve updated your fiddle with the method I described above where you store the inputValue in the $root Vue component: https://jsfiddle.net/u39ap2hm/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search