data: () => ({
value: 1,
step: 0.25,
}),
methods: {
updateValue(up) {
const { value, step } = this;
const rounded = Math[up ? 'floor' : 'ceil'](value / step) * step;
this.value = rounded + step * (up ? 1 : -1);
},
},
<input v-model.number="value">
<button @click="updateValue(0)">-</button>
<button @click="updateValue(1)">+</button>
watch(values, (newValues, oldValues) => {
const addedValue = newValues.find(n => !oldValues.includes(n));
if (addedValue) {
const findAncestorValues = (arr, val, values = []) =>
(Array.isArray(arr) ? arr : []).reduce((found, n) => {
if (!found) {
values.push(n.value);
found = n.value === val ? [...values] : findAncestorValues(n.children, val, values);
values.pop();
}
return found;
}, null);
values.value = [...new Set([ ...values.value, ...findAncestorValues(data, addedValue) ])];
}
});
watch
необходимо слушать у el-tree-select
событие обновления массива выбранных значений. При этом, чтобы иметь доступ к предыдущей версии этого массива, надо будет немного поработать руками. Как-то так:const oldValues = ref([]);
function onUpdate() {
const addedValue = values.value.find(n => !oldValues.value.includes(n));
if (addedValue) {
// тут всё по-прежнему
}
oldValues.value = values.value;
}
<el-tree-select
@update:modelValue="onUpdate"
...
v-for
индексы, которые затем проверяйте в v-if
ячеек с rowspan'ами - рендерить их нужно только при нулевых значениях.objects[0]
? Неужели в objects
может быть только один элемент? Заверните то, что сейчас есть в ещё один template
, в котором будет v-for
по элементам objects
.v-for
.methods: {
rowspan: attr1 => attr1.reduce((acc, n) => acc + n.attr3.length + 1, 0),
},
<template v-for="obj in objects">
<template v-for="{ road, attr1, TOTAL } in obj.data">
<template v-for="({ attr2, attr3, attr4 }, iAttr1) in attr1">
<tr v-for="(attr3Item, iAttr3) in attr3">
<td :rowspan="rowspan(attr1)" v-if="!iAttr1 && !iAttr3">{{ road }}</td>
<td :rowspan="attr3.length" v-if="!iAttr3">{{ attr2 }}</td>
<td>{{ attr3Item.road }}</td>
<td>{{ attr3Item.cargo }}</td>
<td>{{ attr3Item.amount }}</td>
<td>{{ attr3Item.wo_nds }}</td>
</tr>
<tr>
<td colspan="2">Итого {{ attr2 }}:</td>
<td>{{ attr4.cargo }}</td>
<td>{{ attr4.amount }}</td>
<td>{{ attr4.wo_nds }}</td>
</tr>
</template>
<tr>
<td colspan="3">Итого {{ road }}:</td>
<td>{{ TOTAL.cargo }}</td>
<td>{{ TOTAL.amount }}</td>
<td>{{ TOTAL.wo_nds }}</td>
</tr>
</template>
</template>
v-bind:header="user"
v-slot:header="{ user }"
header
, а использовать пытаетесь user
. const filters = reactive({});
<input v-model="filters.search">
watch(
() => filters.search,
debounce(search => store.commit('setFilters', { search }), 1500)
);
watch(
store.state.filters,
val => Object.assign(filters, val), { immediate: true }
);
Thev-enter
transition class has been renamed tov-enter-from
<RatingSelect v-model="rating" />
const props = defineProps({
modelValue: {
type: Number,
required: true,
},
maxRating: {
type: Number,
default: 10,
},
});
const emit = defineEmits([ 'update:modelValue' ]);
const selected = computed({
get: () => props.modelValue,
set: val => emit('update:modelValue', val),
});
<li v-for="n in maxRating">
<label>
<input type="radio" :value="n" v-model="selected">
{{ n }}
</label>
</li>
data: () => ({
buttons: [
{ className: 'btn1', text: 'Limit' },
{ className: 'btn2', text: 'Market' },
],
active: 0,
}),
<button
v-for="(n, i) in buttons"
v-text="n.text"
:class="[ 'btn', n.className, { 'active-btn': i === active } ]"
@click="active = i"
></button>
btn*
действительно идут по порядку)data: () => ({
buttons: [ 'Limit', 'Market' ],
active: 'Limit',
}),
<button
v-for="(n, i) in buttons"
:class="`btn btn${i + 1} ${n === active ? 'active-btn' : ''}`"
@click="active = n"
>{{ n }}</button>
<YandexClusterer
@vue:mounted="onClustererMounted"
...
methods: {
onClustererMounted(e) {
e.component.exposed.events.add('click', обработчикКлика);
},
...
@click.stop
).data: () => ({
openedPopup: null,
}),
methods: {
togglePopup(popup) {
this.openedPopup = this.openedPopup === popup ? null : popup;
},
},
@click="togglePopup('search')"
v-show="openedPopup === 'search'"
const { filledColor: F, emptyColor: E, ...props } = defineProps({
value: Number,
maxValue: Number,
segments: {
type: Number,
default: 5,
},
filledColor: {
type: String,
default: 'red',
},
emptyColor: {
type: String,
default: 'black',
},
});
const background = val =>
val >= 1 ? F :
val <= 0 ? E :
`linear-gradient(to right, ${F}, ${F}, ${val * 100}%, ${E} ${val * 100}%)`;
<div class="rating">
<div
v-for="i in segments"
:style="{ background: background(value / maxValue * segments - i + 1) }"
class="rating-segment"
></div>
</div>
false
, всё выбрано - true
, для остальных вариантов undefined
, при котором в true
будет выставляться indeterminate. Также у него будет сеттер - если попытаться назначить true
, то выбранными должны стать все чекбоксы; если false
, то никто.const items = ref([
{ id: 69, title: 'hello, world!!' },
{ id: 187, title: 'fuck the world' },
{ id: 666, title: 'fuck everything' },
]);
const checked = ref([ 187 ]);
const isAllChecked = computed({
get: () => ({
0: false,
[items.value.length]: true,
})[checked.value.length],
set: val => checked.value = val ? items.value.map(n => n.id) : [],
});
<div>
<label>
<input
type="checkbox"
v-model="isAllChecked"
:indeterminate.prop="isAllChecked === undefined"
>
<b>Check all</b>
</label>
</div>
<div v-for="n in items" :key="n.id">
<label>
<input type="checkbox" v-model="checked" :value="n.id">
{{ n.title }}
</label>
</div>
clearInterval из функции stopTheTimer результата необходимого не показал
data() { <...> }, mounted() { <...> }, stopTheTimer() { clearInterval(this.interval); }
v-model
:props: {
modelValue: {
type: String,
default: '',
},
...
<select
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
<option
v-for="n in options"
v-text="n.label"
:value="n.value"
></option>
</select>
data: () => ({
selected: Array(10).fill(null),
...
}),
methods: {
getValue(index) {
this.active = index;
console.log(this.selected[index]);
},
},
<div
v-for="(n, i) in selected"
class="test__item"
:class="{ test__item_active: i === active }"
>
<span @click="getValue(i)">элемент списка</span>
<Select v-model="selected[i]" :options="options" />
</div>
const profilesSorting = computed(() => profiles
.value
.filter(n => n.id === filters.value.id)
.sort(...)
.slice(...)
);