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>
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 ;)
Vue - #input is triggered by :placeholder in Internet Explorer 11 immediately upon page load not when entering a value. That is, the problem is only in the explorer. When the page loads, input is triggered immediately, but only if there is a placeholder
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Тег SCRIPT</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<component-c/>
</div>
<script type="text/javascript">
var ComponentA = Vue.component('ComponentA', {
props: ['field'],
methods: {
//#input is triggered by :placeholder in Interner Exployer 11 immediately upon page load not when entering a value
validator: function (ev){
console.log(ev.target.value, 'value in validator');
}
},
computed: {
fieldPlaceholder: function () {
return this.field.placeholder;
},
},
template: '<input type="password" #input="validator" :placeholder = "fieldPlaceholder">'
});
var ComponentС = Vue.component('ComponentB', {
data: function () {
return {
field: {
placeholder: 'place'
}
}
},
components: {
'component-a': ComponentA,
},
template: '<component-a :field = "this.field" />'
})
var app = new Vue({
el: '#app',
components: {
'component-c': ComponentС,
}
})
</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 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!
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.