vuejs not showing the value inside {{ }} , the text is displayed as it is - vue.js

I developed a vuejs program and run the npx serve command. I go to the directory and run npx serve. I browse the http://localhost:300/myvuefile.html , I get the following output only.
{{count}} inside the button. My code :
<script src="https://unpkg.com/vue#3/dist/vue.global.js"></script>
<div id="app">
<button #click="count++">{{ count }}</button>
</div>
<script>
import { createApp } from 'vue'
const app = createApp({
data() {
return {
count: 0
}
}
})
app.mount('#app')
</script>
I have to get the value of the count and onclick the count should increment. Instead I get the output as {{count}} only. Please help to fix this issue.

According to the documentation-
When using the global build of Vue, all top-level APIs
are exposed as properties on the global Vue object.
So, either use like this-
const app = Vue.createApp({
data() {
return {
count: 0
}
}
})
app.mount('#app')
<div id="app">
<button #click="count++">{{ count }}</button>
</div>
<script src="https://unpkg.com/vue#3/dist/vue.global.js"></script>
Or use like this-
const { createApp } = Vue
const app = createApp({
data() {
return {
count: 0
}
}
})
app.mount('#app')
<div id="app">
<button #click="count++">{{ count }}</button>
</div>
<script src="https://unpkg.com/vue#3/dist/vue.global.js"></script>

Related

How to get $el in petite vue

From the example inside the petite vue repo:
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
// exposed to all expressions
count: 0,
// getters
get plusOne() {
return this.count + 1
},
// methods
increment() {
this.count++
}
}).mount()
</script>
<div v-scope>
<p>{{ count }}</p>
<p>{{ plusOne }}</p>
<button #click="increment">increment</button>
</div>
When I am trying to get a p tag like so:
<p ref="foobar">{{ count }}</p>
This returns an error, since this.$refs.foobar is undefined:
increment() {
console.log(this.$refs.foobar.$el)
this.count++
}
How can I get the HTML element inside my javascript through $el?
Credits to #kissu for pointing me to the right discussion form, where I found the answer.
So apparently $refs only works inside of the "component" concept within petite vue.
If you have the following snippet, from the docs, with a ref added to the p tag:
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
function Counter(props) {
return {
count: props.initialCount,
inc() {
this.count++
},
mounted() {
console.log(`I'm mounted!`)
}
}
}
createApp({
Counter
}).mount()
</script>
<div v-scope="Counter({ initialCount: 1 })" #vue:mounted="mounted">
<p ref="foobar">{{ count }}</p>
<button #click="inc">increment</button>
</div>
You'll be able to do:
this.$refs.foobar from within that function, to get the element. Note: $el is not needed.

Vue 3 - cannot name ref same as prop - why?

If I define a property with the name 'foobar' and then try to create a ref with the name 'foobar', Vue complains that 'foobar' is undefined when I try to access that ref. This only happens when building the vue app e.g. npm run build, but not when serving it e.g. npm run dev. I'm not sure if it happens with Vue 2.
I can fix the issue simply by naming them different things but I am curious as to why this happens as there's nothing in the docs about it?
<script setup>
defineProps({
foobar: {
type: String
}
})
</script>
<template>
<div>
<div ref="foobar">
{{ foobar }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
}
},
mounted() {
// error!
const el = this.$refs.foobar;
}
}
</script>
No error:
<script setup>
defineProps({
foobar: {
type: String
}
})
</script>
<template>
<div>
<div ref="foobar2">
{{ foobar }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
}
},
mounted() {
// no error!
const el = this.$refs.foobar2;
}
}
</script>

How to use template refs in Nuxt 3

In Nuxt2 there were template $refs that you could access in <script> with this.$refs
I would like to know what is the Nuxt3 equivalent of this is.
I need this to access the innerText of an element. I am not allowed to use querySelector or getElementById etc.
This is the way we write code. I can give html elements ref="fooBar" but I can't access it with this.$refs.fooBar or even this.$refs.
<script setup lang="ts">
import { ref, computed } from 'vue';
const foo = ref('bar');
function fooBar() {
//Do stuff
}
</script>
<template>
//Html here
</template>
With Options API
<script>
export default {
mounted() {
console.log('input', this.$refs['my-cool-div'])
}
}
</script>
<template>
<div ref="my-cool-div">
hello there
</div>
</template>
With Composition API
<script setup>
const myCoolDiv = ref(null)
const clickMe = () => console.log(myCoolDiv)
</script>
<template>
<button #click="clickMe">show me the ref</button>
<div ref="myCoolDiv">
hello there
</div>
</template>

Vue3 Components in a Separate File

