passing an object in ejs to a vue method - vue.js

in an Express app, I need to pass an object to vue method, here is the ejs template:
<%-item.price%>
<button v-on:click="add_to(<%=item%>)" class="float-right">Add...</button>
here is the js:
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
add_to: function (item) {
console.log(item)
}
}
})
but it does not work, any hint? Thanks

You need to enclose the ejs rendering the object you want to pass to the vue.js method with single quote ''
v-on:click="add_to('<%=item%>')"

Related

How do I use a non-Vue custom Web Component in a Vue Component (without Webpack)?

I have the following code...
<html>
<head></head>
<body>
<div id="app">
{{ message }}
<jrg-element></jrg-element>
</div>
<script type="module">
import Vue from "//unpkg.com/vue/dist/vue.esm.browser.js";
import {ShadowElement, CREATE_ELEMENT} from "//unpkg.com/#jrg/ui/target/jrg-ui.esm.mjs";
class JrgElement extends ShadowElement {
constructor() {
super("<h1>CustomElement</h1>");
this.render();
}
}
CREATE_ELEMENT("jrg-element", JrgElement, {});
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
But when I run I get....
If I comment out the Vue portion everything works fine. How do I use Custom elements with Vue?
Update
I tried updating to ...
CREATE_ELEMENT("jrg-element", JrgElement, {});
Vue.config.ignoredElements = ['jrg-element']
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
But I still get...
The result is the Vue element renders but the custom element does not.
Full Code
Update 2
I tried waiting until the dom is loaded like...
document.addEventListener("DOMContentLoaded", function() {
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
});
But same outcome
With Vite 2, it's like this:
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: tag => tag === 'jrg-element'
}
}
})
],
Source: https://github.com/vitejs/vite/issues/1312
Vue templates (content of app div in your case) are compiled by Vue template compiler and expects all custom elements are Vue components and properly registered. In order to tell Vue that you are using some non-Vue custom element (Web Components API), you need to configure compiler.
Vue 2.x
Vue.config.ignoredElements = ['jrg-element']
Vue 3
const app = Vue.createApp({})
app.config.isCustomElement = tag => tag === 'jrg-element'
The docs

How to access data from outside the instance in Vue js?

I'd like to get access to vm data from outside the instance like so:
myComponent.vue
export default {
data() {
return {
name: 'Joe'
};
}
}
main.js
var vm = new Vue({
el: '#app',
render: h => h(myComponent)
});
Desired Result
console.log(vm.name); // should return - Joe
For some reason, console returns undefined. What I'm doing wrong?
To access vue.js object datas from inside you can use $property_name. Example
var vm = new Vue({
el: '#app',
data() {
return {
name: "Kapucni",
}
},
template: '<div>{{ name }}</div>'
});
// use $name .property
console.log(vm.$data.name);
console.log(vm.$el);
// calling functions from $method, etc ...
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.js"></script>
<div id='app'>
</div>
Thanks to comments from ittus, I realised that I have to look for child components, not the root component.
We can get to child component like so:
vm.$children[0].name
where $children[0] is a direct (and first in this case) child of the root component.

Accessing data inside a render function of a functional vuejs component

I'm trying to use a functional component to render multiple elements without having to have a single root element but I can't seem to have access to the component data, see this simplified example:
Trying to access context.data logs an empty object {}:
<div id="app">
<hello />
</div>
Vue.component('hello', {
functional: true,
render: function(h, context) {
console.log(context.data) // This logs {}
return new Array(5).fill(1).map((_, index) => h('p', {}, 'Hello world'))
},
data () {
return {
foo: 'bar'
}
}
})
new Vue({
el: '#app',
data: function() {
return {
foo: '<p>foo</p>',
bar: 'bar'
}
}
})
A working jsfiddle
Thanks in advance
A functional component has no data which is why it does not receive data in the context. You can find additional information in this section of the manual
If you want to render a component without having to use a single root element you might want to give vue-fragment a try.

VueJs async template/component with placeholder

I am pretty new to VueJs, so I am still figuring things out.
Since our templates are stored in the database, I want my templates to load async. For my components I now use the component-factory approach.
var c = Vue.component('my-async-component', function(resolve, reject){
setTimeout(function(){
resolve({
template: '<div class="loader">loaded asynchronous: {{ pageName }}</div>',
data() {
return {
pageName: 'my Page'
}
}
})
},2000)
})
But is it possible to have some kind of placeholder while loading it? I know I can do something with But in that case I need to have a parent component and I would like this to be independent.
On a Vue-instance you can do stuff in the render function end hook it up to mounted like:
var app = new Vue({
el: '#app',
data: {
finish: false,
template: null
},
render: function(createElement) {
if (!this.template) {
return createElement('div', 'loading...');
} else {
return this.template();
}
},
mounted() {
var self = this;
$.post('myUrl', {foo:'bar'}, function(response){
var tpl = response.data.template;
self.template = Vue.compile(tpl).render;
})
}
})
Is this possible in a component? And is this still working when I have some nested divs (see an other question of mine: here)
Ok, I figured it out. I just needed to reed de VUE guide a little bit bettter.
I just followed the advanced async example from the docs and now I have a working example.
So I have my template like this:
<div id="app">
<my-async-component></my-async-component>
</div>
Then in my JS I declared the template like:
var c = Vue.component('my-async-component', function(){
return {
component: new Promise(function(resolve, reject){
// setTimeout to simulate an asynchronous call
setTimeout(function(){
resolve({
template: '<div class="loader">loaded asynchronous</div>'
})
},3000)
}),
loading: Vue.component('loader', {
template: '<p>loading...</p>'
}),
error: Vue.component('load-error', {
template: '<p>error loading component</p>'
}),
delay: 200,
timeout: 10000
}
})
var vm = new Vue({
el: '#app'
});
The loading and error components could also be globally registered components, so it's easy to reuse.
Hopefully I could help someone with this answer to my own question.

Converting data to props for root component in Vue.js 2

This must be simple, but haven't cracked it...
In vue, I think I get how to pass props from parent to child components. And I understand that I have an app state in the data member of the vue instance. What I don't understand is how to get the data state into the root app as props.
It seems there are a few ways to organize a vue app, so here's what I'm trying to make work:
index.ts
import app from './app.vue'
export default new Vue({
// App Root Element
el: '#app',
render: (c) => c('app'),
components: {
app
},
data: {
someValue: 42
}
})
app.vue
<template>
<div>
Some Value: {{someValue}}
</div>
</template>
<script lang="ts">
export default {
props: ['someValue']
};
</script>
I assume it should be something like the following, but I don't know how to get a reference directly to the data - unless I keep a reference to it outside of vue for this purpose, but that seems like it should not be necessary:
render: (c) => c('app', { someValue: ??? }),
Use this to get data or property values inside your render method (or methods or computed values, etc). Don't use an arrow function to define your render function if you're going to use this inside it.
new Vue({
el: "#app",
render(c) {
return c('app', {props:{someValue: this.someValue}})
},
components: {
app
},
data: {
someValue: 42
}
})
Example.
console.clear()
const app = {
props: ["someValue"],
template: `<div>Some Value: {{someValue}}</div>`
}
new Vue({
el: "#app",
render(c) {
return c('app', {props:{someValue: this.someValue}})
},
components: {
app
},
data: {
someValue: 42
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
</div>
As #RoyJ pointed out, this is the key section of the documentation.