vue pushed data reset get in first place - vuejs3

what I want to do may be simple but what I don't understand is, When I click on any of the buttons, I push the new number. but what I want is, I want every data pushed to be initialized.
When it is newly pushed, I want it to be first in the "hello" data.
when button click
output of the sent data.
i want it to be like this
hello: [newnumber,1, 9, 15, 7, 9]
<div>
output : {{hello}},
<button #click="addItem(5)"></button>
<button #click="addItem(65)"></button>
</div>
<script>
export default {
data() {
return {
hello: [1, 9, 15, 7, 9]
}
},
methods: {
addItem(newnumber) {
this.hello.push(newnumber)
}
}
}
</script>

Related

Move the zoom-in/zoom-out to another place than upper-left corner

When using Vue2Leaflet and the "l-map" component, is there a way to move the zoom-in/zoom-out buttons to another place than upper-left corner?
https://vue-leaflet.github.io/Vue2Leaflet/#/components/l-map/?id=props
https://i.stack.imgur.com/ITRFr.png
You need disable the default zoom controls first. Then add LControlZoom component with your preferred position. like-
<l-control-zoom position="bottomleft"></l-control-zoom>
HTML:
<template>
<l-map style="height: 350px" :zoom="zoom" :center="center" :options="{zoomControl: false}">
<l-tile-layer :url="url"></l-tile-layer>
<l-control-zoom position="bottomleft"></l-control-zoom>
</l-map>
in javaScript
<script>
import {LMap, LTileLayer, LControlZoom} from 'vue2-leaflet';
export default {
components: {
LMap,
LTileLayer,
LControlZoom
},
data () {
return {
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
zoom: 8,
center: [47.313220, -1.319482],
};
}
}
</script>
Hope this helps. Read here vue2-leaflet documentation : https://vue2-leaflet.netlify.com/components/LControlZoom.html

Vue.js: How to change a class when a user has clicked on a link?

I am trying to add a class to an element depending on whether the user has clicked on a link. There is a similar question here but it is not working as I wanted it to be.
I created a component which has its own internal data object which has the property, isShownNavigation: false. So when a user clicks on the a I change isShownNavigation: true and expect my css class isClicked to be added. Alas that is not happening - isShownNavigation stays false in the component when I displayed it {{isShownNavigation}} but I can see in the console that my method is working when clicked.
I imported my header component to the App. Code is below.
Header Component
<template>
<header class="header">
<a
href="#"
v-bind:class="{isClicked: isShowNavigation}"
v-on:click="showNavigation">
Click
</a>
</header>
</template>
<script>
export default {
name: 'header-component',
methods: {
showNavigation: () => {
this.isShowNavigation = !this.isShowNavigation
}
},
data: () => {
return {
isShowNavigation: false
}
}
}
</script>
Application
<template>
<div id="app">
<header-component></header-component>
</div>
</template>
<script>
import HeaderComponent from './components/Header.vue'
export default {
name: 'app',
components: {
'header-component': HeaderComponent
}
}
</script>
I am using the pwa template from https://github.com/vuejs-templates/pwa.
Thanks.
Don't use fat arrow functions to define your methods, data, computed, etc. When you do, this will not be bound to the Vue. Try
export default {
name: 'header-component',
methods: {
showNavigation(){
this.isShowNavigation = !this.isShowNavigation
}
},
data(){
return {
isShowNavigation: false
}
}
}
See VueJS: why is “this” undefined? In this case, you could also really just get rid of the showNavigation method and set that value directly in your template if you wanted to.
<a
href="#"
v-bind:class="{isClicked: isShowNavigation}"
v-on:click="isShowNavigation = true">
Click
</a>
Finally, if/when you end up with more than one link in your header, you will want to have a clicked property associated with each link, or an active link property instead of one global clicked property.

Show only specific time range in week view

How can I only show time between 08:00-12:00 and 13:00-18:00 instead of the full 24 hours in week view using FullCalendar?
I tried this solution on SO, but I couldn't get it to work.
businessHours may get you where you want to go. Starting in v2.9.1 you can specify multiple sections of hours.
$('#calendar').fullCalendar({
defaultView: 'agendaWeek',
businessHours: [{
dow: [0, 1, 2, 3, 4, 5, 6], // Maybe not 0,6? Sunday,Saturday
start: '08:00',
end: '12:00'
}, {
dow: [0, 1, 2, 3, 4, 5, 6], // Maybe not 0,6? Sunday,Saturday
start: '13:00',
end: '18:00'
}]
});
#import url('https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.0.1/fullcalendar.min.css');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.0.1/fullcalendar.min.js"></script>
<div id="calendar"></div>
It will still allow events to be created or moved into non-business-hours but gives a visual indication to the calendar of "not normal hours".
You could also remove the rows from the view something like this
$('#calendar').fullCalendar({
defaultView: 'agendaWeek',
viewRender: function(view, element) {
if (view.name.substr(0, 6) === 'agenda') {
$(element).find('div.fc-slats table tr[data-time]').filter(function() {
var _t = $(this).data('time');
/* find times not in the ranges we want */
return ((_t >= '08:00' && _t <= '12:00') || (_t >= '13:00' && _t <= '18:00')) === false;
}).each(function() {
$(this).hide(); /* hide the rows */
});
}
}
});
#import url('https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.0.1/fullcalendar.min.css');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.0.1/fullcalendar.min.js"></script>
<div id="calendar"></div>
This approach could be fragile though if rendering changes get made to FullCalendar.
This code displays the calendar between 08:00-18:00. May not what you exactly looking for, but it helped me (FullCalendar 4.2.0):
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
minTime: '08:00:00',
maxTime: '18:00:00'
}
calendar.render();
});

