Vue - how to add to component's prop - vue.js

I wanted to add a line break to a component's props using the
but when I do so I get an error.
does anyone have a solution?
code:
<template>
<section class="w-screen h-screen bg-slate-700 grid place-items-center">
<div class="mb-12">
<div class="text-8xl">Title</div>
<div class="m-8 text-center text-3xl">
<Writer
:array="[
'Code 1',
'line 1
line 2',
]"
:typeSpeed="100"
:iterations="1"
/>
</div>
</div>
</section>
</template>

You can use the \n character in the string and then the css white-space property in the consuming element.
Here a working example.
On the Writer parent use the \n character for the new line like:
<Writer
:array="[
'Code 1',
'line 1\n line 2',
]"
:typeSpeed="100"
:iterations="1"
/>
Inside the Writer component you should add the white-space property to your css element like:
<template>
<div
class="break-lines"
v-for="arrayElement in array">
{{ array Element }}
</div>
</template>
<style>
.break-lines {
white-space: break-lines;
}
</style>
This should do the trick ;)

Related

How to pass in img src in vue.js using props?

I have an info-card.vue component that is used twice in a landing page, but I want different data displayed in each of them. Here is the info-card.vue component:
<template>
<div class="card-container glass-effect">
<div class="illustration-container">
<img src="{{ image }}" alt="Businesses" class="illustration">
</div>
<div class="title-container">{{ title }}</div>
<div class="paragraph-container">{{ content }}</div>
</div>
</template>
<script>
export default {
props: ['image','title', 'content']
}
</script>
And here is the landing-info.vue page that the info-card component is used in:
<div class="business-side">
<info-card image="/images/image1.png" title="BUSINESSES" content="This is some content"></info-card>
</div>
<div class="customer-side">
<info-card image="/images/image2.png" title="CUSTOMERS" content="This is some content"></info-card>
</div>
But this didn't work, I'm new to vue so any ideas?
You can't use mustache {{   }} in vue attributes. Instead use v-bind:attr="" or :attr="" where attr is the dynamic attribute you want to bind.
So, your image component should be:
<img v-bind:src="image" alt="Businesses" class="illustration" />
or
<img :src="image" alt="Businesses" class="illustration">
The colon is a shorthand for v-bind.
Read more on v-bind here.

Ant Design Vue - Custom Header in Collapse Component

Hello I'am using Vue and Ant Design. So i pick Collapse Component from Ant Design: https://antdv.com/components/collapse/
My problem is that in Collapse.Panel there is a prop header which is string, but i need to put string in there (example: v0.6.1.11) and date, so i can add margin-left: auto or something like that in date.
Exmaple:
I tried using white-space: pre and then simply add spaces to achive that space between but it's not responsive solution.
How can i pass into header prop pure html so i could put something like two <p> tags there and then create space between title and date?
As per docs, we can make use of Panel property extra slot.
Run this sample code
new Vue({
el: "#app",
data() {
return {
text: `A dog is a type of domesticated animal.Known for its loyalty and faithfulness,it can be found as a welcome guest in many households across the world.`,
activeKey: ['1'],
expandIconPosition: 'left',
};
},
computed:{
currDate(){
return new Date().toLocaleDateString()
}
}
});
.ant-collapse>.ant-collapse-item>.ant-collapse-header{
display:flex;
justify-content:space-between
}
<link rel="stylesheet" href="https://unpkg.com/ant-design-vue#1.4.11/dist/antd.min.css">
<script src="https://unpkg.com/vue#2.6.11/dist/vue.min.js"></script>
<script src="http://bms.test/vendor/laravel-admin/moment/min/moment-with-locales.min.js"></script>
<script src="https://unpkg.com/ant-design-vue#1.5.0/dist/antd.min.js"></script>
<div id="app">
<a-collapse v-model="activeKey">
<a-collapse-panel key="1" header="This is panel header 1">
<p>{{ text }}</p>
<div slot="extra">{{currDate}}</div>
</a-collapse-panel>
<a-collapse-panel key="2" header="This is panel header 2" :disabled="false">
<p>{{ text }}</p>
<div slot="extra">{{currDate}}</div>
</a-collapse-panel>
<a-collapse-panel key="3" header="This is panel header 3" disabled>
<p>{{ text }}</p>
<div slot="extra">{{currDate}}</div>
</a-collapse-panel>
</a-collapse>
</div>
You can use the below code for the pupose.
<a-collapse-panel key="1" header="heading 1">
<p>Content</p>
<template #extra><p>heading 2</p></template> <!-- for newer version -->
<p slot="extra">heading 2</p> <!-- for older version -->
</a-collapse-panel>

