Using the ref attribute with dom element outside a VueJS 2 component template - vue.js

I am currently struggling with referencing existing DOM elements with VueJS.
I have an existing date input rendered from the applications twig template and a separate VueJS widget i integrated.
<input type="time" ref="date_time_1" min="09:00" max="18:00" value="13:30">
The date input field is NOT inside the components template, but within the VueJS application (having id="#app").
For data-binding i would like to use the ref attribute to connect the VueJS component with my date input field inside the components template (e.g. for initialization with values coming from the application):
mounted() {
componentsTimeValue: this.$refs["date_time_1"].value;
}
getting undefined here.
Is there a way to connect "existing" DOM elements (that are not created with vue), with vue components using the ref attribute at all?

Though not a good practise because #div container is handed over to vue for manipulation but still you can reference the dom that weren't created by vue but lie inside #app
For that you must reference properly, so if you are in some child component you use
mounted() {
componentsTimeValue: this.$root.$refs["date_time_1"].value;
}

Related

Can i make it happen has() in vue.js?

i'm using vue.js and vuetify.
elements made by parent element exist in my code.
i want to change parent element's class dynamically depending on it's child class, like jQuery has() method.
is vue.js has any way to do this?
jQuery has()
You can access a state if a child property of a child on different ways. (I assume the child class is set based on a certain state).
You could use vuex that keep a state over several components. You could emit a state back to you parent component. Or you could use the ref to access the child components properties.
<component ref="childcomponent"></markdown>
process: function(){
// items is defined object inside data() of the child component
var hasClass= this.$refs.childcomponent.item
}

Vue with Web Component "is" Attribute

I am trying to use a web component which extends an existing element using the "is" attribute tag, but vue takes that attribute and converts it into a custom element.
I need vue to still recognize the v-model and business logic, but I also need vue to not change it to a custom component.
Vue turns this:
<textarea v-model="text" is="my-component"></textarea>
into:
<my-component></my-component>
I have tried setting "v-pre" but that keeps vue from tracking the v-model. I have also tried to set ignoredElements, but vue still convert to a custom element. I looked https://github.com/vuejs/vue/issues/2642 and it seems like this is supposed to be a fixed issue, but maybe I am missing something.
Here is a minimal example of what is happening: https://jsfiddle.net/ntkg1xeq/1/
Notice that the textarea turns into real-set in this example.
I would expect vue to disregard the "is" attribute if it does not match any registered components, and to not rewrite the element thus preventing the web component from working.
Is there any way to use vue and web components like this together?
According to the last comment of Web component with "is" attribute not rendered in the view., <textarea v-pre v-model="text" is="my-component"></textarea> would be
render to <textarea is="my-component"> just as your expectation. However, it seems the issue just fixed Vue 1.x ( Vue 1.0.12 example code ), not Vue 2.x ( your example code ).
So. if you want to set is attribute in textarea and make v-model works in Vue 2.x, I thought $refs is another solution ( Vue 2.x example code by using $refs ).

custom child components in angularjs2

I currently developing angular2 application . I would like to know how to add html attributes to custom components.
For example lets assume i have custom dropdown component and am re-using in same page on many places. If i would like to develop some dropdowns as multiselect and some of them single select, Could you please tell me how to that. If I add mutiple on component template it is showing multiselect for all dropdowns. If I add to each component individually where am using, it is not understanding that "Multiple" attribute.
If i would like to develop some dropdowns as multiselect and some of
them single select, Could you please tell me how to that.
You should be using a boolean #Input decorator defined in your custom component (Question seems unclear and i am assuming that you didn't ask for an implementation logic of multi select and single select). Below gives an example of adding a multiselect check for your custom component and how parent should bind value to that attribute when rendering the custom component
In your custom component.ts class
#Input() multiple: boolean = false;
In your custom html class
<div *ngIf="!multiple">
// render your single select html
</div>
<div *ngIf="multiple">
//render your multiple select html
</div>
In the parent html while rendering the custom component (assumpe selector as the name of the component)
// for multi select
<selector [multiple]=true> </select>
// for single select
<selector [multipl]=false> </select>
If your struggling to make a generic component supporting both single and multi select check this open source component ng-select
If you have no idea on #Input and #Output decorators in angular2 check this article

How to get the parent template component in Vue

I know in vue, I can use this.$parent to get the upper component in the vdom tree. But I'm expecting something different: to get the component that rendered the current component.
For instance, I have a component (named comp-container) with template:
<template>
<comp-a>
<comp-b></comp-b>
</comp-a>
</template>
And in comp-b the $parent would be an instance of comp-a not comp-container which I'm expecting.
My current aproach is traversing up with the $parent attribute until I find comp-b exists in $options.components. This method is working for now but seems quite ugly and breaks if comp-b is a globaly registered component. Is there an official way to do this?
Passing the parent template component via props as <comp-b :container="this"></comp-b> may do the job, but it's too verbose to be liked.
I'm not sure about the exact use case, but basically if there are slots involved (which I almost assume, because otherwise $parent will work fine), you can find the rendering component at:
this.$slots.default[0].context;
Basically, the context property of a slot is the rendering context (rendering component - i.e. the component who's template the component was rendered in).
Only tested with Vue 2

Vue component not updating after parent state change

I have Vue component which receives json data from props, after this render child components using v-for and pass this data as prop. Everything works fine until i try to remove one item from this list, when i remove it, it removes element incorrectly. In vue devtools i see that parent receives data correctly but not renders it properly. can anyone help me?
here is my code: https://gist.github.com/giokaxo/3d291b9b7b8ef97f81dc83799c430302
Use "key" attribute when rendering elements using v-for, for example:
<p v-for="(product, index) in order.products" :key="i">..</p>
The relevant documentation is here:
You can directly use v-for on a custom component, like any normal
element:
<my-component v-for="item in items" :key="item.id"></my-component>
In 2.2.0+, when using v-for with a component, a key is now required.
However, this won’t automatically
pass any data to the component, because components have isolated
scopes of their own. In order to pass the iterated data into the
component, we should also use props:
<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id">
</my-component>
The reason for not automatically injecting item into the component is because that makes the component
tightly coupled to how v-for works. Being explicit about where its
data comes from makes the component reusable in other situations.
And here:
When Vue is updating a list of elements rendered with v-for, it by
default uses an “in-place patch” strategy. If the order of the data
items has changed, instead of moving the DOM elements to match the
order of the items, Vue will simply patch each element in-place and
make sure it reflects what should be rendered at that particular
index.
...
To give Vue a hint so that it can track each node’s identity, and thus
reuse and reorder existing elements, you need to provide a unique key
attribute for each item. An ideal value for key would be the unique id
of each item.