A counter gets incremented by a custom value.
Each increment value gets stored with its refcount that tracks how many times it occurred.
An ordered list shows all increment values entered so far by number of occurrences.
Higher rank means more occurrence.
Before venturing futher, a disclaimer:
- I can't make prettier work on my VS Code, so I resort to formatting (often poorly) the code myself.
#No longer the case
- The reason behind the variable names is that I need long (to the point of excess) names so I can reason about my code and I find udnerscores soothing for some reason.
That being said: I will welcome every remark, reproach, fist shaking with the same amount (a lot) of gratitude that I will welcome criticism (of any kind) and advice.
The code:
Two components: Parent: CounterInDis.vue
and child: CounterDisplay.vue
.
CounterInDis.vue
:
<script>
import CounterDisplay from './CounterDisplay.vue';
let count = 0;
let increment = 0;
let last_value = 0;
let values_occurrence = {};
let sorted_values = [];
export default {
components: { CounterDisplay },
data() {
return {
count: count,
last_value: last_value,
increment: increment,
values_occurrence: values_occurrence,
sorted_values: sorted_values,
}
},
methods: {
increment_count() {
let checked = this.is_increment_a_number(this.increment)
if (checked == 0) { return }
this.last_value = checked;
this.count += checked;
this.update_values_occurrence(checked);
this.sort_by_occurrence();
},
is_increment_a_number(amount) {
if (typeof amount != 'number') { amount = 0; };
return amount;
},
update_values_occurrence(amount) {
if (!values_occurrence[amount]) {
values_occurrence[amount] = 0;
}
values_occurrence[amount] += 1
},
sort_by_occurrence() {
const keys_n_values = Object.entries(this.values_occurrence);
keys_n_values.sort((a, b) => b[1] - a[1]);
sorted_values = keys_n_values.map((entry) => entry[0]);
},
},
computed: {
to_the_doms_with_you() {
return {
current_count: this.count,
last_value: this.last_value,
current_increment: this.increment,
values_occurrence: this.values_occurrence,
sorted_values: sorted_values, //this.sorted_values won't make the list display, idk why
}
},
},
}
</script>
<template>
<div>
<h3>Counter</h3>
<h4>Welcome to the new and improved counter!</h4>
<CounterDisplay :counter_display_values="to_the_doms_with_you" />
<button v-on:click="increment_count">Increment dat count</button>
<div>
<label for="increment">Increment by</label>
<input type="number" v-model="increment">
</div>
</div>
</template>
CounterDisplay.vue
.
<script>
export default {
props: {
counter_display_values: {
type: Object,
required: true,
},
}
}
</script>
<template>
<p>The Counter is at {{ counter_display_values.current_count }}.</p>
<p v-if="counter_display_values.last_value == 0">Click the button and start counting.</p>
<p v-else>Last increment's value: {{ counter_display_values.last_value }}</p>
<div class="fixed_width">
<p class="half">To each value, its number of occurrences:
<pre>{{ counter_display_values.values_occurrence }}</pre>
</p>
<p>Ranked occurrences:</p>
<ol class="half">
<li v-for="value in counter_display_values.sorted_values" v-bind:key="value">
{{ value }}
</li>
</ol>
</div>
</template>
<style>
.full {
height: 250px;
}
.half {
height: 110px;
}
</style>
The implementation:
Two components: Parent: CounterInDis.vue
and child: CounterDisplay.vue
.
CounterInDis.vue
has a "number" input field bound to the variable increment
. And a button that fires the function increment_count
.
increment_count
passes increment
to the function is_increment_a_number
that loosely checks if increment
is a number, and either returns 0
if typeof increment != 'number'
or returns increment
.
if is_increment_a_number
returned a 0
, increment_amount
exits.
otherwise:
it updates the variable last_value
with increment
(regardless if it's increment === last_value
or not).
then, it adds increment
to the variable count
(the count).
then, it passes increment
to the function update_values_occurrence
.
update_value_occurrence
creates a new entry in the values_occurrence
dict if increment
isn't already there with the refcount of 0
, then it increments the refcount by 1.
then, it (increment_count
) fires the function sort_by_occurrence
.
sort_by_occurrence
get values_occurrence
's entries, sort them (which refcount is greater) then map
the sorted keys to the array sorted_values
.
by now, computed
detected changes in the variables it's watching (basically, all of them) and pass them down as props the child component.
something i don't understand: inside the object returned by computed
:
sorted_values: this.sorted_values
won't display the array in the child component.
sorted_values: sorted_values
shows the array inside the child component. why?
inside CounterDisplay.vue
: the properties of the object get displayed.
- a
v-for
that iterates over* thesorted_values
array and uses each value as its ownkey
-> My reasoning is that this ensures the keys will remain unique since no value can have a duplicate.
Is my reasoning correct? Is there a better way to generate the list items and move them around based on their rank?
Thank you (:
npm
, there's also some npm tools that can help you with this. If you're not usingnpm
, well... then you just have some more to learn :) \$\endgroup\$