Should the reducers be nested?

I have an app which is very similar to instagram, but instead of having one main feed, the user
can have multiple feeds based on the events he/she attends. I'm using redux for the state management
and currently I have these reducers:
feed
people
schedule
user
navigation
My feed reducer looks like:
{
allEvents: [],
event: {
id: 123,
name: 'Foo'
},
items: [
{
id: 23,
imageUrl: 'http://img.com/foo',
likes: [{ id: 1, user: {...} }, { id: 2, user: {...} }],
comments: [{ id: 1, text: '...', user: {...} }, { id: 2, text: '...', user: {...} }]
}
]
}
So my state structure currently looks like:
{
feed,
people,
schedule,
user,
navigation
}
But at the moment every time the user changes current event the whole feed state is replaced by a
new state for that particular event, so if the user comes back to the previous event the whole feed needs
to be fetched again, same is with people reducer and schedule, which depends on the event.
Also user has it's own profile feed which shows user's feed items. And in order to have this feed I would
need to duplicate what I have in the current feed reducer, so I thought it would be better to have multiple feeds,
inside event reducer.
I was wondering if the state structure like this wouldn't be better:
{
events: {
items: [
feed,
people,
schedule
]
}
user,
navigation
}
Then I read redux#815 or redux#994 that it's not the best way to nest reducers.
Should it look more or less like:
{
feed: {
feedIds: [23, 24, 25],
byId: {
23: {
items: [123, 124, 125]
}
}
},
items: {
itemsIds: [123, 124, 125, 126, 127],
byId: {
124: {
id: 124,
image: 'http://img.com ',
likes: [1, 2, 3]
}
}
},
likes: {
likesIds: []
},
events: {
eventIds: [1, 2, 3],
byId: {
1: {
id: 1,
name: 'TYW Croatia w34'
feedId: 23,
peopleId: 12,
scheduleId: 1
}
}
},
people: {...}
}
What's the best practice in this case and which way is the most performant?
A normalized structure, like your last example, is definitely both a best practice and more performant. The state is flatter, so updates are more targeted and affect fewer unrelated objects; items can be easily looked up by ID as needed; and the update logic will generally be simpler. Also, this allows you to pass item IDs to connected child components, which then look up their own data based on that ID, and they will only need to re-render when their own data changes. Finally, it works well for caching data.
You might want to read through some of these articles on Redux performance for more information, particularly High Performance Redux. You may also want to read some of the discussion at Normalising state and garbage collection.
edit:
As a follow-up, I recently added a new section to the Redux docs, on the topic of "Structuring Reducers". In particular, this section includes chapters on "Normalizing State Shape" and "Updating Normalized Data".

Meteor C3 charts based on D3 - multiple charts?

EDIT: clone this repository for a non working reproduction. https://github.com/FickleLife/meteor-c3-test
I am using https://github.com/peernohell/meteor-c3.js/
I pull two examples off the C3 site http://c3js.org/examples.html and can get them to display once on the page, but when I try to add a second on the same page the first disappears. There's no console error and the javascript variables are different.
chart 1 html template:
<template name="chart_cp_overview">
<div id="cpOverview"></div>
</template>
chart 1 js helper:
Template.chart_cp_overview.rendered = function () {
var cpOverview = c3.generate({
data: {
columns: [
['data1', 30, 200],
['data2', 130, 100]
],
type: 'bar',
groups: [
['data1', 'data2']
]
},
grid: {
y: {
lines: [{value:0}]
}
}
});
}
chart 2 html template:
<template name="chart_status">
<div id="chart"></div>
</template>
chart 2 helper:
Template.chart_status.rendered = function() {
var chart = c3.generate({
data: {
columns: [
['Dropped', 30],
['On Course', 120],
['DNS', 20],
['Finished', 40]
],
colors: {
'Dropped': '#E60000',
'On Course': '#00ACED',
'DNS': '#DBDBDB',
'Finished': '#00BD07'
},
type : 'donut',
onclick: function (d, i) { console.log("onclick", d, i); }
// onmouseover: function (d, i) { console.log("onmouseover", d, i); },
// onmouseout: function (d, i) { console.log("onmouseout", d, i); }
},
donut: {
title: "Entrant Status",
label: {
format: function (value, ratio) {
return value;
}
}
}
});
};
display code :
<div class="row">
<div class="col-md-6">
{{> chart_cp_overview}}
</div>
<div class="col-md-6">
{{> chart_status}}
</div>
</div>
This code above displays only the last chart - chart_status. If I remove any one of the handlebars reference the other chart displays fine, or if I have multiple handlebars to multiple charts whatever was last declared is displayed.
How can I get multiple charts to display within one page? Example is on github at https://github.com/FickleLife/meteor-c3-test
It looks like maybe you are intending the two variable names you have chosen in your template rendered functions, cpOverview and chart, to bind to the dom elements with those ids. It won't work that way.
The variable names you have chosen are local to their functions and in any case would not automatically attach to elements with that id even if they were global. So c3 is binding all these charts to the same dom element (the docs say the default is #chart), and the last one is overriding the prior ones.
You want to bind each chart to its respective element. You can use this.firstNode inside your rendered function (based on the way you have it set up), or use jquery, or this.find("div#cpOverview"), and then use the c3 api to bind the chart to it - it looks like { bindto: "div#cpOverview" } may be the one you want.

Resources