why doesn't my child component work? - vue.js

Data can be passed down to child components using props. But why doesn't my tag child work?It doesn't print out hello.Here is my code,
html:
<div id="app">
<child message="hello"></child>
</div>
javascript:
new Vue({
el:'#app'
});
Vue.component('child',{
props:['message'],
template:"<span>{{message}}</span>"
})

You component needs to be declared before your main Vue instance:
Vue.component('child',{
props:['message'],
template:"<span>{{message}}</span>"
})
new Vue({
el:'#app'
});
Here's the JSFiddle: https://jsfiddle.net/Lxeb7gmo/

You must dynamically bind it by adding : in front of message like this
:message="hello"

Related

How to call a component method each time this component show in vue2?

Vue component hasn't onShow lifecycle method.
How to call a component method each time this component show in vue2?
I have used this library for that purpose before:
https://github.com/Akryum/vue-observe-visibility
I am assuming you are dynamically hiding and showing the component and you want to trigger few functionality every time component show. If Yes, You can simply achieve this requirement by using v-if directive instead of v-show. As v-if will rebuild the component every time condition got passed.
Live Demo :
Vue.component('child', {
props: ['childmsg'],
template: '<p>{{ childmsg }}</p>',
mounted() {
console.log('child component mounted');
}
});
var app = new Vue({
el: '#app',
data: {
buttonMsg: 'Show Child Component',
showChild: false
},
methods: {
toggleBtn() {
this.showChild = !this.showChild;
this.buttonMsg = this.showChild ? 'Hide Child Component' : 'Show Child Component';
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="toggleBtn">{{ buttonMsg }}</button>
<child v-if="showChild" childmsg="This is a child message"/>
</div>

How to get parent component's ref in child component

I want to pass button element to the child component using refs.
<button ref="button">
Button
</button>
<child :element="$refs.button" />
But in child component element prop comes null. How can I send button element to the child component ?
As per my understanding, You want to use the button element in multiple components. You can make button itself as a separate component and use it where ever you want.
You can try something like this :
Vue.component('customBtn', {
props: ['buttontext'],
template: '<button>{{ buttontext }}</button>'
});
Vue.component('child', {
template: '<custom-btn buttontext="This is a child button"></custom-btn>'
});
var app = new Vue({
el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<custom-btn buttontext="This is a parent button">
</custom-btn>
<child></child>
</div>

Dynamic x-templates in Vue components

I have this component, and would like to pass a parameter/prop to the component saying which x-template to use. When I do it like this, it fails:
JS:
Vue.component('custom-table', {
props: ['template'],
template: '#' + this.template
})
new Vue({ el: '#app' })
HTML:
<custom-table template="my-template"></custom-table>
<script type="text/x-template" id="my-template">
<p>My Template</p>
</script>
Error:
vue.js:3 [Vue warn]: Cannot find element: #undefined
How can I use dynamic templates like this?
I'm not sure whether this is actually a good idea but it does come pretty close to what you've requested:
Vue.component('custom-table', {
props: ['template'],
template: `<component :is="{ template: '#' + template }" />`
})
new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue#2.6.10/dist/vue.js"></script>
<script type="text/x-template" id="button-template">
<button>My Template</button>
</script>
<script type="text/x-template" id="em-template">
<em>My Template</em>
</script>
<div id="app">
<custom-table template="button-template"></custom-table>
<custom-table template="em-template"></custom-table>
</div>
The trick here is to use the object version of is, which allows you to pass in a component definition inline. Strictly speaking there are two components in play here, a parent and a child, and the x-template is assigned to the child. That said, the resulting DOM should be as desired as the parent doesn't add any extra elements of its own.
You can't have dynamic templates for a single component.
You could create various components, and then dynamically pick which component to render for the particular tag. For this, Vue supports dynamic component:
<component v-bind:is="currentTabComponentName"></component>
Alternatively, if you want caller to fill-in-the-blanks of your component with arbitrary HTML, then you can use slots.
Or, if it is just static HTML, then you can just pass the HTML itself as string, and render the content without escaping it:
<div v-html="task.html_content"> </div>
Maybe one of these works for you...
Other options could be to use render functions or JSX.

In Vue, how can I get a css style selector from a $ref?

I'm able to use $ref to isolate the correct chuck of html, but I need a css selector for that chuck. I wish this worked...
this.$refs.myref.querySelector()
did you try:
this.$refs.myref[0].$el
it equals
document.querySelector(’.myref’)
You are, in fact, able to use querySelector on a ref if the ref in question is referring to a DOM element and not to a child Vue component. The fact that this.$refs.myref.querySelector() doesn't work for you leads me to believe that myref is a component and not an element.
If the ref is a Vue component, you are still able to reference the root DOM element of the component via its $el property. So, in your case: this.$refs.myref.$el.querySelector().
Here's a simple example snippet illustrating the difference:
Vue.config.devtools = false;
Vue.config.productionTip = false;
Vue.component('child', {
template: `
<div>
<span class="inside-child">Inside Child</span>
</div>
`
})
new Vue({
el: '#app',
mounted() {
console.log(this.$refs.child.$el.querySelector('.inside-child'));
console.log(this.$refs.div.querySelector('.inside-div'))
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<child ref="child"></child>
<div ref="div">
<span class="inside-div">Inside Div</span>
</div>
</div>

Vue.js 2.0 Dynamic Props Docs

js 2.0 and I'm stock in dynamic props.
See Image attached
My HTML code like this:
<div id="app">
<div>
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
</div>
My Component code:
Vue.component('child', {
props: ['myMessage'],
template: '<p>{{ myMessage }}</p>',
})
var app = new Vue({
el: "#app",
});
I know that data should be a function but how I'm going to implement it. I get this error on the console.
Property or method "parentMsg" is not defined on the instance but referenced during render
I think message is clear. "parentMsg" is not defined on the instance. You have to define parentMsg at parent level. like following:
var app = new Vue({
data: {
"parentMsg": ""
}
el: "#app"
});
You can have a working fiddle here.