Math.random
в sort
в любом случае не даст нормального распределения, т.к. под капотом используется определённый оптимизированный алгоритм сортировки, к тому же браузерозаивисимый и разный для разных случаев. sort
ни для чего, кроме его предназначения - детерминированной сортировки.function shuffle( array ) { // Shuffle an array
//
// + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
for(var j, x, i = array.length; i; j = parseInt(Math.random() * i), x = array[--i], array[i] = array[j], array[j] = x);
return true;
}
о какой рендер функции идет речь?
<template>
.(под капотом <template>
компилируется в render-функцию)setup
, можно класть в свойство render
.script setup,
можно сделать так:<template>
<div>
<render/>
</div>
</template>
<script setup lang="ts">
import { h, useSlots } from 'vue'
const slots = useSlots();
const render = () => {
return h('div', slots.default());
};
</script>
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);
}
}