Vue convert string to dom (Nuxt.js) - vue.js

I try to add dom in vue element, but it doesnt work.
here is my code,
<div v-bar="{preventParentScroll: true}">
<div>
<el-menu
ref="menu"
default-active=""
class="lnbmenu"
:unique-opened="true">
**{{ this.menuList}}**
</el-menu>
</div>
and next, js code.
computed: {
menuList(){
~~~ reducer ~~~
return dom
*//return
<el-submenu index="M0010">
<template slot='title'>
<span>menu1</span>
</template>
<el-menu-item index="M0018">
<nuxt-link to="tempMenu">
<span>menu2</span>
</nuxt-link>
</el-menu-item>
</el-submenu>*
}
}
I tried to use 'v-html' in el-menu tag, but still not work.
how can I add this thing?

Normally, you manipulate the DOM in Vue with the $refs keyword.
Have a look: https://codingexplained.com/coding/front-end/vue-js/accessing-dom-refs

Related

Vue.js: Why does $el return a text node

I do have the following code:
<template>
<custom-child></custom-child>
</template>
export default class Custom extends Vue {
mounted() {
console.log(this.$el); // Returns a text node (with an empty content)
console.log(this.$el.nextElementSibling); // Returns a element representing my custom child
}
}
I am quite confused why would I need to use nextElementSibling as I expected $el to return an element directly.
The solution is as follows.
wrong
<template>
<div></div>
<div>
...
</div>
</template>
correct
<template>
<div>
 <div>...</div>
...
</div>
</template>
OR
wrong
<template>
<div></div>
<div>
...
</div>
</template>
correct
<template>
<div>
 <div>...</div>
</router-view>
</div>
</template>
If you do not use a "div" tag just inside the "Template" tag, you will get the same problem.

Vuetify custom v-text-field component is not updating the v-model

I’m following this documentation: https://v2.vuejs.org/v2/guide/components.html
I created custom v-text-field component which looks like that:
<template>
<div>
<v-text-field
:label="label"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"></v-text-field>
</div>
</template>
<script>
export default {
name: "txtbox",
props: ['value', 'label'],
}
</script>
I implemented it in my main component almost succesfully:
<txtbox
label="Name"
v-model="eventName"
/>
I don’t think it is necessary to paste all the code, but if it is I will edit the post. Here is how it works:
I have a list, when i click on the list element the text-field displays content of it, this works fine. Sadly when I’m editing the content of text-field the v-model value is not updating. I can also add that it works fine with normal (like in the docs) instead of . Is there anything I can do to make it work, or should i use simple input ?
Thanks
When you want to $emit the new value, you just have to emit the $event, and not $event.target.value
<template>
<div>
<v-text-field
:label="label"
v-bind:value="value"
v-on:input="$emit('input', $event)"></v-text-field>
</div>
</template>
v-on:input can also be shortened to just #input

How to bind slot with v-bind for url attribute?

How to pass attributes from component to slot?
This is in component
<navigation-link url="/profile">
Your Profile
</navigation-link>
Then in the template I want to use url
<template>
<div>
<a
v-bind:href="url"
class="nav-link">
<slot></slot>
</a>
<span class="active></span>
<div>
</template>
according to docs this should work, but instead I get error: Property or method "url" is not defined on the instance but referenced during render.
I think you want to put the text "Your Profile" in <slot></slot>
So, for this, you need to do this.
<navigation-link url="/profile">
<template slot="text">
Your Profile
</template>
</navigation-link>
And in the component, name the slot like this
<template>
<div>
<a
v-bind:href="url"
class="nav-link">
<slot name="text" />
</a>
<span class="active></span>
<div>
</template>
Probably, this work.
EDIT:
according to docs this should work, but instead I get error: Property or method "url" is not defined on the instance but referenced during render.
That is because, you are not declaring url in the component, you probably need to put
props: ['url'],
data() {
return {
propUrl: this.url
}
}
and in the template use this.propUrl
Regards

v-if on a component template tag

From the docs:
Because v-if is a directive, it has to be attached to a single
element. But what if we want to toggle more than one element? In this
case we can use v-if on a element, which serves as an
invisible wrapper. The final rendered result will not include the
element.
But on my template in my component:
<template v-if="false">
<div>
....
</div>
</template>
But the component still renders.
I ask because I want a hook on the component so if v-if is true, I can do some code in beforeMounted and beforeDestroyed if false.
If I undestood what are you doing...
You're putting v-if int the template tag ina .vue file right?
Like this
// component.vue
<template v-if="false">
<div>
My Component
</div>
</template>
<script>
export default {
name: 'my-component'
};
</script>
<styles>
</styles>
Right?
If YES, you are doing it wrong.
The template there is a tag for Webpack Vue Loader to load the component template.
So the if must go inside the template tag.
// component.vue
<template>
<div v-if="false">
My Component
</div>
</template>
<script>
export default {
name: 'my-component'
};
</script>
<styles>
</styles>
If you need to "hide" multiple elements, just encapsulate into another div.
As Lucas Katayama said, you cannot use v-if inside SFC, but another way to hide you component is use v-if on this component in its parent component.
Your reference to the docs is correct, you can use a v-if on a template tag. However, I believe conditionals on the top-level <template> in a Single File Component are ignored.
To achieve the effect showed in the docs (conditional render a template) that template needs to be within the top-level template section.
Example:
<script>
// your script section
</script>
<template>
<template v-if="false">
<div>
....
</div>
</template>
</template>
<style>
// your style section
</style>

How do I use conditional rendering on template tag?

According to the Vue documentation I should be able to add the v-if condition to the <template> tag:
<template v-if="false">
<div>Invisible text</div>
</template>
But this will not hide the element, however it does work when added to the child element:
<template>
<div v-if="false">Invisible text</div>
</template>
Any suggestions?
I'm including the template in another .vue file:
<template>
<div id="app">
<H1 class= "main-title">Title</H1>
<span class="components">
<testtemplate></testtemplate>
</span>
</div>
</template>
The template tag of a single-file component is not rendered by Vue like normal <template> tags. It is simply one of the placeholders, along with <script> and <style> that vue-loader uses to build the component. The root element of that template is what will be the root in the component.
But, even if it worked the way you want, there would be no difference between your first and second example. Using v-if on the root will prevent the entire component's template from rendering if set to false.
Had this problem with VUE3. Using SFC just nest tag template inside another tag template :
<template>
<template v-if="false">
You won't see this
</template>
</template>