export default defineComponent({
name: 'CounterButton',
props: {
count: {
type: Number,
default: 0
}
},
template: `<button type="button" @click="counter++">{{counter}}</button>`,
emits: ['update:count'],
setup(props, context) {
const innerCounter = ref(props.count);
watch(() => props.count, (value) => innerCounter.value = value);
return {
counter: computed({
get: () => innerCounter.value,
set: (value) => context.emit('update:count', innerCounter.value = value)
})
}
}
})
BehaviorSubject
не стоит, не одному тебе потом с ним работать.class DistinctBehaviorSubject<T> extends BehaviorSubject<T> {
next(value: T) {
if (this.value !== value)
super.next(value);
}
}
Но я на вскидку не скажу какие тут могут быть подводные камни.) function doSomething(param: string, value: unknown) {
console.log('doSomething', param, value);
}
function WebworkerParam(param: string){
return (target: any, key: PropertyKey) => {
let subscription: Subscription;
let innerValue: any;
Object.defineProperty(target, key, {
get() {
return innerValue;
},
set(value) {
if (subscription)
subscription.unsubscribe();
if(value instanceof BehaviorSubject)
subscription = value.subscribe(newValue => doSomething(param, newValue));
else
doSomething(param, value);
innerValue = value;
}
})
}
}
type MethodNames<T extends string> = `get${T}s` | `create${T}` | `get${T}`;
interface IAPI {
new <T extends string>(type: T, url: string): {
[K in MethodNames<T>]: Function
}
}
export default API as unknown as IAPI;
сработает как надо. Естественно ты можешь доработать интерфейс IAPI до полного совпадения.type MethodNames<T extends string> = `get${T}s` | `create${T}` | `get${T}`;
class API {
[key: MethodNames<string>]: Function
_url;
constructor(type: string, url: string) {
this._url = url;
this[`get${type}s`] = this._readMany;
this[`create${type}`] = this._create;
this[`get${type}`] = this._read;
}
_readMany(params = {}) {
const options = getApiOptions(Method.GET);
const url = new URL(this._url);
url.search = new URLSearchParams(params);
return fetch(url.toString(), options);
}
_create(body) {
const options = getApiOptions(Method.POST, body);
return fetch(this._url, options);
}
_read(id) {
const options = getApiOptions(Method.GET);
return fetch(`${this._url}/{id}`, options);
}
}
Date
не может быть children'ом для компонента, и это так. Однако дело в том, что тип у тебя задан неверно, на самом деле у тебя там никакой не Date
а банальный string
. Если ты поправишь типы, то всё заработает и выведет тебе то что ты передаёшь, т.е. 2012-03-23T08:25:44.962Z
.2012-03-23T08:25:44.962Z
в строку Created 7 years ago
надо либо руками написать соответствующую функцию, либо воспользоваться какой-либо библиотекой для работы с датами. Например с помощью moment
это будет выглядеть примерно так:const createdFromNow = `Created ${
moment.duration(moment().diff(data.createdAt)).humanize()
} ago`;
А ещё динамическая типизация сильно экономит время на написание кода - это очень нехилая оптимизация рабочего процесса.
moment.updateLocale('uz-latn', {
relativeTime: {
past: '%s oldin'
}
});
moment.defineLocale('uz-latn-short', {
parentLocale: 'uz-latn',
relativeTime: {
past: '%s oldin'
}
});
и используешь её где надо.