I have a header component. i cant able to update value of header component on button click
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<header>
<my-component ref="foo"></my-component>
</header>
<div id="app">
<h1>Component Test</h1>
<button v-on:click="test">Button</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var MyComponent = Vue.extend({
template: '<div><p>Hello</p><div v-if="islogin">User</div></div>',
data: function () {
return {
islogin: false
};
}
});
var vm = new Vue({
el: '#app',
components: {
'my-component': MyComponent
},
methods: {
test: function () {
this.$refs.foo.islogin = true;
}
}
});
</script>
</body>
</html>
i want to update the islogin to true on button click. Now it shows "TypeError: Cannot set property 'islogin' of undefined" error.
Thanks
Your component 'my-component' is not in the scope of Vuejs. Vue is in the div with the id 'app'. So you can't add others components outside this main div
Put the component inside Vuejs #app scope :
<div id="app">
<header>
<my-component ref="foo"></my-component>
</header>
<h1>Component Test</h1>
<button v-on:click="test">Button</button>
</div>
Related
I'm trying to create a Vue app with a render() function and withModifiers. But somehow a keyup.enter event does not work as expected: It fires for every key, not only the enter or return key.
Here is a minimum example:
<html>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue#3/dist/vue.global.prod.js"></script>
<script>
const app = Vue.createApp({
render() {
return Vue.h("input", { onKeydown: Vue.withModifiers((e) => console.log(e), ["enter"]) });
},
}).mount("#app");
</script>
</body>
</html>
What did I miss?
I have an app that I am porting from Vue2 to Vue3. I am not using a bundler as Vue is just providing simple interactivity on a page. This is the simplified version in Vue2:
// my-modal.js
var myModal = Vue.component('my-modal',
{
template:
`<div id="myModal">
<button #click.prevent="open=true">Open Modal</button>
<div v-if="open" class="my-modal">
<p>Hello from the modal!</p>
<button #click.prevent="open=false">Close</button>
</div>
</div>`,
data() {
return {
open: false
}
}
})
In Vue 2 this Works;
<script src="https://unpkg.com/vue#2"></script>
<div id="app">
<div class="outer">
<h3>Modal Example - {{ message }}</h3>
<div>
<my-modal />
</div>
</div>
</div>
<script src="/js/my-modal.js"></script>
<script>
const app = new Vue(
{
el: '#app',
data() {
return {
message: 'Hello Vue!'
}
}
});
</script>
For Vue3, per the documentation at: https://v3-migration.vuejs.org/breaking-changes/global-api.html#a-new-global-api-createapp I switched things over to what I expected would work:
<script src="https://unpkg.com/vue#3"></script>
<div id="app">
<div class="outer">
<h3>Modal Example - {{ message }}</h3>
<div>
<my-modal />
</div>
</div>
</div>
<script src="/js/my-modal.js"></script>
<script>
Vue.createApp({
data()
{
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
and in the my-modal.js file I changed the first few lines to use the Global Vue:
const { createApp } = Vue;
const app = createApp({});
app.component('my-modal', ...
The Vue instance works but the component is not found with the error message: "Failed to resolve component: my-modal". I tried adding a 'components' section to the Vue instance and a few other things with no luck.
Any suggestions?
Each instance from createApp() is unique. That is, calling createApp() in index.html does not return the same instance from the previous call in my-modal.js.
One solution is to declare the global app instance before importing my-modal.js:
<!-- index.html -->
<script>
window._app = Vue.createApp({⋯})
</script>
<script src="/js/my-modal.js"></script>
<script>
// finally mount
window._app.mount('#app')
</script>
// js/my-modal.js
window._app.component('my-modal', {⋯})
demo
I'm trying to get data from parent component and use them in child component v-bind:style.
Here's my code.
<body>
<div id="parentComponent">
<child-component v-bind:propsdata="parentBackground" v-bind:propsdata2="parentFontstyle"></child-component>
</div>
<script>
Vue.component('child-component', {
props: ['propsdata', 'propsdata2'],
data: function() {
return {
childBackground: this.propsdata,
childFontStyle: this.propsdata2
},
template: '<p v-bind:style="childBackgroundColor, childFontStyle">Child componnent Area</p>'
});
new Vue ({
el: '#parentComponent',
data: function() {
return {
parentBackground: 'background-color:yellow;',
parentFontStyle: 'font-style: italic;'
},
})
</body>
When I run this code, only second style(childFontStyle) is applied to Child componnent template.
I also tried v-bind:style="[childBackgroundColor, childFontStyle]" and doesn't work.
Is there any way to apply both style?
You need to pass the props property as an object and can able to bind the props directly to the child. You have some typo mistakes that need to be fixed as well. Here is the working snippet.
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="parentComponent">
<child-component v-bind:propsdata="parentBackground" v-bind:propsdata2="parentFontStyle"></child-component>
</div>
<script>
Vue.component("child-component", {
template: `<p v-bind:style="[propsdata, propsdata2]">Child componnent Area</p>`,
props: ["propsdata", "propsdata2"]
});
new Vue({
el: "#parentComponent",
data: function() {
return {
parentBackground: {
"background-color": "yellow"
},
parentFontStyle: {
"font-style": "italic"
}
};
}
});
</script>
</body>
</html>
How to add v-b-tooltip.hover directive to myInput and myButton without changing myDiv html? I've been trying to access them in render function but using api turns out not obvious.
Updated: added second component
Vue.component('other-component', {
template: "<div><b-form-input title='myInput'/><b-button title='myButton'>Button</b-button></div>"
})
var MyComponent = {
render: function(createElement) {
console.log(this.$slots.default.children);
return createElement("div", this.$slots.default)
}
}
new Vue({
el: "#app",
components: {
MyComponent
}
})
<!-- Load required Bootstrap and BootstrapVue CSS -->
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css" />
<!-- Load Vue followed by BootstrapVue -->
<script src="//unpkg.com/vue#latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<div id="app">
<my-component>
<other-component />
</my-component>
</div>
You can modify the slot vnode to achieve this.
const MyComponent = {
render(h) {
let buttonVNode = this.$slots.default[0].children[2]
buttonVNode.data.directives = [{
name: 'b-tooltip',
value: 'Tooltip Content!'
}]
return h('div', this.$slots.default)
}
}
Example in JSFiddle.
If you want something more general such as find the vnode by their id attribute you may need to use recursive and check for each vnode children.
js i'm starting to catch up on it but i'm stuck on components would appreciate your help thanks
//here is my js
Vue.component('thatsCool', {
template: document.querySelector('#myOwnTemplate'),
data: function() {
return {
helloWorld: 'thats cool',
};
},
});
new Vue({
el: 'body',
});
//and this is my html
<! DOCTYPE html>
<html>
<head>
<title>playing with Vue components</title>
</head>
<body>
<thatsCool></thatsCool>
<script id="myOwnTemplate" type="x/template">
<p v-text="helloWorld"></p>
</script>
<script src="vue.js"></script>
<script src="component.js"></script>
</body>
</html>
There are a couple of errors in your code. Use dash-separated convention for your components and simple handlebar notation for string output. Try with this code:
HTML
<thats-cool></thats-cool>
<script id="myOwnTemplate" type="x-template">
<p>{{ helloWorld }}</p>
</script>
JS
Vue.component('thats-cool', {
template: '#myOwnTemplate',
replace : true,
data: function() {
return {
helloWorld: 'thats cool',
};
}
});
Note that the option 'replace : true' replaces the original template's content of el instead of appending to it.