Access HTML of DOM element? - vue.js

With Vue 2 I have this in my template:
<table ref="test">
....
</table>
When I get this via this.$refs.test I get [object HTMLTableElement] is there a way to return the actual HTML?

It's hard to tell what's your purpose in doing this, but if you want to be able to for example display it's outerHTML you have to check if this.$refs.test exists and if it does - render it. This is because refs aren't reactive so using computed properties won't work.
<pre v-if="!!$refs.test">{{$refs.test.outerHTML}}</pre>
If you want to set it's outerHTML to a property or use querySelector or any other DOM operation on it, you need to wait for your component to be mounted.
mounted() {
this.testRowContent = this.$refs.test.querySelector('.test').innerHTML;
}
Example: http://jsfiddle.net/eywraw8t/323125/

Related

Problem with creating a div into the document (DOM)

I have some problems with this fragment, it creates a div into the DOM so that div appears in every page as it is normal, which is an image.
How can I change it so this div is only being created when I access at this custom component (Model.vue) and no longer being visible once I'm out of the component page.
Thanks!!
container = document.createElement( 'div' );
document.body.appendChild( container );
If your HTML is predictable you should probably add it in your template (as HTML or as a component) and then show/hide it with v-if or v-show
If you need static content, for example depending on the user input, then v-html is the way.
If you need dynamic content (e.g. with event bindings), then check out render functions.
There's also dynamic component like <component :is="someComponent">, where someComponent can be either a string name of the component, or the component itself. But you should probably try the other solution first.
First of all direct DOM manipulation(Add/Del elements) is not at all preferred in vuejs. You can use v-if instead to show the element conditionally.
Or else if you still want to do direct manipulation then you can write the above lines of code in mounted hook of your model.vue component.
mounted() {
container = document.createElement('div');
container.setAttribute("id", "divId");
}
And then in before destroyed hook you can remove this element from the DOM as below.
beforeDestroy() {
var elem = document.querySelector('#divId');
elem.parentNode.removeChild(elem);
}

VueJS find element by key

I've just wanted to know if it is possible to find a DOM element by the key attribute of vue?
I'm currently working with a list. I'm displaying it via v-for directive on a div. I'm binding the key with the index of the elements.
v-for="(apk, index) in project.apks" v-bind:key="index"
It would really help me if i could compute something for each of these elements as soon as they are fetch from my server and displayed. It's just parsing a file and looking for keyword, and accordingly choosing a css class for the items.
The problem is I dont know how to call a method for each of these elements as soon as they are added to the DOM. They are a lot of html events but i couldnt find one representing the object beeing inserted to dom :(
The purpose of key is not selecting element. Even if it can be done, don't do it.
The proper way to do it is by using ref.
for example, add ref attribute to your html like this
v-for="(apk, index) in project.apks" v-bind:key="index" :ref="'sample-ref-'+index"
and then in your methods, you can get the DOM using this.$refs['sample-ref-0'],this.$refs['sample-ref-1'] and so on.
Hope this helps.
I found that if you give the 'ref' the same name in a v-for, like this:
<div v-for="data in list" :key="data.id" ref="bar"></div>
Then you will find they just store in an array called 'bar' and you can visit them by:
this.$refs['bar'][index]
something like this could allow you to find a component by key :
this.$children.forEach(child=>{
print("child.$vnode.key")
})
also use mounted , as it gets called when the component is added to the dom:
mounted:function(){
this.$el.querySelector("#ele1")...
}
The problem is I dont know how to call a method for each of these elements as soon as they are added to the DOM. They are a lot of html events but i couldnt find one representing the object beeing inserted to dom :(
You can create a new component with your v-for and just call the created() hook.
Example
/* On your main function */
<div v-for="apk in project.apks">
<apk :data="apk"></apk>
</div>
/* On your 'apk' component */
export default {
props: [ "data" ],
created() {
console.log("Created !");
}
}

Unable to append html element to the parent in Vue js directive

I have a global directive in vue js
Vue.directive('customDirective',{
bind(el,binding,vnode){
// need to get the parent
// append a div after the input element
}
})
I have the following html code .
<div class="parentDiv">
<input type="text" name="firstName" v-customDirective="Some text"/>
</div>
<div class="parentDiv"> is loading dynamically via jquery. I need to get the parent of input tag and need to append some html after the input tag. I have tried with parent(), but it is showing as parent is not a function. Any suggestions ?
You should probably use the inserted hook instead of bind if you want to access the parent element.
You can get the parent element via el.parentElement.
You probably should use vnode, and Vue nextTick.
import Vue from 'vue';
Vue.directive('customDirective',{
bind(el,binding,vnode){
Vue.bextTick(() => {
let parent = vnode.elm.parentElement;
});
}
})
If you want to use parent() which is the jQuery function, you must get the element by jQuery.
Vue.directive('customDirective',{
bind(el,binding,vnode){
Vue.bextTick(() => {
let id = vnode.elm.id;
let parent = jQuery('#'+id).parent();
});
}
})
I'm not sure, that second code works, but it will be something like that.

When v-for array created by computed option changs, the DOM doesn't change accordingly

Recently, I've encountered a problem that caused by the computed option of vuejs.
Firstly, I use v-for to loop for an array (soloColImgs) which is created by the computed option.
my HTML
<div class="show-box" v-for="item in soloColImgs" track-by="$index">
<img v-bind:src="item.imgUrl"/>
<a v-bind:href="item.itemUrl" target="_blank"></a>
</div>
my JS
//...
computed: {
soloColImgs :function(){
//....
},
methods: {
change:function(){
this.soloColImgs.pop();
}
}
Secondly, I change the array (soloColImgs) by using pop() or splice() etc...When I look into the console, the array can change accordingly, however, the DOM does't change at all. It would be greatful if anyone can help me out of this.
The point of a computed property is that its determined solely by the function that defines it. You cannot change it directly, you must change it by acting on the dependencies. The dependencies are the properties that are used to calculate the returned value.

what is innerHtml alternative in riotjs

What is the alternative of innerHtml in riotjs
like
asdfghjkl
in js
we write
var str=document.getElementById("one").innerHtml;
but for the same html tag we have to get that value in riotjs
like
riot.id will return value "one"
what function will retun value "asdfghjkl" instead of .
If I understand your question correctly you would like to get the innerHTML of your created tag. That is as easy as "this.root.innerHTML".
<riot-tag>
asdfghjkl
<script>
this.on('updated', function(){
console.log(this.getInnerHTML());
});
getInnerHTML(){
return this.root.innerHTML;
}
</script>
</riot-tag>
If you need the innerHTML of any sub-element of your created tag set a name or id property on the element and reference it directly. Or if you are calling your function from an event, like click, have the element reference from e.target.
<riot-tag>
<h1 onclick={getInnerHTML} name="myTagHeader">asdfghjkl</h1>
<script>
getInnerHTML(e){
console.log(e.target.innerHTML);
console.log(this.myTagHeader.innerHTML);
}
</script>
</riot-tag>
Hope that it will help