I am trying to get to a point where I can have multiple component types being rendered within a single parent. It's not something which is easy to search for answers on.
I know that it is differentiating the components by adding something to the templates to distinguish them, but if I pass data as you'll see below, I get nothing, any tips?
Edit: I also don't want to have to render out these components in the HTML for this to work, needs to be passed in via JS.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app">
<component v-for="widget in widgets" :is="widget.type"></component>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script>
Vue.config.debug = true
Vue.component('component-a', {
template: '<p>{{foo}}</p>',
props: ['foo',]
});
Vue.component('component-b', {
template: '<p>{{bar}}</p>',
props: ['bar',]
});
new Vue({
el: "#app",
data: {
widgets: [
{
type: "component-a",
foo: 'Hello'
},
{
type: "component-b",
bar: "World",
},
]
}
});
</script>
</body>
</html>
The issue is that you're not passing any props for the foo and bar elements
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app">
<component v-for="widget in widgets" :is="widget.type" :foo="widget.foo" :bar="widget.bar"></component>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script>
Vue.config.debug = true
Vue.component('component-a', {
template: '<p>{{foo}}</p>',
props: ['foo',]
});
Vue.component('component-b', {
template: '<p>{{bar}}</p>',
props: ['bar',]
});
new Vue({
el: "#app",
data: {
widgets: [
{
type: "component-a",
foo: 'Hello'
},
{
type: "component-b",
bar: "World",
},
]
}
});
</script>
</body>
</html>
jsFiddle
In your example the components are rendering with empty strings so you're not seeing the values you're trying to pass. when using interchangeable components it's often best to use a common value interface. Something along the lines of:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app">
<component v-for="widget in widgets" :is="widget.type" :value="widget.value"></component>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script>
Vue.config.debug = true
Vue.component('component-a', {
template: '<p>{{value.foo}}</p>',
props: ['value',]
});
Vue.component('component-b', {
template: '<p>{{value.bar}}</p>',
props: ['value',]
});
new Vue({
el: "#app",
data: {
widgets: [
{
type: "component-a",
value: {
foo: 'Hello'
}
},
{
type: "component-b",
value: {
bar: "World",
}
},
]
}
});
</script>
</body>
</html>
So that the components only pass the single value object to the component necessary and the component pulls the unique values from that object.
Related
I'm pretty new in Vue and I'm trying to write down a function that returns true or false on a given data when input modified. I have 4 different data that I need possibly to change the truthiness.
My logic was to produce a function that accepts data as parameter but... It doesn't work. Maybe it's not the proper way to go for...
Here the HTML:
<input type="text" v-model="bannerContent.button" #input="checkMaxChar(48,bannerContent.button.length,isButtonTooLong)" id="banner-button">
And the JS
var app = new Vue({
el: '#app',
data: {
bannerContent: {
title : 'Title',
text: 'Text',
copyright: 'Copyright',
button: 'Button'
},
isButtonTooLong: false,
},
methods: {
checkMaxChar: function(a,b,c) {
var vm = this
if( a < b ) {
vm.c = true;
};
console.log(this.c);
}
}
})
I'm not sure why you are doing var vm = this and also where do you defined c?
for your purpose define c in the data section like code below and work wit your input:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<input
type="text"
v-model="bannerContent.button"
#input="checkMaxChar(48,bannerContent.button.length,isButtonTooLong)"
id="banner-button"
/>
</div>
</body>
<script>
var app = new Vue({
el: "#app",
data: {
bannerContent: {
title: "Title",
text: "Text",
copyright: "Copyright",
button: "Button",
},
isButtonTooLong: false,
c: false,
},
methods: {
checkMaxChar(a, b, c) {
if (a < b) {
this.c = true;
}
console.log(this.c);
},
},
});
</script>
</html>
Hope it helps You ;)
im learnign VUE JS and I dont understand this behavior (strange for me).
I want to get list of people in table via Vue component.
Html tag table is under the list.
Documentation says: Every compoment must have one single root, ok I can wrap each tr with tbody but it doesnt solve this problem.
How to solve it?
<html>
<head>
<link rel="stylesheet" href="index.css">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<table>
<row
v-for="people in peoples"
v-bind:people="people"
v-bind:key="people.id">
</row>
</table>
</div>
<script>
Vue.component('c-tr', {
template: '<tr></tr>'
});
Vue.component('row', {
props: ['people'],
template: '<tr><td>{{ people.name }}</td></tr>'
});
var app = new Vue({
el: '#app',
data: {
peoples: [
{ id: 20, name: 'Roman' },
{ id: 30, name: 'Vasek' },
{ id: 40, name: 'Ondra' }
]
}
})
</script>
</body>
</html>
I am working on a site where the user can select an image via radio selection.
I would like to dynamically update the image URL depending on selection of the user. My approach is to use a computed variable which returns the URL from a list of objects depending on the selection of the user.
<template>
<v-img
:src="require(currBackgroundURL)"
class="my-3"
contain
width="397"
height="560"
></v-img>
</template>
<script>
// data() ...
currBackground: 0,
backgrounds: [
{
name: "Flowers",
url: "../assets/background/bg_1.png"
},
// ...
computed: {
currBackgroundURL: function() {
return this.backgrounds[this.currBackground].url
}
}
</script>
Unfortunately, i get an error which says Critical dependency: the request of a dependency is an expression.
And the browser console says: [Vue warn]: Error in render: "Error: Cannot find module '../assets/background/bg_1.png'"
Question: What is the right way to switch the URL of the image dynamically?
Thanks for your help!
Here is a working example:
var app = new Vue({
el: '#app',
data: () => ({
currBackground: 0,
backgrounds: [
{
name: "black",
url: "https://dummyimage.com/600x400/000/fff"
},
{
name: "blue",
url: "https://dummyimage.com/600x400/00f/fff"
},
{
name: "red",
url: "https://dummyimage.com/600x400/f00/fff"
}
]
}),
computed: {
currBackgroundURL: function() {
return this.backgrounds[this.currBackground].url
}
},
methods: {
nextImage() {
this.currBackground += 1
if (this.currBackground > 2) {
this.currBackground = 0
}
}
}
})
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.18/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>
<div id="app">
<v-btn #click="nextImage()">Change image</v-btn>
<v-img
:src="currBackgroundURL"
class="my-3"
contain
width="397"
height="560"
></v-img>
</div>
</body>
I removed the require.
The src is a link/path so you don't need require. require will try to take a path and load it into a module instead of a link/path.
Hopefully, this helps.
I am trying to implement a Vue Component with a custom render function.
As soon as my template has nested HTML elements, i get this error:
TypeError: this.$options.staticRenderFns is undefined
How do I implement staticRenderFns?
Code:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<comp temp="temp1"></comp>
</div>
<script>
var myTemplates = new Array();
myTemplates['temp1'] = Vue.compile("<div><div>This template will come from an AJAX source</div></div>").render;
var Comp = {
props: ["temp"],
data() {
return {
renderFunc: myTemplates[ this.$props.temp ],
}
},
render(h) {
return this.renderFunc()
}
};
new Vue({
el: "#app",
data: { },
components: { Comp }
});
</script>
</body>
</html>
I am a fresher.I try to use scope slot and directive to create a list sample ,the code follow:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>作用域插槽</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
</head>
<body>
<div id="app">
<app></app>
</div>
</body>
<script>
Vue.directive("selectall",{
bind:function(el,binding,vnode,oldVnode){
var arg = binding.arg,
value = binding.value;
console.log(arg,value);
$(el).on('change',function(){
});
}
});
Vue.component("list",{
template:"<div><ul>"
+"<slot name='item' v-for='item in litodos' :text= 'item.text' :time='item.time' :idx='item.idx'></slot>"
+"</ul>"
+"</div>",
props:['litodos'],
data:function(){
return {
message:"list-message"
}
}
});
Vue.component("app",{
template:"<div class='container'>"
+" <input type='checkbox' v-selectall:parent='group1'/>select all gruop1"
+"<list :litodos='todos1'>"
+"<template slot='item' scope='props'>"+
+"<li><input type='checkbox' value='{{props.idx}}' v-selectall:child='group1'/>{{props.text}} </li>"
+"</template>"
+"</list>"
+" <hr><input type='checkbox' v-selectall:parent='group2'/>select all gruop2"
+"<list :litodos='todos2'>"
+"<template slot='item' scope='props'>"+
+"<li><input type='checkbox' value='{{props.idx}}' v-selectall:child='group2'/>{{props.text}}</li>"
+"</template>"
+"</list>"
+"</div>",
data:function(){
return {
group1:"group1",
group2:"group2",
todos1:[
{
text:'study english',
time:'3hour',
idx:'1'
},{
text:'study vue',
time:'2hour',
idx:'2'
}
],
todos2:[
{
text:'学英语',
time:'3hour',
idx:'3'
},{
text:'学js',
time:'2hour',
idx:'4'
}
]
};
}
})
var app = new Vue({
el: '#app',
data:{}
});
</script>
</html>
and here are essential fragment:
+"<list :litodos='todos1'>"
+"<template slot='item' scope='props'>"+
+"<li><input type='checkbox' value='{{props.idx}}' v-selectall:child='group1'/>{{props.text}} </li>"
+"</template>"
+"</list>"
but the result is like this:
enter image description here
I find out that the slot return to NaN,so I am so confused.Can you help me find the keys point to resolve this bug?Thank you!