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(...)
);
выбранным оказывается последний добавленный элемент, несмотря на то, что всем добавленным элементам в GetSelected я вернул ' '
v-model
? из дочернего мне нужно передать именно ключ b в родительский
this.$emit('do-something')
.<child-component :object="objects.a" @do-something="doSomething('a')" />
<child-component :object="objects.b" @do-something="doSomething('b')" />
<!--> или <-->
<child-component v-for="(v, k) in objects" :object="v" @do-something="doSomething(k)" />
methods: {
doSomething(key) {
// чего-то делаете
},
...
затем пройтись по objects и при совпадении ключей (a, b или c) выполнить действия над значением
<child-component :object="objects.a" @do-something="doSomething(objects.a)" />
<child-component :object="objects.b" @do-something="doSomething(objects.b)" />
<!--> или <-->
<child-component v-for="n in objects" :object="n" @do-something="doSomething(n)" />
this.$emit('do-something', this.object)
. Тогда не придётся дублировать обращение к нему в родителе:<child-component :object="objects.a" @do-something="doSomething" />
<child-component :object="objects.b" @do-something="doSomething" />
<!--> или <-->
<child-component v-for="n in objects" :object="n" @do-something="doSomething" />
function createTree({
arr,
idKey = 'id',
parentKey = 'parentId',
childrenKey = 'children',
}) {
const tree = Object.fromEntries(arr.map(n => [ n[idKey], { ...n, [childrenKey]: [] } ]));
return Object.values(tree).filter(n => !tree[n[parentKey]]?.[childrenKey].push(n));
}
v-tree
, выводящий древовидные данные:props: {
items: {
type: Array,
default: () => [],
},
maxdepth: {
type: Number,
default: Infinity,
},
},
<ul v-if="Array.isArray(items) && items.length && maxdepth">
<li v-for="n in items" :key="n.id">
{{ n.value }}
<v-tree :items="n.children" :maxdepth="maxdepth - 1" />
</li>
</ul>
v-model.lazy
.const current = ref(props.value);
emits("change", current);
@change="changeCount"
function changeCount(value) { count.value = value; }
emits("change", current);
---> emits("change", current.value);