this
внутри function
зависит от контекста вызова этой function
.onAuthStateChanged
- вызывается переданная ему функция-обработчик, которой устанавливается какой-то this
(или не устанавливается, и тогда он по умолчанию window
или, в строгом режиме, undefined
). И этот this
точно никак не связан с текущим this
Vue, потому что тот никаким образом не передан при вызове, и, соответственно onAuthStateChanged
о нём ничего не знает.(async function(user) { ... }).bind(this)
чтобы жёстко привязать эту функцию к this
.vm.g = 5;
, т.к. таким образом конкретный this
сохранён в переменную и не меняется в зависимости от контекста вызова.async (user) => { ... }
, её механика работы по сути осуществляет неявный bind
.bind
всех методов к this:onAuthStateChanged(this.onAuthStateChanged)
methods: {
onAuthStateChanged: async function (user) { ... }
}
Array.forEach
- синхронный. Он не будет ждать промисов. Либо используй какие-то либы которые умеют асинхронный each
и всё остальное, либо используй обычный цикл: for (const lId of locationIds) {
const syncResp = await fetch(`https://server/sync-one-c/26/41/${lId}`).then(resp => resp.json())
console.log('lId -> ', lId, 'done', syncResp)
})
firefox
есть такая нестандартная фича как -moz-element
, которая идеально подходит под задачу: canvas
движке(можно попробовать что-то такое), и тогда просто получать копию холста на меньший canvas
. Это более оптимально но требует переписывание всего и сложности основной работы.Vue.observable
\reactive
или vuex
), один из которых уменьшать с помощью transform: scale()
.html2canvas
, предложенный выше, имеет очень ограниченную область применения и вряд ли тут сработает, но можете попробоватьthis.$el.cloneNode(true)
и класть полученную копию в нужное место с тем же transform: scale()
, но это может весьма сильно тормозить в зависимости от количества элементов и частоты обновления. let routes = await axios(...)
.then((response: AxiosResponse<Route[]>) => response.data)
.catch(console.log);
Нет смысла гонять из пустого в порожнее.const ROUTES = {
blog: {
art: 'page-art',
toString() {
return 'section-blog'
}
}
}
ROUTES.blog.art // page-art
ROUTES.blog // object
'text: ' + ROUTES.blog // text: section-blog
const minGap = 3;
const keys = ['name', 'price'];
const input = [
{
name: "абрикосы",
price: 20
},
{
name: "тыква",
price: 50
},
{
name: "уи",
price: 1000
}
];
const maxLengths = keys.slice().fill(0);
const normalizedInput = input.map(item => keys.reduce((acc, key, i) => {
const current = String(item[key]);
const currentLength = current.length;
if(currentLength > maxLengths[i])
maxLengths[i] = currentLength;
acc[key] = current;
acc.length += currentLength;
return acc;
}, { length: 0 }));
const maxLength = maxLengths.reduce(
(sum, current) => sum + current,
minGap
);
const res = normalizedInput
.map(({
name,
price,
length
}) => name + ' '.repeat(maxLength - length) + price)
.join('\n');