Why is instead of the Vue component some JS comment added to the DOM? - vue.js

I am working with BootstrapVue and am trying to dynamically create components after the site is rendered (I want to use asynchronous data for the generation process later) with Vue and add them to the DOM.
(I am simulating the asynchrony in the demo by creating the components with a 1 second delay after the page is loaded).
This is what happens:
Vue is creating the components and then they should be mounted to the DOM. But sadly they don't show up. Instead this comment: <!--function(e,n,r,i){return Pt(t,e,n,r,i,!0)}--> is added to them DOM (at the correct position though) in place of the actual HTML code of the component.
This is the jsfiddle with example code that demonstrates the problem: https://jsfiddle.net/0stdxorj/1
Thank you for your help :).
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<title>Test</title>
<!-- Bootstrap Core CSS -->
<link
type="text/css"
rel="stylesheet"
href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css"
/>
<!-- Bootstrap Vue CSS -->
<link
type="text/css"
rel="stylesheet"
href="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css"
/>
<!-- Custom CSS -->
<link href="../vrc/vrc.css" rel="stylesheet">
<!-- Using: https://bootstrap-vue.org/ -->
<!-- Load polyfills to support older browsers -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver"></script>
<!-- Vue JS -->
<script src="https://unpkg.com/vue#latest/dist/vue.min.js"></script>
<!-- Bootstrap Vue JS -->
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue-icons.min.js"></script>
<!-- Portal Vue JS -->
<script src="https://unpkg.com/portal-vue#latest/dist/portal-vue.umd.min.js"></script>
<!-- Popper JS -->
<script src="https://unpkg.com/#popperjs/core#2"></script>
<!-- VCalendar JS -->
<script src='https://unpkg.com/v-calendar'></script>
</head>
<body>
<div id="app">
<!-- Application root element -->
<b-container fluid="xl">
<b-row align-h="center" align-v="start" id="card-container">
<!-- Card Inline Template -->
<card inline-template id="card-template">
<b-card
v-bind:title=card.title
img-src="https://picsum.photos/600/300/?image=25"
img-alt="Image"
img-top
style="max-width: 370px; margin: 5px"
class="no-select"
>
<b-button v-b-toggle="'collapse-' + card.id">Button</b-button>
<b-collapse v-bind:id="'collapse-' + card.id" class="mt-2">
<v-calendar
is-expanded
:min-date='new Date()'
>
</v-calendar>
</b-collapse>
</b-card>
</card>
</b-row>
</b-container>
</div>
</body>
</html>
const vue = new Vue({
el: '#app'
})
const cardComponentConstructor = Vue.extend({
props: {
card: {
required: true,
default: {id: 0, title: 'Default.'}
}
},
template: '#card-template',
mounted() {
alert("mounted " + this.card.id + " " + this.card.title)
},
created() {
//alert("created " + this.card.id + " " + this.card.title)
}
});
window.addEventListener("load", function(event) {
setTimeout(function () {
createCard({propsData: {card: {id: 0, title: '0'}}})
createCard({propsData: {card: {id: 1, title: '1'}}})
}, 1000);
});
function createCard(props) {
let componentInstance = new cardComponentConstructor(props)
componentInstance.$mount()
document.getElementById("card-container").appendChild(componentInstance.$el)
}

I fixed the problem by going at it in another way. Vue re-renders v-for tags when using a key attribute (:key="card.id"). So I don't try to manually create the components anymore but make use of this feature and modify the cards data instead, which in turn then makes Vue re-render the deleted/modified/added cards:
Updated jsfiddle with my solution https://jsfiddle.net/t7k49a2n/
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<title>Test</title>
<!-- Bootstrap Core CSS -->
<link
type="text/css"
rel="stylesheet"
href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css"
/>
<!-- Bootstrap Vue CSS -->
<link
type="text/css"
rel="stylesheet"
href="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css"
/>
<!-- Custom CSS -->
<link href="../vrc/vrc.css" rel="stylesheet">
<!-- Using: https://bootstrap-vue.org/ -->
<!-- Load polyfills to support older browsers -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=es2015%2CIntersectionObserver"></script>
<!-- Vue JS -->
<script src="https://unpkg.com/vue#latest/dist/vue.min.js"></script>
<!-- Bootstrap Vue JS -->
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue-icons.min.js"></script>
<!-- Portal Vue JS -->
<script src="https://unpkg.com/portal-vue#latest/dist/portal-vue.umd.min.js"></script>
<!-- Popper JS -->
<script src="https://unpkg.com/#popperjs/core#2"></script>
<!-- VCalendar JS -->
<script src='https://unpkg.com/v-calendar'></script>
</head>
<body>
<div id="app">
<!-- Application root element -->
<b-container fluid="xl">
<b-row align-h="center" align-v="start">
<!-- Card Inline Template -->
<card
inline-template
v-for="card in cards"
v-bind="{card: card}"
:key="card.id"
>
<b-card
v-bind:title=card.title
img-src="https://picsum.photos/600/300/?image=25"
img-alt="Image"
img-top
style="max-width: 370px; margin: 5px"
class="no-select"
>
<b-button v-b-toggle="'collapse-' + card.id">Button</b-button>
<b-collapse v-bind:id="'collapse-' + card.id" class="mt-2">
<v-calendar
is-expanded
:min-date='new Date()'
>
</v-calendar>
</b-collapse>
</b-card>
</card>
</b-row>
</b-container>
</div>
</body>
</html>
Vue.component('card', {
props: {
card: {
required: true,
default: {id: 0, title: 'Default.'}
}
}
});
window.app = new Vue({
el: '#app',
data: {
cards: []
}
})
window.addEventListener("load", function(event) {
setTimeout(function () {
window.app.cards.push({id: 0, title: '1'})
}, 1000);
});

