input
, чтобы v-model
обновил данные компонента:methods: {
removeLastChar({ target: t }) {
t.value = t.value.slice(0, -1);
t.dispatchEvent(new Event('input'));
},
...
},
<input
@focus="removeLastChar"
...
>
sortOpen() {
this.$emit('sortOpen', this.sortWindowOpen = !this.sortWindowOpen);
},
<TableControl @sortOpen="addStatic = $event"></TableControl>
data: () => ({
meetupId: null,
meetupData: null,
}),
watch: {
meetupId(val) {
fetch(`https://course-vue.javascript.ru/api/meetups/${val}`)
.then(r => r.json())
.then(r => this.meetupData = r);
},
},
<label v-for="i in 5">
<input type="radio" name="meetupId" :value="i" v-model="meetupId">
{{ i }}
</label>
<pre>{{ meetupData }}</pre>
@update:modelValue="$emit('change', $event.target.value)"
update:modelValue
?@change="$emit('update:modelValue', $event.target.value)"
model: { prop: 'modelValue', event: 'update:modelValue' },
BREAKING:v-bind
's.sync
modifier and componentmodel
option are removed and replaced with an argument on v-model;
Как должен выглядеть json...
[
{
title: '...',
children: [
{
title: '...',
children: [
{
title: '...',
},
...
],
},
...
],
},
...
]
...для генерации такого вложенного списка через v-for?
name: 'v-tree',
props: [ 'items' ],
<ul v-if="Array.isArray(items) && items.length">
<li v-for="n in items">
{{ n.title }}
<v-tree :items="n.children" />
</li>
</ul>
const popup =createApp(App);
popup.$store.dispatch
$store
, вам нужен результат вызова mount
, а не createApp
.store.dispatch
. computed: {
bullshitEmails() {
const search = this.search.trim().toLowerCase();
return this.emails.map(n => ({
email: n,
marked: !!search && n.toLowerCase().includes(search),
}));
},
},
<ul>
<li
v-for="{ email, marked } in bullshitEmails"
v-text="email"
:class="{ marked }"
></li>
</ul>
const props = defineProps({
showBgBlue: {
type: Boolean,
default: true,
},
});
const mainClass = computed(() => props.showBgBlue ? 'bg-blueGray-50 py-12' : 'bg-white');
new Vue({
loaves: [
this.loaves[idx] =
data: () => ({
maxlen: 10,
items: [
'hello, world!!',
'fuck the world',
'fuck everything',
'1234567890',
'Lorem ipsum dolor sit amet, consectetur adipiscing elit,',
],
}),
methods: {
short1: (str, maxlen) => str.length <= maxlen ? str : str.slice(0, maxlen) + '...',
short2: (str, maxlen) => str.substring(0, maxlen) + (str.charAt(maxlen) && '...'),
short3: (str, maxlen) => str.replace(RegExp(`(.{${maxlen}}).+`), '$1...'),
short4: (str, maxlen) => str.replace(RegExp(`(?<=.{${maxlen}}).+`), '...'),
},
<input type="range" min="1" max="20" v-model="maxlen">
<span>{{ maxlen }}</span>
<div v-for="n in items">
<div v-text="short1(n, maxlen)"></div>
<div v-html="short2(n, maxlen)"></div>
<div :text-content.prop="short3(n, maxlen)"></div>
<div>{{ short4(n, maxlen) }}</div>
</div>
computed: {
columns() {
return Object.keys(this.fedresurs.find(n => n.items.length)?.items[0] ?? {});
},
},
<table v-for="messages in fedresurs">
<caption>{{ messages.title }}</caption>
<thead>
<tr>
<th v-for="column in columns">{{ column }}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in messages.items">
<td v-for="column in columns">{{ item[column] }}</td>
</tr>
</tbody>
</table>
Использую yandex-map@beta
пытаюсь изменить параметр zoom в YandexMap, но не работает, и что-то мне подсказывает, что не всё так просто
setup() {
...
let map = null;
return {
...
onCreate: e => map = e,
updateZoom: z => map.setZoom(Math.max(1, Math.min(19, map.getZoom() + z))),
};
},
<yandex-map
...
@created="onCreate"
/>
...
<button @click="updateZoom(+1)">+</button>
<button @click="updateZoom(-1)">-</button>
data: () => ({
currencies: [
{ title: 'рубль', rate: 1, val: 0 },
{ title: 'доллар', rate: 62.65, val: 0 },
{ title: 'евро', rate: 60.90, val: 0 },
],
}),
methods: {
onInput({ rate, val }) {
this.currencies.forEach(n => n.val = val * rate / n.rate);
},
},
<div v-for="n in currencies">
<input
v-model.number="n.val"
@input="onInput(n)"
type="number"
min="0"
>
{{ n.title }}
</div>
data: () => ({
filterColumns: [
[ 'name', 'имя', 'string' ],
[ 'count', 'количество', 'number' ],
[ 'distance', 'расстояние', 'number' ],
],
operations: [
[ 'equal', 'равно' ],
[ 'contains', 'содержит' ],
[ 'greater', 'больше' ],
[ 'less', 'меньше' ],
],
...
data: () => ({
types: {
string: {
equal: (a, b) => a.toLowerCase() === b,
contains: (a, b) => a.toLowerCase().includes(b),
greater: (a, b) => a.toLowerCase() > b,
less: (a, b) => a.toLowerCase() < b,
},
number: {
equal: (a, b) => a === +b,
contains: (a, b) => `${a}`.includes(b),
greater: (a, b) => a > +b,
less: (a, b) => a < +b,
},
},
...
<select v-model="column">
<option v-for="n in filterColumns" :value="n[0]">{{ n[1] }}</option>
</select>
<select v-model="operation">
<option v-for="n in operations" :value="n[0]">{{ n[1] }}</option>
</select>
computed: {
filteredItems() {
const { items, column } = this;
const type = this.filterColumns.find(n => n[0] === column)?.[2];
const filterFn = this.types[type]?.[this.operation];
const filterVal = this.filterVal.toLowerCase();
return filterFn && filterVal
? items.filter(n => filterFn(n[column], filterVal))
: items;
},
...
<card-item :title="Неработающий заголовок"/>
Динамически связывает атрибуты тега или входной параметр компонента с выражением.
Неработающий заголовок
- это выражение? <div class="wrapper" v-if="надо рендерить обёртку">
...
<элемент />
...
</div>
<элемент v-else />
Время, которое я задаю, применяется к fadeOut, а вот к runProgress нет
this.fadeOut = `fadeOut ${this.time}s linear forwards`, this.runProgress = `runProgress ${this.time}s liner forwards`,
v-for
. Если изменить значение свойства time и добавить в messages новый элемент, то у тех, что были добавлены раньше, изменится длительность анимации. Наверное, стоит вырезать свойства fadeOut и runProgress, элементам messages при создании добавлять актуальное значение свойства time, типа time: this.time
, и использовать его при задании стилей:methods: {
getStyle: (name, { time }) => ({
animation: `${name} ${time}s linear forwards`,
}),
...
:style="getStyle('fadeOut', message)"
:style="getStyle('runProgress', message)"
function shuffle(arr) {
for (let i = arr.length; i > 1;) {
const j = Math.random() * (i--) | 0;
[ arr[i], arr[j] ] = [ arr[j], arr[i] ];
}
return arr;
}
computed: {
shuffledAnswers() {
return shuffle(Object.entries(this.questions[this.idx].answers));
},
...
<div v-for="[ key, answer ] in shuffledAnswers">
...
"answers": {
import usersData from "../questions.json";
selectedAnswer: "",
count: 5,
<div v-if="idx < count">
computed:{ randomQuestions () { usersData.sort(() => Math.random() - 0.5)
:disabled="selectedAnswer != ''"
<button @click="nextQuestion"
document.querySelectorAll("input").forEach((el) => (el.checked = false));
:key="индекс_вопроса"
). Но это, конечно, костыльное решение. Правильно будет управлять радиокнопками основываясь на данных, через v-model
.@change="answered($event)"
answered(e) { this.selectedAnswer = e.target.value; if (this.selectedAnswer == this.questions[this.idx].correctAnswer) { this.correctAnswers++;