I'm creating a calendar with a bg-primary for the container. For each row (week), I use a b-row with class of pb-2. I then have individual b-col's for the days. The b-col for Sunday uses px-2 while the other days have pr-2 and pl-0. This gives me the gutter all around that I desire. If I put the code in my main component, everything works fine. However, if I pass an array for one week of days to the child component, no gutters show.
*** CalendarGrid.vue <script> ***
data() {
return {
days: [1, 2, 3, 4, 5, 6, 7],
};
},
*** CalendarGrid.vue <template> ***
<template>
<b-row class="pb-2">
<b-col class="px-2">
<Day>{{ days[0] }}</Day>
</b-col>
<b-col
v-for="(day, index) in days.slice(1)"
:key="index"
class="pr-2 pl-0"
>
<Day>{{ day }}</Day>
</b-col>
</b-row>
</template>
I want to use a child component to display the calendar days, since I have additional data and formatting to add to each day. Day vue, at this point simply displays the day value sent to it.
*** Day.vue ***
<template>
<div class="days text-right">
<slot></slot>
</div>
</template>
I have a child component called Week.vue, which I call I want to call from CalendarGrid.vue
<Week :days="days" />
Week.vue consists of the exact same template as above. The only difference is that days is an array prop.enter code here
Related
I'm creating a calendar to track payments due. I have the following section of code to create the calendar grid. I am using Bootstrap-Vue:
<div v-for="week in 5">
<b-row class="pb-2">
<b-col class="px-2">
<Day
:day="first(week)"
:today=days[(week - 1) * 7]
:payments="payments"
></Day>
</b-col>
<b-col
v-for="(day, index) in days.slice((week - 1) * 7 + 1, week * 7)"
:key="index"
class="pr-2 pl-0"
>
<Day
:day="day"
:today="today"
:payments="payments"
></Day>
</b-col>
</b-row>
</div>
Day is a child component that renders the data and payments due for that day. The days prop is an array of moment.js variables. When I run this, no days are created for Sundays. I get the following error 5 times (one for each Sunday):
[Vue warn]: Error in render: "TypeError: Cannot read property 'date' of undefined"
If I change the assignment of the day prop for Sundays to:
:day="first(week)"
and then create a first method:
first(week) {
return this.days[(week - 1) * 7];
},
the calendar will be created correctly (after the screen flashes a few times). However, I still get the aforementioned errors. Why?
Day has a child component, Date, which is responsible for displaying the day's date.
<div
class="date"
:id="id"
:title="title"
>
{{ day.date() }}
</div>
This is where the error is generated.
The child components are mounted before the parent, although I am not sure it will actually help you solve your issue.
I think you should't mount the child component before obj get date attr
I have a vue component which displays a gauge. I need to include units on the display and have this as one of the props of the component. However, because there are a number of gauges with different formatting it is all stored in a vuex store that reads its settings from an API. This all works nicely apart from when I want to bring special symbols (such as degree signs) across. The vuex object is storing the formatting object as:
{"min":0,"max":50,"dp":1,"units":"°C"}
and I use it in my component as follows:
<svg-gauge v-else
v-bind:g-value="device.value"
v-bind:g-min="device.format.min"
v-bind:g-max="device.format.max"
v-bind:g-decplace="device.format.dp"
v-bind:g-units="device.format.units"
>
The problem is that this simply displays °C rather than a degree symbol. If I hard code the last line as
g-units="°C"
It all works as expected. I suspect it is that I am having to use v-bind to pass the property and this is messing things up. Is there a way to ensure that v-bind is treating my characters as I would like?
EDIT: Here is the svg-gauge component template where the units are actually rendered.
<template>
<b-row>
<b-card no-body class="bg-dark text-light border-0" align="center">
<b-card-body class="m-0 pt-0 pb-0">
<h5><slot name="title">Title</slot></h5>
<div class="row mini-gauge pt-3" align="center">
<vue-svg-gauge
class="mini-gauge"
:start-angle="-90"
:end-angle="90"
:value="gValue"
:separator-step="0"
:min="gMin"
:max="gMax"
base-color="#595959"
:gauge-color="[{ offset: 0, color: '#347AB0'}, { offset: 100, color: '#D10404'}]"
:scale-interval="5"
>
<div style="line-height: 11rem">{{gValue.toFixed(gDecplace)}} {{gUnits}}</div>
</vue-svg-gauge>
</div>
<div class="row mini-gauge">
<div class="col" align="left">{{gMin}}</div>
<div class="col" align="right">{{gMax}}</div>
</div>
</b-card-body>
</b-card>
</b-row>
</template>
Change this line to have a span with a v-html. Then in the v-html pass the gUnits prop
<div style="line-height: 11rem">
{{gValue.toFixed(gDecplace)}}
<span v-html="gUnits"></span>
</div>
You can find the reason by looking here.
Hope this helps!
So, i have two arrays. One contains some appointments which all state what day they are scheduled for. In another array, i have the name of all the weekdays. I want to print only the weekdays with which there are appointments.
<b-col class="h-100">
<b-row v-for="day in week" class="schemaLine">
<div>{{day}}</div>
<b-row v-for="appointment in appointments" class="">
<div v-if="appointment.day === day && companies.includes(appointment.company)">
<b-button class="appointmentBlock w-100 m-2">
<div class="appointmentTitle">
{{appointment.name}}
</div>
<div class="appointmentTime">
{{appointment.time}}
</div>
</b-button>
</div>
</b-row>
</b-row>
</b-col>
The easiest way to only print the days you have at least one appointment for, is to pre-process your appointments. This has the added benefit of not requiring you to go over every appointment for every day of the week.
To get started, we create a computed property appointmentsPerDay, which maps a day to an array of appointments. Then we create another computed property that takes the keys of that object and sorts them so you can loop over them:
computed: {
appointmentsPerDay () {
// We assume that you get the appointments variable somehow
const appointmentsPerDay = {};
for (const appointment of this.appointments) {
const { day } = appointment;
// We initialise an array if no such array exists
if (!appointmentsPerDay[day]) {
appointmentsPerDay[day] = [];
}
// Now that it is guaranteed that we have an array, add our appointment to it
appointmentsPerDay[day].push(appointment);
}
return appointmentsPerDay;
},
visibleDays() {
const days = Object.keys(this.appointmentsPerDAy);
days.sort();
return days;
}
}
Now how do we use these?
<b-col class="h-100">
<b-row v-for="day in visibleDays" class="schemaLine">
<div>{{day}}</div>
<b-row v-for="appointment in appointmentsPerDay[day]" class="">
<div v-if="companies.includes(appointment.company)">
<b-button class="appointmentBlock w-100 m-2">
<div class="appointmentTitle">
{{appointment.name}}
</div>
<div class="appointmentTime">
{{appointment.time}}
</div>
</b-button>
</div>
</b-row>
</b-row>
</b-col>
As you can see, we just have to swap out some variables. You still see that we have to use a v-if to filter on companies. Obviously we can also pre-process that to eliminate the v-if entirely and just loop over the data that we actually want to show. I will leave that as an exercise for you.
i believe week is your weekdays array if so then it should be like this :
<b-row v-for="day in week" class="schemaLine" v-if="appointments.find(app => app.day === day)">
I'm using Element UI library with Vuejs framework (configured using Vue CLI).
I currently have a nested input form that is taking information and pushing it to an object array inside of a parent component, but I'm having a lot of trouble sharing this information to a child component.
I believe using props is the correct approach, but I'm not sure I'm declaring the props correctly. I also have the parent / child set up with vue-router.
Form in parent component...
<div>
<el-dialog title="Create a new space to huddle" :visible.sync="createHuddleVisible" width="1000px" height="200%">
<el-form :huddle="huddle" :index="index">
<el-form-item label="Huddle Headline" :label-width="formLabelWidth">
<el-input v-model="newHuddle" autocomplete="off" placeholder="What should we call this meeting?"></el-input>
</el-form-item>
<el-form-item label="Goal" :label-width="formLabelWidth" :autosize="{ minRows: 1, maxRows: 2 }">
<el-input type="textarea" v-model="newGoal" placeholder="Use this text box to quickly establish the goal of this huddle.">
</el-input>
</el-form-item>
<el-form-item label="Body" :label-width="formLabelWidth">
<el-input style="white-space: pre-line;" type="textarea" :autosize="{ minRows: 10, maxRows: 15 }" v-model="newBody"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button #click="createHuddleVisible = false">Cancel</el-button>
<el-button type="primary" #click="addHuddle">Confirm</el-button>
</span>
</el-dialog>
</div>
The 'addHuddle' method successfully takes all strings and creates new objects.
I would like to use the data captured here and displayed in a child component.
For now, I've just been trying to print one of the object values onto a card as a test with no luck. Blank card.
<template>
<el-card class="huddle-box-card" shadow="always">
{{ huddle[0].goal }}
</el-card>
</template>
<script>
export default {
name: 'HuddleSpaceOne',
props: {
huddle: {
type: Object
},
index: {
type: Number
},
}
}
</script>
I'm using bootstrap-vue package. In some component I have three card-flip components:
<b-row>
<b-col lg="4">
<card-flip :order="'fifth'"></card-flip>
</b-col>
<b-col lg="4">
<card-flip :order="'sixth'"></card-flip>
</b-col>
<b-col lg="4">
<card-flip :order="'seventh'"></card-flip>
</b-col>
</b-row>
and inside this card-flip component I'm displaying three different buttons depending on :order prop:
<template>
<!-- some not related content -->
<template v-if="order === 'fifth'">
<button class="card-flip__button card-flip__button--2"
v-b-modal.modalStandard="">
Sprawdź ofertę1
</button>
</template>
<template v-if="order === 'sixth'">
<button class="card-flip__button card-flip__button--2"
v-b-modal.modalPremium="">
Sprawdź ofertę2
</button>
</template>
<template v-if="order === 'seventh'">
<button class="card-flip__button card-flip__button--2"
v-b-modal.modalPremiumPlus="">
Sprawdź ofertę3
</button>
</template>
<modal-standard></modal-standard>
<modal-premium></modal-premium>
<modal-premium-plus></modal-premium-plus>
</template>
I'm using this template syntax to not create unnecessary divs.
And issue is that when I click some of this button it open correct modal but three times on top of previous ones.
I'm adding correct id's to <b-modal> inside those modal-* components.
This is done because each modal is rendered three times, one for each card-flip. You should also add v-if="order === 'fifth'" etc also for each modal in your card-flip template.