Related

Vuetify instance with cdn not work on vuejs3

I have application on aspnet mvc and import vuejs v3 cdn and i like use vuetify but i dont know how do it.
its my code example
<!DOCTYPE html>
<html lang="en">
<head>
<title>#ViewData["Title"] - MVCAndVue</title>
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://unpkg.com/vue#next"></script>
</head>
<body>
<div class="container">
<main role="main" class="pb-3">
#RenderBody()
</main>
</div>
#await RenderSectionAsync("Scripts", required: false)
</body>
</html>
<script>
const {
ref,
reactive,
} = Vue;
//Define Vue app
const App = {
data() {
return {
};
},
methods: {
},
setup(props, context) {
}
};
// Create new Vue app
const app = Vue.createApp(App);
app.mount("#app");
</script>
You are facing this issue because you included Vuetify 2.x which is not compatible with Vue 3. So, use Vuetify 3 instead.
Now, the right way to use Vuetify via CDNs, you need to follow these steps-
Import Vuetify CSS in your head tag-
<link
href="https://cdn.jsdelivr.net/npm/vuetify#3.0.5/dist/vuetify.min.css"
rel="stylesheet"
/>
If you want to use material design icons, then import this CSS link in your head tag too-
<link
href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css"
rel="stylesheet"
/>
Import the Vuetify script in your body tag-
<script src="https://cdn.jsdelivr.net/npm/vuetify#3.0.5/dist/vuetify.min.js"></script>
If you are planning to use Vue3 also via CDN, then import the Vue script in your body tag-
<script src="https://unpkg.com/vue#3/dist/vue.global.js"></script>
Here is a complete working HTML file with all necessary imported CDNs for Vue3 and Vuetify3-
<!DOCTYPE html>
<html>
<head>
<link
href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css"
rel="stylesheet"
/>
<link
href="https://cdn.jsdelivr.net/npm/vuetify#3.0.5/dist/vuetify.min.css"
rel="stylesheet"
/>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/vue#3/dist/vue.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#3.0.5/dist/vuetify.min.js"></script>
<script type="text/x-template" id="app-template">
<v-app>
<v-card
class="mx-auto"
width="400"
append-icon="mdi-human-greeting"
>
<template v-slot:title>
Title
</template>
<v-card-text>
Description
</v-card-text>
</v-card>
</v-app>
</script>
<script>
const { createApp } = Vue;
const { createVuetify } = Vuetify;
const vuetify = createVuetify();
const app = createApp({
template: "#app-template",
})
.use(vuetify)
.mount("#app");
</script>
</body>
</html>
To read more about using CDNs, read here-
https://next.vuetifyjs.com/en/getting-started/installation/#cdn
https://next.vuetifyjs.com/en/features/icon-fonts/#material-design-icons

Vue html elements not showing correct output

I am following microsoft online Vue tuturial. But following code should be outputting as below html page:
But I am getting this as output not sure why.
Why productName and productDescription are not appearing as string values?
index.js:
const app = Vue.createApp({
data() {
return {
productName: 'Book a Cruise to the Moon',
productDescription: 'Cruise to the moon in our luxurious shuttle. Watch the astronauts working outside the International Space Station.',
// additional properties later
};
},
});
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Relecloud Galaxy Tours</title>
<link rel="stylesheet" href="./assets/styles.css" />
<!-- TODO: Import Vue.js core library -->
<script src="https://unpkg.com/vue#next"></script>
</head>
<body>
<div class="nav-bar"></div>
<h1>Relecloud Galaxy Tours</h1>
<!-- TODO: Add information display -->
<div id="app">
<h2>{{ productName }}</h2>
<div>{{ productDescription }}</div>
</div>
<!-- TODO: Import Vue app -->
<script src="./index.js"></script>
<script>
app.mount('#app');
</script>
</body>
</html>
I tested your code on my computer and it worked for me.
Make sure the file path is correct and try again.
I just copied and pasted.

I'm using and api and it's showing me object Object instead of the variable

