This is my second day with vue. I was already using webpack and vue-cli, but I would like to understand how to make everything working within one file. I developed a code which works well, but I would like to refactor the code to have a component which I could later use to generate screen full of color changing tiles.
I tried Vue.component(‘name’, {}), but with no result, because in the console I’m seeing [vue.js warn]: The “data” option should be a function that returns a per-instance value in component definitions. and [vue.js warn]: Unknown custom element: <brick> - did you register the component correctly? For recursive components, make sure to provide the “name” option.
This code works well:
<html>
<head>
<title>v pavle</title>
<script type=”text/javascript” src=”https://vuejs.org/js/vue.js"></script>
</head>
<body>
<div id=”app”></div>
<script type=”text/javascript”>
var vm = new Vue({
el: “#app”,
template:
‘<div v-bind:style=”styleobj” v-on:mouseover=”changebgcolor” v-on:mouseout=”changebgcolor”></div>’,
data: {
styleobj: {
width: “100px”,
height: “100px”,
backgroundColor: “white”
}
},
methods: {
changebgcolor: function() {
this.styleobj.backgroundColor = Math.floor(
Math.random() * 16777215
).toString(16);
}
}
});
</script>
</body>
</html>
And that code gives everything, but not what to see :(
<html>
<head>
<title>v pavle</title>
<script type=”text/javascript” src=”https://vuejs.org/js/vue.js"></script>
</head>
<body>
<div id=”app”>
<brick></brick>
</div>
<script type=”text/javascript”>
var vm = new Vue({
el: “#app”
});
var brick = Vue.component(“brick”, {
template:
‘<div v-bind:style=”styleobj” v-on:mouseover=”changebgcolor” v-on:mouseout=”changebgcolor”></div>’,
data: {
styleobj: {
width: “100px”,
height: “100px”,
backgroundColor: “white”
}
},
methods: {
changebgcolor: function() {
this.styleobj.backgroundColor = Math.floor(
Math.random() * 16777215
).toString(16);
}
}
});
</script>
</body>
</html>
It may seem easy for you, but after 7h spent, there is nothing more for me, but just ask you on SO
Solution :
Okay I will answer the 2 questions. First and about data, it has to be a function. So you have to write it like that:
data() {
return {
styleobj: {
width: “100px”,
height: “100px”,
backgroundColor: “white”
}
}
}
After that, the forgot to reference the component in the vue.js instance. Try that:
var vm = new Vue({
el: “#app”,
components: {
brick: brick
}
})
Hope it will work.
Solution 2:
Data must be a function like data: function(){ return obj }
Register the component using components: {yourcomponent}
You needed to use # in front of the color.
<html>
<head>
<title>v pavle</title>
<script type=”text/javascript” src=”https://vuejs.org/js/vue.js"></script>
</head>
<body>
<div id=”app”>
Hello App!
<brick>Hello Brick</brick>
</div>
<script type=”text/javascript”>
var brick = Vue.component(“brick”, {
template:
‘<div :style=”styl” @click=”changebgcolor” @mouseover=”changebgcolor” @mouseout=”changebgcolor”><slot></slot></div>’,
data: function(){
return {
styl: {
width: “100px”,
height: “100px”,
backgroundColor: “#b6d8a1”,
color: “blue”
}
};
},
methods: {
changebgcolor: function() {
console.log(‘changebgcolor!’);
this.styl.backgroundColor = “#”+ Math.floor(
Math.random() * 16777215
).toString(16);
}
}
});
var vm = new Vue({
el: “#app”,
components:{brick:brick}
});
</script>
</body>
</html>
Solution 3:
When using Vue.component, you need to make sure that you have registered all components once you start rendering the app. At the moment, you first render the main app and then register the component, so swap those around
var brick = Vue.component(“brick”, {
template:
‘<div v-bind:style=”styleobj” v-on:mouseover=”changebgcolor” v-on:mouseout=”changebgcolor”></div>’,
data: {
styleobj: {
width: “100px”,
height: “100px”,
backgroundColor: “white”
}
},
methods: {
changebgcolor: function() {
this.styleobj.backgroundColor = Math.floor(
Math.random() * 16777215
).toString(16);
}
}
});
var vm = new Vue({
el: “#app”
});
Solution 4:
The data property on the component should be a function that returns an object. Why? Because otherwise all instances of the component share the same data, meaning all tiles on the app would have the same color.
data() {
return {
styleobj: {
width: “100px”,
height: “100px”,
backgroundColor: “white”
}
}
},
You should first register the component before you fire up the vue.js instance, just reorder the code and it works!