setData does not force a re-render of the component when using v-model, data(), and a computed property
See original GitHub issueVersion
1.0.0-beta.13
Reproduction link
https://github.com/s-robertson/vtu-setdata
Steps to reproduce
Create a new Vue component with the following criteria:
- Have
data()
return an object containing an empty string, e.g.msg
- Have a computed property that returns a boolean depending on if
msg
is empty or not. E.g.hasMsg
- Have an
<input>
in the component template that usesv-model
, bound tomsg
- Have an element, such as an
<h1>
in the component template that usesv-if
, bound tohasMsg
. This element must come AFTER the<input>
in the template
Now write a unit test that:
- Mounts the component via
shallow()
- Calls
setData
and setsmsg
to a non-empty string - Checks to see if the template contains the
<h1>
Finally, run the unit test.
What is expected?
Calling setData
will cause the component to re-render, making hasMsg
be true
and the test will pass.
What is actually happening?
Calling setData
does not cause the component to re-render. The unit test cannot find the <h1>
element and fails:
FAIL tests/unit/HelloWorld.spec.js
HelloWorld.vue
✕ renders props.msg when passed (36ms)
● HelloWorld.vue › renders props.msg when passed
expect(received).toBe(expected) // Object.is equality
Expected value to be:
true
Received:
false
9 | wrapper.setData({ msg });
10 |
> 11 | expect(wrapper.contains('h1')).toBe(true);
12 | })
13 | });
14 |
at Object.<anonymous> (tests/unit/HelloWorld.spec.js:11:36)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 1.062s
Ran all test suites.
ERROR jest exited with code 1.
error Command failed with exit code 1.
What’s interesting is that the order of the <input>
and <h1>
in the template matters. If the <h1>
comes before the <input>
the test will also pass.
You can also get the test to pass by forcefully updating the component via wrapper.vm.$forceUpdate();
after you’ve called setData
.
Issue Analytics
- State:
- Created 5 years ago
- Comments:18 (6 by maintainers)
Top Results From Across the Web
Vue computed property updated, but component did not re ...
But what can explain that the computed property did update correctly, but the component did not re-render? How to fix it? Someone mentioned...
Read more >Reactivity in Depth - Vue.js
We can debug computed properties by passing computed() a second options object with onTrack and onTrigger callbacks: onTrack will be called when a...
Read more >Maintaining a single source of truth while handling form data ...
Set data using a activeUser watcher with deep: true — However, I decided it's probably best not to use a watcher if a...
Read more >How to detect page is refreshed on vue? How can Vue router
Vue users should use the official @vitejs/plugin-vue-jsx plugin, ... after change vmodel data; how to reload automaticaly in vue; rerender a vue component; ......
Read more >Using Vue.js event emitters to modify component data
Editor's note: This article was updated on 4 April 2022 to demonstrate modifying component data using Vue.js v.3 and Composition API.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@onomojo @rafaoliverce what do your tests look like? Are you using
await wrapper.vm.$nextTick()
in your tests? There was a large breaking change in v30 to remove sync mode. This requires you to await for Vue to finish the next event loop after each change that will affect the DOM.Here are the current docs on it https://vue-test-utils.vuejs.org/guides/testing-async-components.html#updates-applied-by-vue
I’ve found that sometimes I have to use an
async
function and callawait
onsetData
andsetProps