as i said in the title, i'm using an api, here is the html
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<!-- JQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- Popper -->
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.9.1/dist/umd/popper.min.js"
integrity="sha384-SR1sx49pcuLnqZUnnPwx6FCym0wLsk5JZuNx2bPPENzswTNFaQU1RDvt3wT4gWFG"
crossorigin="anonymous"></script>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/js/bootstrap.min.js"
integrity="sha384-j0CNLUeiqtyaRmlzUHCPZ+Gy5fQu0dQ6eZ/xAww941Ai1SxSY+0EQqNXNE6DZiVc"
crossorigin="anonymous"></script>
<title>Ejemplo consumo web service con FETCH </title>
</head>
<body>
< <div class="container">
<div class="row">
<button class="btn btn-primary" id="btn-cargar">Cargar InformaciĆ³n</button>
</div>
<div class="row">
<div id="info" class="text-center">
<h1></h1>
</div>
</div>
</div>
<script src="js/carga_1.js"></script>
</body>
</html>
and here is the code of the js
$("#btn-cargar").click(function (event) {
event.preventDefault();
var url = "https://api.punkapi.com/v2/beers/random";
fetch(url)
.then(response => response.json())
.then(data =>
{
var $nombre_cerveza = $('<h1>').text(data[0].name);
var $grados = "Grados: " + $('<p>').text(data[0].abv);
var $foto_cerveza = $("<p><img src='"+data[0].image_url+"'>");
$("#info").empty();
$('#info')
.append($nombre_cerveza)
.append($grados)
.append($foto_cerveza);
})
.catch(error => console.error(error));
});
it shows me the name as it should, but in the abv it shows "Grados: [object Object]" and i want it to show the abv in numbers, does anyone knows a way to fix this?
i'm sorry that all of it is in spanish

Integrating VueJS into ASP.NET Core without nodejs, webpack, or npm

Due to security reasons we cannot install nodejs and any package managers. THerefore, I am trying to build my SPA with cdn support only. However, I am struggling to get it to work as I keep getting the failed to mount template error when running my code. I am using ASP.NET core 3.1 and i am able to get to the page to load up my partial views showing the side navigation and top navigation items. The page loads up and the router seems to work in changing the url in browser but the view components for the actual page templates do not show up on the screen. For instance dashboard view should show up but does not and therefore i believe this is where the issue is but I cannot see any issues with my code.
My code is as follows:
_vueapp:
<!DOCTYPE html>
<html lang="en">
<head>
#RenderSection("Styles", required: false)
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>#ViewData["Title"] - ARMS 2.0</title>
<link rel="stylesheet" href="~/css/sidebar.css" />
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous" />
</head>
<body>
#RenderBody()
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
#RenderSection("Scripts", required: false)
</body>
</html>
index file
#page
#model ARMS_2._0_LOCAL.Pages.vue.IndexModel
#{
Layout = "_Vueapp";
}
<div id="app" v-cloak>
<side-navigation></side-navigation>
<top-navigation></top-navigation>
<router-view></router-view>
</div>
#section Scripts
{
<partial name="components/side-navigation" />
<partial name="components/top-navigation" />
<partial name="views/dashboard" />
<partial name="views/reviews" />
<script>
//setup routing using SPA VUE interface
Vue.use(VueRouter);
const routes = [
{ path: '/', component: dashboard },
{ path: '/reviews', component: reviews }
]
const router = new VueRouter({
routes // short for `routes: routes`
})
var app = new Vue({
el: '#app',
router
}).$mount('#app')
</script>
}
side-navigation:
<style>
</style>
<template id="side-navigation">
<div>
<router-link to="/">Home</router-link>
<router-link to="/reviews">Reviews</router-link>
</div>
</template>
<script>
Vue.component('side-navigation', {
template: '#side-navigation'
})
</script>
one of my views which is dashboard:
<style>
</style>
<template id="dashboard">
<div>
<h1>dashboard</h1>
</div>
</template>
<script>
Vue.component('dashboard', {
template: '#dashboard'
})
</script>
You need to assign the components (dashboard and reviews) to a constant, otherwise the router can not recognize them.
dashboard:
<style>
</style>
<template id="dashboard">
<div>
<h1>dashboard</h1>
</div>
</template>
<script>
const dashboard = Vue.component('dashboard', {
template: '#dashboard'
})
</script>
reviews:
<style>
</style>
<template id="reviews">
<div>
<h1>reviews</h1>
</div>
</template>
<script>
const reviews = Vue.component('reviews', {
template: '#reviews'
})
</script>

Why Failed to show markdown-editor using VueSimpleMDE by CDN?

Why the following code failed to show the markdown-editor?
Why Failed to show markdown-editor using VueSimpleMDE by CDN?
<html>
<head>
<script src="https://cdn.bootcss.com/vue/2.4.4/vue.min.js"></script>
<link href="https://unpkg.com/simplemde#1.11.2/dist/simplemde.min.css" rel="stylesheet">
<script src="https://unpkg.com/simplemde#1.11.2/dist/simplemde.min.js"></script>
<script src="https://unpkg.com/vue-simplemde#0.4.6/dist/vue-simplemde.min.js"></script>
</head>
<body>
<script>
Vue.use(VueSimpleMDE);
</script>
<div id="vue-app">
{{ content }}
<markdown-editor v-model="content" ref="markdownEditor"></markdown-editor>
</div>
<script>
var vue = new Vue({ "el": "#vue-app", data: { content: "kdfljads" } });
</script>
</body>
</html>