I have an app that I am porting from Vue2 to Vue3. I am not using a bundler as Vue is just providing simple interactivity on a page. This is the simplified version in Vue2:
// my-modal.js
var myModal = Vue.component('my-modal',
{
template:
`<div id="myModal">
<button #click.prevent="open=true">Open Modal</button>
<div v-if="open" class="my-modal">
<p>Hello from the modal!</p>
<button #click.prevent="open=false">Close</button>
</div>
</div>`,
data() {
return {
open: false
}
}
})
In Vue 2 this Works;
<script src="https://unpkg.com/vue#2"></script>
<div id="app">
<div class="outer">
<h3>Modal Example - {{ message }}</h3>
<div>
<my-modal />
</div>
</div>
</div>
<script src="/js/my-modal.js"></script>
<script>
const app = new Vue(
{
el: '#app',
data() {
return {
message: 'Hello Vue!'
}
}
});
</script>
For Vue3, per the documentation at: https://v3-migration.vuejs.org/breaking-changes/global-api.html#a-new-global-api-createapp I switched things over to what I expected would work:
<script src="https://unpkg.com/vue#3"></script>
<div id="app">
<div class="outer">
<h3>Modal Example - {{ message }}</h3>
<div>
<my-modal />
</div>
</div>
</div>
<script src="/js/my-modal.js"></script>
<script>
Vue.createApp({
data()
{
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
and in the my-modal.js file I changed the first few lines to use the Global Vue:
const { createApp } = Vue;
const app = createApp({});
app.component('my-modal', ...
The Vue instance works but the component is not found with the error message: "Failed to resolve component: my-modal". I tried adding a 'components' section to the Vue instance and a few other things with no luck.
Any suggestions?
Each instance from createApp() is unique. That is, calling createApp() in index.html does not return the same instance from the previous call in my-modal.js.
One solution is to declare the global app instance before importing my-modal.js:
<!-- index.html -->
<script>
window._app = Vue.createApp({⋯})
</script>
<script src="/js/my-modal.js"></script>
<script>
// finally mount
window._app.mount('#app')
</script>
// js/my-modal.js
window._app.component('my-modal', {⋯})
demo

vuejs 3 data options property no more reactive with external object

I have an app that shares an external module with other applications by sharing a global javascript object.
One of these apps is developed with vue 2 and when the global object is updated in the external module, the option data property of vue 2 is updated perfectly while in vue 3 it is not. I also tried with the new reactive property but nothing to do, is it a bug?
Not being able to make any changes to the external module because it is shared with other apps, how can I make it work in vue 3?
Here are some test links:
Vue 2 share external object
<script src="https://unpkg.com/vue"></script>
<script>
var EXTERNAL_OBJECT={
name:"Bob",
list:[{name:"Ivan"}]
}
function change_object(){
EXTERNAL_OBJECT.name+="+++"
EXTERNAL_OBJECT.list.push({name:"Carl"})
}
</script>
<button onClick="change_object()">change external object</button>
<div id="app">
<div>
{{share.name}}
</div>
<div v-for="item in share.list">
{{item.name}}
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
share:EXTERNAL_OBJECT
}
})
</script>
Vue 3 share external object
<script src="https://unpkg.com/vue#3.2.4/dist/vue.global.js"></script>
<script>
var EXTERNAL_OBJECT={
name:"Bob",
list:[{name:"Ivan"}]
}
function change_object(){
EXTERNAL_OBJECT.name+="+++"
EXTERNAL_OBJECT.list.push({name:"Carl"})
}
</script>
<button onClick="change_object()">change external object</button>
<div id="app">
<div>
{{share.name}}
</div>
<div v-for="item in share.list">
{{item.name}}
</div>
</div>
<script>
const app = Vue.createApp({
data () {
return {
share:EXTERNAL_OBJECT
}
}
});
app.mount('#app')
</script>
Vue 3 share external object with reactive property
<script src="https://unpkg.com/vue#3.2.4/dist/vue.global.js"></script>
<script>
var EXTERNAL_OBJECT={
name:"Bob",
list:[{name:"Ivan"}]
}
function change_object(){
EXTERNAL_OBJECT.name+="+++"
EXTERNAL_OBJECT.list.push({name:"Carl"})
}
</script>
<button onClick="change_object()">change external object</button>
<div id="app">
<div>
{{share.name}}
</div>
<div v-for="item in share.list">
{{item.name}}
</div>
</div>
<script>
const { createApp, reactive } = Vue
const app = createApp({
setup(){
let share = reactive(EXTERNAL_OBJECT)
return {
share
}
},
data () {
return {
msg:"reactive test"
}
}
});
app.mount('#app')
</script>
thanks
It is a bit hard to read ... I just look at the Vue3 Example.
How many file are you showing?
Cant write your EXTERNAL_OBJECT directly in the reactive property? Like:
const EXTERNAL_OBJECT = reactive({ name:"Bob",
list:[{name:"Ivan"}] });