data: () => ({
columns: [
{ field: '...', label: '...' },
{ field: '...', label: '...' },
...
],
focused: {},
...
}),
methods: {
rowStyle(row) {
return row === this.focused.record && {
backgroundColor: 'red',
};
},
cellStyle(row, cell) {
return cell.name === this.columns[this.focused.colPos]?.field && {
backgroundColor: 'orange',
};
},
},
<vue-excel-editor
:row-style="rowStyle"
:cell-style="cellStyle"
@cell-focus="focused = $event"
...
>
<vue-excel-column
v-for="n in columns"
v-bind="n"
:key="n.field"
/>
</vue-excel-editor>
state: {
pokemons: [],
next: 'https://pokeapi.co/api/v2/pokemon',
},
actions: {
async fetchPokemons({ state, commit }) {
const data = await fetch(state.next).then(r => r.json());
commit('setPokemons', {
pokemons: data.results,
next: data.next,
});
}
},
<button
:disabled="!$store.state.next"
@click="$store.dispatch('fetchPokemons')"
>
NEXT
</button>
const defaultAnimals = {
cat: '',
dog: '',
mouse: '',
rhinoceros: '',
};
const animalsReducer = (state, action) => {
switch (action.type) {
case 'updateObj':
return {
...state,
obj: {
...state.obj,
[action.payload.name]: action.payload.value,
},
};
case 'addObjToArr':
return {
...state,
arr: [ ...state.arr, state.obj ],
obj: defaultAnimals,
};
default:
return state;
}
};
const Animals = () => {
const [ animals, dispatch ] = useReducer(animalsReducer, {
obj: defaultAnimals,
arr: [],
});
const onChange = ({ target: { name, value } }) => {
dispatch({
type: 'updateObj',
payload: { name, value },
});
};
const onSubmit = e => {
e.preventDefault();
dispatch({
type: 'addObjToArr',
});
};
return (
<div>
<form onSubmit={onSubmit}>
{Object.entries(animals.obj).map(([ k, v ]) => (
<div key={k}>
<label>
{k}:
<input name={k} value={v} onChange={onChange} />
</label>
</div>
))}
<button>Save</button>
</form>
<pre>{JSON.stringify(animals.obj, null, 2)}</pre>
<pre>{JSON.stringify(animals.arr, null, 2)}</pre>
</div>
);
};
const animalsReducer = (state, action) => {
switch (action.type) {
case 'updateObj':
return {
...state,
obj: {
...state.obj,
[action.payload.name]: action.payload.value,
},
};
case 'addObjToArr':
return {
...state,
arr: [
...state.arr,
{
animal: action.payload,
name: state.obj[action.payload],
},
],
};
default:
return state;
}
};
const Animals = () => {
const [ { obj, arr }, dispatch ] = useReducer(animalsReducer, {
obj: {
cat: '',
dog: '',
mouse: '',
rhinoceros: '',
},
arr: [],
});
const onChange = ({ target: { name, value } }) => {
dispatch({
type: 'updateObj',
payload: { name, value },
});
};
const onSubmit = (e, animal) => {
e.preventDefault();
dispatch({
type: 'addObjToArr',
payload: animal,
});
};
return (
<div>
{Object.entries(obj).map(([ k, v ]) => (
<form onSubmit={e => onSubmit(e, k)} key={k}>
{k}:
<input name={k} value={v} onChange={onChange} />
<button>Save</button>
</form>
))}
<pre>{JSON.stringify(obj, null, 2)}</pre>
<pre>{JSON.stringify(arr, null, 2)}</pre>
</div>
);
};
components: {
componentName: () => import('...').then(component => {
console.log(component.default.props);
return component;
}),
...
},
const getNestedValues = (arr, nestedKey, valKey) =>
Array.isArray(arr)
? arr.flatMap(n => [ n[valKey], ...getNestedValues(n[nestedKey], nestedKey, valKey) ])
: [];
const values = getNestedValues(arr, 'evolves_to', 'species');
methods: {
toggleElement(id) {
const index = this.selectedElArr.indexOf(id);
if (index !== -1) {
this.selectedElArr.splice(index, 1);
} else {
this.selectedElArr.push(id);
}
},
...
@click="toggleElement(data.id)"
const selectors = [ '.addservice', '.addprice' ];
const data = Array.from(
document.querySelectorAll('.addserviceBlock'),
n => selectors.map(m => n.querySelector(m).value)
);
const wrapper = document.createElement('div');
const start = block.querySelector('.start');
for (let el; !(el = start.nextElementSibling).matches('.end'); wrapper.appendChild(el)) ;
start.insertAdjacentElement('afterend', wrapper);
const wrapper = document.createElement('div');
const children = [...block.children];
const iStart = children.findIndex(n => n.classList.contains('start'));
const iEnd = children.findIndex(n => n.classList.contains('end'));
wrapper.append(...children.slice(iStart + 1, iEnd));
children[iStart].after(wrapper);
data.reduce((acc, { unique, id, count, name }) => (
((acc[unique] ??= { count })[id] ??= []).push(name),
acc
), {})
const names = [ 'иван', 'антон' ] as const;
type Name = typeof names[number];
const fn = (name: Name) => name;
function chunked(str, numChunks) {
const chunkSize = Math.ceil(str.length / numChunks);
return Array.from(
{ length: numChunks },
(n, i) => str.slice(i * chunkSize, (i + 1) * chunkSize)
);
}
function chunked(str, numChunks) {
return str.match(RegExp(`.{1,${Math.ceil(str.length / numChunks)}}`, 'g'));
}
function chunked(str, numChunks) {
return str.split(RegExp(`(.{${Math.ceil(str.length / numChunks)}})`)).filter(Boolean);
}
неаккуратненько как-то:
chunked('test', 3) // [ "te", "st", "" ]
const chunked = (str, numChunks) =>
numChunks <= str.length
? Array.from(
{ length: numChunks },
function(n, i) {
return str.slice(i * this, i === numChunks - 1 ? str.length : (i + 1) * this);
},
str.length / numChunks | 0
)
: 'извини, столько непустых кусков нарезать нельзя';
function chunked(str, numChunks) {
const chunkSize = str.length / numChunks | 0;
const numLooseItems = str.length % numChunks;
return Array.from(
{ length: numChunks },
function(_, i) {
return str.slice(this(i), this(i + 1));
},
i => i * chunkSize + Math.min(i, numLooseItems)
);
}