Vue.js: Loading template (or div) when user clicks button?

So I currently have a template sitting in a ".vue" file like so:
<template>
<div id="dataAttachToMe"></div>
</template>
I don't want this to load, unless a user clicks a button, something like
<button #click="loadTheTemplateAbove">See Data</button>
I've tried using this example:https://v2.vuejs.org/v2/guide/conditional.html#Controlling-Reusable-Elements-with-key. But it says something like "Component template should contain exactly one root element" in the error message.
I need more than a show/hide here I think, something that can initiate the template dynamically.
<template>
<div id="data">
<button #click="loadTemplate">Load the template</button>
<div v-if="buttonClicked">
<div id="dataAttachedToThisDiv"></div>
</div>
</div>
</template>
The error you are getting, means that there is more than one root element inside <template></template> tag.
It is required in Vue.js (and other template based frameworks/libraries) to have only one root element.
This will NOT work:
<template>
<div id="dataAttachToMe"></div>
<button #click="loadTheTemplateAbove">See Data</button>
</template>
This will work:
<template>
<div id="someRootDiv">
<div id="dataAttachToMe">Some data</div>
<button #click="loadTheTemplateAbove">See Data</button>
</div>
</template>
Here is a code example (App.vue) of what you are trying to achieve:
Basic idea: we have to create a variable, that will be changed upon button click. We add v-if directive that depends on that variable and will handle element's visibility.
Welcome to StackOverflow. When you get the error Component template should contain exactly one root element it means that you can only have one root element in your template. You can fix that error by wrapping everything in a blank div like so
<template>
<div>
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
</div>
</template>
Please edit your post and place you <script> tag. Conditional Rendering requires a data field of a boolean that you can place in your if statement on your template
<template>
<div>
<div v-if="show">{{message}}</div>
<div v-if="#show">Not Showing when show is set to false</div>
<button v-on:click="show = true">Show</button>
</div>
</template>
<script>
module.exports {
data: function () {
message: 'Hello Vue!',
show: false
}
}
</script>

Output html using a Vue template tag, but without having a nested element

My over-arching question is: In Vue, how to output inner html while iterating over a collection but without having to wrap it in an additional div or span.
Specifically: I'm iterating over an array of js objects from within a Vue template. Each object has a "render" method which outputs html.
This works:
template:
`<div id="container">
<template v-for="element in elements">
<span v-html="element.render()"></span>
</template>
</div>
`,
But I would like to do something like below, because I don't want the output to be wrapped in a div or span. This code produces no error but also produces no output:
template:
`<div id="container">
<template v-for="element in elements" v-html="element.render()">
</template>
</div>
`,
In a perfect world, I would do something like this, but mustache format can't output html:
<div id="container">
<template v-for="(element, index) in elements">
{{ element.render() }}
</template>
</div>
The desired output:
<div id="container">
(output of element.render())
(output of element.render())
(output of element.render())
etc.
</div>
Thank you for any guidance,
L
Delete the <template> tag completely and use render function in <script> tag. Something like this, but this code is not tested, demonstrational only.
export default {
...
render (h) {
return h('div', this.elements.map(function (elm) {
return h(elm.render())
})
}
}

vuejs render part of template inside different elements without repeating

I am new to Vuejs. This is what I need to do.
<div v-for="r in records">
<div v-if="r.something">
<div id="x">
{{ r. something}}
more of r here.
</div>
</div>
<div v-else id="x">
same div as in the block above.
</div>
</div>
What I want do is not define div with id x two times as it is huge.
Make your 'div' a component and refer to it in both places.
There are many ways to define your component. This is example shows just one. If you are using WebPack, use a single file component. You can then have your script, html, and css all in one file that gets precompiled. That's the best way to manage your 'huge' div. Then you can continue to refactor and break it up into more components.
const myComponent = {
template: "<div :id='id'>HELLO, my id is {{id}}. r.foo is {{r.foo}} </div>",
props: {
id: String
},
data() {
return {
r: {
foo: 'bar'
}
}
}
}
<div v-for="r in records">
<div v-if="r.something">
<my-component id='x' />
</div>
<div v-else id="x">
<my-component id='x' />
</div>
</div>