require
не "берёт картинки из папки", require
обрабатывает картинки loader'om
и выдаёт в ответ результат. Статический результат, который попадает в бандл. require(`./img/${name}.png`);
- не значит "взять картинку по имени name
из папки img
во время исполнения", это значит "во время компиляции взять все картинки с маской './img/*.png',
обработать loader'ом
, получить для каждой статическую ссылку, и положить в бандл". loader'ы
по умолчанию превращают маленькие картинки в data:uri
строки, а большие перекладывают в папочку imgs
и переименовывают с хэшем, возвращая путь. Но это по-умолчанию, а так они способны много всякой магии творить.public
копируются в результирующую папку как есть и доступны по /name.png
без require
, просто через обычный html
и css
. computed
не будет пересчитаться при обновлении ref'ов или dom-значений. Он работает с реактивными данными.computed
и поместите в mounted
, вручную присваивая значения переменной в data
. Не забудьте добавить значения по умолчанию, а также обновлять их при необходимости(по событию resize или ещё какому, способныму повлиять на эти размеры)./catalog/:slug/:option?
./catalog/:slug/(.*)?
и ловить любые пути. const queryKey: AuthMessagesKeys = queryObject.message
function isAuthMessagesKey(str: string): str is AuthMessagesKeys {
return ['login', 'logout', 'session'].includes(str);
}
const loader_1 = new GCodeLoader();
const loader_2 = new AMFLoader();
let ask_1 = true;
let ask_2 = true;
async function main() {
console.log('Start load')
if (ask_1){
const amfobject = await loader_1.loadAsync( './models/amf/rook.amf');
scene.add( amfobject );
console.log('on loader AMF', amfobject);
}
if (ask_2){
const object = await loader_2.loadAsync( 'models/gcode/benchy.gcode');
scene.add( object );
console.log('on loader GCode', object);
}
console.log('END load')
}
main();
Promise
- это просто хитрая надстройка надо коллбэками(полностью реализуемая на обычном js), позволяющая развернуть их порядок назначения - не более. async-await
- просто синтаксический сахар над Promise
, делающий оные менее многословными, но не меняющий механизма. PropsWithChildren<Props>
. Но под капотом он просто делает так: type PropsWithChildren<P> = P & { children?: ReactNode };
type TwitterProps = {
children: (user: string) => ReactNode
}
const response: ITwitter = ...
. Только если какая-нить хрень прилетит то может сломаться в рантайме, так что либо ты доверяешь серверу, либо используешь какую-нить либу для дополнительной проверки вживую.) type WritableFields<T> = Partial<Pick<T, WritableKeys<T>>>;
export function createElement<K extends keyof HTMLElementTagNameMap>(tag: K, options?: WritableFields<HTMLElementTagNameMap[K]>): HTMLElementTagNameMap[K] {
let element = document.createElement(tag)
if (options) {
// assign options
Object.assign(element, options);
}
return element
}
type WritableFields<T> = Partial<Pick<T, WritableKeys<T>>>;
export function createElement<K extends keyof HTMLElementTagNameMap>(tag: K, options?: WritableFields<HTMLElementTagNameMap[K]>): HTMLElementTagNameMap[K] {
let element = document.createElement(tag)
if (options) {
// assign options
let option: keyof typeof options;
for (option in options) {
element[option] = options[option]!; // ! - потому что теоретически ты можешь передать undefined явно, но морочиться с этим не стоит
}
}
return element
}
interface Foo {
foo: number;
}
тебе ничего не мешает передать ему {
foo: 1,
bar: 2
}
, т.к. данный объект расширяет интерфейс Foo и, соответственно, удовлетворяет ему. Получается, что внутри функции typescript никак не может быть уверен, что ключи указанные в интерфейсе - это ВСЕ ключи, а значит не может быть уверен, что при переборе и присвоении не будет присвоено что-то лишнее. (Это не говоря уже о прототипах, геттерах и прочем) Vue
появились дополнительные свойства типа $route
. Надо отдельно подключать декларации вручную, либо следовать инструкции выше.