Reputation: 767
I migrate from Vue 2 to Vue 3 code. And I have a problem with computed properies.
html:
<div id="cartStatePopupApp" v-if="isShow"> <!-- v-show="isShow" does not work too -->
<button v-on:click="change()">change</button>
<span >{{ isShow }}</span>
</div>
js:
import { createApp } from '../../lib/vue/dist/vue.esm-browser.js';
const app = createApp({
data() {
return {
isShowed: true,
};
},
computed: {
isShow() {
debugger;
return this.isShowed;
}
},
methods: {
change() {
this.isShowed = !this.isShowed;
}
}
});
app.mount('#cartStatePopupApp');
Vue devtool show as change properties:
but component does not hide. How fix it? Any ideas
Upvotes: 1
Views: 42
Reputation: 2191
Your computed value is fine. The issue is that Vue 3 replaces the innerHTML
of the mounted element, not the element itself. Consequently, doing Vue things, like v-if
, will not affect it. In your case, the v-if
is placed on the exact mounted element, which Vue does not process. On the contrary, Vue 2 replaces the mounted component.
The following example demonstrates it clearly:
<div id="cartStatePopupApp" v-if="false"> ...
As a rule of thumb, ignore the mounted element and do not manipulate it. However, defining class, style, or other pure HTML and CSS stuff is fine.
You can achieve the same result by template
:
<div id="cartStatePopupApp">
<template v-if="isShow">
<button v-on:click="change">change</button>
<span>{{ isShow }}</span>
</template>
</div>
Live template:
const { createApp } = Vue;
console.log('Hello world');
createApp({
data() {
return {
isShowed: true,
};
},
computed: {
isShow() {
return this.isShowed;
},
},
methods: {
change() {
this.isShowed = !this.isShowed;
}
},
}).mount('#cartStatePopupApp');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.4.8/vue.global.min.js"></script>
<div id="cartStatePopupApp">
<template v-if="isShow">
<button v-on:click="change">change</button>
<span>{{ isShow }}</span>
</template>
<button v-on:click="change">(restore)</button>
</div>
Upvotes: 0
Reputation: 4849
I don't think you can put v-if
on the root element.
I've provided a snippet below where it works, if you create a wrapper element.
const { createApp, ref } = Vue
const app = createApp({
data() {
return {
isShowed: true,
};
},
computed: {
isShow() {
debugger;
return this.isShowed;
}
},
methods: {
change() {
this.isShowed = !this.isShowed;
}
}
});
app.mount('#cartStatePopupApp');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.4.8/vue.global.min.js"></script>
<div id="cartStatePopupApp">
<div v-if="isShow">
<button v-on:click="change()">change</button>
<span >{{ isShow }}</span>
</div>
</div>
Upvotes: 1