@dxtmisha/wiki 0.24.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/media/functional/en/about.mdx +55 -0
- package/src/media/functional/en/dataStorage.mdx +61 -83
- package/src/media/functional/en/useApiRef.mdx +517 -0
- package/src/media/functional/en/useBroadcastValueRef.mdx +344 -0
- package/src/media/functional/en/useCookieRef.mdx +348 -0
- package/src/media/functional/en/useGeoIntlRef.mdx +288 -0
- package/src/media/functional/en/useHashRef.mdx +302 -0
- package/src/media/functional/en/useLazyRef.mdx +329 -0
- package/src/media/functional/en/useLoadingRef.mdx +159 -0
- package/src/media/functional/en/useSessionRef.mdx +248 -0
- package/src/media/functional/en/useStorageRef.mdx +242 -0
- package/src/media/functional/en/useTranslateRef.mdx +312 -0
- package/src/media/functional/ru/about.mdx +55 -0
- package/src/media/functional/ru/dataStorage.mdx +59 -81
- package/src/media/functional/ru/useApiRef.mdx +517 -0
- package/src/media/functional/ru/useBroadcastValueRef.mdx +344 -0
- package/src/media/functional/ru/useCookieRef.mdx +348 -0
- package/src/media/functional/ru/useGeoIntlRef.mdx +288 -0
- package/src/media/functional/ru/useHashRef.mdx +302 -0
- package/src/media/functional/ru/useLazyRef.mdx +329 -0
- package/src/media/functional/ru/useLoadingRef.mdx +159 -0
- package/src/media/functional/ru/useSessionRef.mdx +248 -0
- package/src/media/functional/ru/useStorageRef.mdx +242 -0
- package/src/media/functional/ru/useTranslateRef.mdx +312 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import {Meta} from '@storybook/addon-docs/blocks'
|
|
2
|
+
|
|
3
|
+
<Meta title='@dxtmisha/functional/ru/Composables/useGeoIntlRef'/>
|
|
4
|
+
|
|
5
|
+
# Композабл useGeoIntlRef
|
|
6
|
+
|
|
7
|
+
Композабл для создания реактивного объекта интернационализации. Предоставляет методы форматирования чисел, валют, дат и названий с автоматическим учётом локали пользователя. Все методы возвращают computed значения, которые автоматически обновляются при изменении входных данных.
|
|
8
|
+
|
|
9
|
+
## Основные возможности
|
|
10
|
+
|
|
11
|
+
- **Форматирование чисел** — локализованное представление чисел с разделителями
|
|
12
|
+
- **Форматирование валют** — отображение денежных сумм с символами валют
|
|
13
|
+
- **Форматирование дат** — различные форматы дат и времени по региональным стандартам
|
|
14
|
+
- **Названия стран и языков** — локализованные названия регионов
|
|
15
|
+
- **Относительное время** — "2 дня назад", "через 5 минут" и т.д.
|
|
16
|
+
- **Проценты и единицы** — форматирование процентов и единиц измерения
|
|
17
|
+
- **Реактивность** — все методы возвращают computed, обновляющиеся автоматически
|
|
18
|
+
- **Автоопределение локали** — использует геолокацию пользователя по умолчанию
|
|
19
|
+
|
|
20
|
+
## Функция
|
|
21
|
+
|
|
22
|
+
### `useGeoIntlRef()`
|
|
23
|
+
|
|
24
|
+
Создаёт и возвращает экземпляр класса `GeoIntlRef` для работы с форматированием данных.
|
|
25
|
+
|
|
26
|
+
**Параметры:** нет
|
|
27
|
+
|
|
28
|
+
**Возвращает:** `GeoIntlRef` — объект с методами форматирования
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
import { useGeoIntlRef } from '@dxtmisha/functional'
|
|
32
|
+
|
|
33
|
+
// Создание экземпляра
|
|
34
|
+
const intl = useGeoIntlRef()
|
|
35
|
+
|
|
36
|
+
// Все методы возвращают ComputedRef
|
|
37
|
+
const formatted = intl.number(1234.56)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Методы форматирования чисел
|
|
41
|
+
|
|
42
|
+
### `number`
|
|
43
|
+
|
|
44
|
+
Форматирование числа согласно локали.
|
|
45
|
+
|
|
46
|
+
**Параметры:**
|
|
47
|
+
- `value: RefOrNormal<NumberOrString>` — число для форматирования
|
|
48
|
+
- `options?: Intl.NumberFormatOptions` — опции форматирования
|
|
49
|
+
|
|
50
|
+
**Возвращает:** `ComputedRef<string>`
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
const intl = useGeoIntlRef()
|
|
54
|
+
const count = ref(1234567.89)
|
|
55
|
+
|
|
56
|
+
intl.number(count) // ComputedRef<'1 234 567,89'>
|
|
57
|
+
intl.number(1000, { minimumFractionDigits: 2 }) // ComputedRef<'1 000,00'>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### `decimal`
|
|
61
|
+
|
|
62
|
+
Возвращает символ десятичного разделителя для текущей локали.
|
|
63
|
+
|
|
64
|
+
**Возвращает:** `ComputedRef<string>`
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const intl = useGeoIntlRef()
|
|
68
|
+
intl.decimal() // ComputedRef<','> (для ru-RU)
|
|
69
|
+
// ComputedRef<'.'> (для en-US)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `percent`
|
|
73
|
+
|
|
74
|
+
Форматирование числа как процента.
|
|
75
|
+
|
|
76
|
+
**Параметры:**
|
|
77
|
+
- `value: RefOrNormal<NumberOrString>` — число для форматирования (0.15 = 15%)
|
|
78
|
+
- `options?: Intl.NumberFormatOptions` — опции форматирования
|
|
79
|
+
|
|
80
|
+
**Возвращает:** `ComputedRef<string>`
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
intl.percent(0.15) // ComputedRef<'15%'>
|
|
84
|
+
intl.percent(1.25) // ComputedRef<'125%'>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### `percentBy100`
|
|
88
|
+
|
|
89
|
+
Форматирование числа как процента (значение уже в процентах).
|
|
90
|
+
|
|
91
|
+
**Параметры:**
|
|
92
|
+
- `value: RefOrNormal<NumberOrString>` — число для форматирования (15 = 15%)
|
|
93
|
+
- `options?: Intl.NumberFormatOptions` — опции форматирования
|
|
94
|
+
|
|
95
|
+
**Возвращает:** `ComputedRef<string>`
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
intl.percentBy100(15) // ComputedRef<'15%'>
|
|
99
|
+
intl.percentBy100(125) // ComputedRef<'125%'>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Методы форматирования валют
|
|
103
|
+
|
|
104
|
+
### `currency`
|
|
105
|
+
|
|
106
|
+
Форматирование денежной суммы.
|
|
107
|
+
|
|
108
|
+
**Параметры:**
|
|
109
|
+
- `value: RefOrNormal<NumberOrString>` — сумма для форматирования
|
|
110
|
+
- `currencyOptions?: RefOrNormal<string | Intl.NumberFormatOptions>` — код валюты или опции
|
|
111
|
+
- `numberOnly?: boolean` — не показывать символ валюты (по умолчанию `false`)
|
|
112
|
+
|
|
113
|
+
**Возвращает:** `ComputedRef<string>`
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
const intl = useGeoIntlRef()
|
|
117
|
+
const price = ref(99.99)
|
|
118
|
+
|
|
119
|
+
intl.currency(price, 'USD') // ComputedRef<'$99,99'>
|
|
120
|
+
intl.currency(1234.56, 'RUB') // ComputedRef<'1 234,56 ₽'>
|
|
121
|
+
intl.currency(500, 'EUR', true) // ComputedRef<'500,00'> (без символа)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `unit`
|
|
125
|
+
|
|
126
|
+
Форматирование с единицами измерения.
|
|
127
|
+
|
|
128
|
+
**Параметры:**
|
|
129
|
+
- `value: RefOrNormal<NumberOrString>` — значение для форматирования
|
|
130
|
+
- `unitOptions?: string | Intl.NumberFormatOptions` — единица измерения или опции
|
|
131
|
+
|
|
132
|
+
**Возвращает:** `ComputedRef<string>`
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
intl.unit(100, 'kilometer') // ComputedRef<'100 км'>
|
|
136
|
+
intl.unit(50, 'kilogram') // ComputedRef<'50 кг'>
|
|
137
|
+
intl.unit(1.5, 'hour') // ComputedRef<'1,5 ч'>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Методы форматирования дат
|
|
141
|
+
|
|
142
|
+
### `date`
|
|
143
|
+
|
|
144
|
+
Форматирование даты и времени.
|
|
145
|
+
|
|
146
|
+
**Параметры:**
|
|
147
|
+
- `value: RefOrNormal<NumberOrStringOrDate>` — дата для форматирования
|
|
148
|
+
- `type?: GeoDate` — тип формата ('date' | 'time' | 'datetime' | 'full' | 'long' | 'medium' | 'short')
|
|
149
|
+
- `styleOptions?: Intl.DateTimeFormatOptions['month'] | Intl.DateTimeFormatOptions` — стиль или опции
|
|
150
|
+
- `hour24?: boolean` — использовать 24-часовой формат
|
|
151
|
+
|
|
152
|
+
**Возвращает:** `ComputedRef<string>`
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
const date = ref(new Date('2024-10-15 14:30:00'))
|
|
156
|
+
|
|
157
|
+
intl.date(date) // ComputedRef<'15.10.2024'>
|
|
158
|
+
intl.date(date, 'time') // ComputedRef<'14:30'>
|
|
159
|
+
intl.date(date, 'datetime') // ComputedRef<'15.10.2024, 14:30'>
|
|
160
|
+
intl.date(date, 'full') // ComputedRef<'вторник, 15 октября 2024 г.'>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### `relative`
|
|
164
|
+
|
|
165
|
+
Форматирование относительного времени ("2 дня назад", "через час").
|
|
166
|
+
|
|
167
|
+
**Параметры:**
|
|
168
|
+
- `value: RefOrNormal<NumberOrStringOrDate>` — дата для сравнения
|
|
169
|
+
- `styleOptions?: Intl.RelativeTimeFormatStyle | Intl.RelativeTimeFormatOptions` — стиль ('long' | 'short' | 'narrow')
|
|
170
|
+
- `todayValue?: Date` — текущая дата (по умолчанию `new Date()`)
|
|
171
|
+
|
|
172
|
+
**Возвращает:** `ComputedRef<string>`
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
const twoDaysAgo = new Date()
|
|
176
|
+
twoDaysAgo.setDate(twoDaysAgo.getDate() - 2)
|
|
177
|
+
|
|
178
|
+
intl.relative(twoDaysAgo) // ComputedRef<'2 дня назад'>
|
|
179
|
+
intl.relative(twoDaysAgo, 'short') // ComputedRef<'2 дн. назад'>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### `relativeLimit`
|
|
183
|
+
|
|
184
|
+
Форматирование относительного времени с ограничением. Если разница превышает лимит, выводится абсолютная дата.
|
|
185
|
+
|
|
186
|
+
**Параметры:**
|
|
187
|
+
- `value: RefOrNormal<NumberOrStringOrDate>` — дата для форматирования
|
|
188
|
+
- `limit: number` — лимит в днях
|
|
189
|
+
- `todayValue?: Date` — текущая дата
|
|
190
|
+
- `relativeOptions?: Intl.RelativeTimeFormatStyle | Intl.RelativeTimeFormatOptions` — опции относительного формата
|
|
191
|
+
- `dateOptions?: Intl.DateTimeFormatOptions['month'] | Intl.DateTimeFormatOptions` — опции формата даты
|
|
192
|
+
- `type?: GeoDate` — тип формата даты
|
|
193
|
+
- `hour24?: boolean` — 24-часовой формат
|
|
194
|
+
|
|
195
|
+
**Возвращает:** `ComputedRef<string>`
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
const threeDaysAgo = new Date()
|
|
199
|
+
threeDaysAgo.setDate(threeDaysAgo.getDate() - 3)
|
|
200
|
+
|
|
201
|
+
intl.relativeLimit(threeDaysAgo, 7) // ComputedRef<'3 дня назад'>
|
|
202
|
+
|
|
203
|
+
const tenDaysAgo = new Date()
|
|
204
|
+
tenDaysAgo.setDate(tenDaysAgo.getDate() - 10)
|
|
205
|
+
|
|
206
|
+
intl.relativeLimit(tenDaysAgo, 7) // ComputedRef<'05.10.2024'> (абсолютная дата)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Методы для названий
|
|
210
|
+
|
|
211
|
+
### `display`
|
|
212
|
+
|
|
213
|
+
Получение локализованного названия (языка, региона, скрипта и т.д.).
|
|
214
|
+
|
|
215
|
+
**Параметры:**
|
|
216
|
+
- `value?: RefOrNormal<string>` — код для получения названия
|
|
217
|
+
- `typeOptions?: Intl.DisplayNamesOptions['type'] | Intl.DisplayNamesOptions` — тип ('language' | 'region' | 'script' | 'currency')
|
|
218
|
+
|
|
219
|
+
**Возвращает:** `ComputedRef<string>`
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
intl.display('US', 'region') // ComputedRef<'США'>
|
|
223
|
+
intl.display('en', 'language') // ComputedRef<'английский'>
|
|
224
|
+
intl.display('USD', 'currency') // ComputedRef<'доллар США'>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### `languageName`
|
|
228
|
+
|
|
229
|
+
Получение названия языка.
|
|
230
|
+
|
|
231
|
+
**Параметры:**
|
|
232
|
+
- `value?: RefOrNormal<string>` — код языка
|
|
233
|
+
- `style?: Intl.RelativeTimeFormatStyle` — стиль отображения
|
|
234
|
+
|
|
235
|
+
**Возвращает:** `ComputedRef<string>`
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
intl.languageName('en') // ComputedRef<'английский'>
|
|
239
|
+
intl.languageName('de') // ComputedRef<'немецкий'>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### `countryName`
|
|
243
|
+
|
|
244
|
+
Получение названия страны.
|
|
245
|
+
|
|
246
|
+
**Параметры:**
|
|
247
|
+
- `value?: RefOrNormal<string>` — код страны
|
|
248
|
+
- `style?: Intl.RelativeTimeFormatStyle` — стиль отображения
|
|
249
|
+
|
|
250
|
+
**Возвращает:** `ComputedRef<string>`
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
intl.countryName('US') // ComputedRef<'США'>
|
|
254
|
+
intl.countryName('GB') // ComputedRef<'Великобритания'>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Примеры использования
|
|
258
|
+
|
|
259
|
+
### Базовое использование
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
import { ref } from 'vue'
|
|
263
|
+
import { useGeoIntlRef } from '@dxtmisha/functional'
|
|
264
|
+
|
|
265
|
+
const intl = useGeoIntlRef()
|
|
266
|
+
const price = ref(1234.56)
|
|
267
|
+
|
|
268
|
+
// Все методы возвращают ComputedRef
|
|
269
|
+
const formatted = intl.currency(price, 'USD')
|
|
270
|
+
console.log(formatted.value) // '$1,234.56'
|
|
271
|
+
|
|
272
|
+
// Автоматическое обновление при изменении
|
|
273
|
+
price.value = 2000
|
|
274
|
+
console.log(formatted.value) // '$2,000.00'
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Реактивные параметры
|
|
278
|
+
|
|
279
|
+
```javascript
|
|
280
|
+
const price = ref(100)
|
|
281
|
+
const currency = ref('USD')
|
|
282
|
+
|
|
283
|
+
// Реактивная валюта и значение
|
|
284
|
+
const formatted = intl.currency(price, currency)
|
|
285
|
+
|
|
286
|
+
currency.value = 'EUR'
|
|
287
|
+
// formatted.value автоматически обновится
|
|
288
|
+
```
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import {Meta} from '@storybook/addon-docs/blocks'
|
|
2
|
+
|
|
3
|
+
<Meta title='@dxtmisha/functional/ru/Composables/useHashRef'/>
|
|
4
|
+
|
|
5
|
+
# Композабл useHashRef
|
|
6
|
+
|
|
7
|
+
Композабл для создания реактивной переменной, синхронизированной с URL hash. Автоматически управляет чтением и записью значений в hash часть URL, обеспечивая двустороннюю синхронизацию между реактивным состоянием Vue и параметрами в адресной строке браузера.
|
|
8
|
+
|
|
9
|
+
## Основные возможности
|
|
10
|
+
|
|
11
|
+
- **Двусторонняя синхронизация** — автоматическая синхронизация между ref и URL hash
|
|
12
|
+
- **Автоматическое сохранение** — изменения ref автоматически отражаются в URL
|
|
13
|
+
- **Реактивность** — изменения URL hash автоматически обновляют ref
|
|
14
|
+
- **Кеширование экземпляров** — переиспользование ref для одинаковых имён параметров
|
|
15
|
+
- **Типобезопасность** — полная поддержка TypeScript с дженериками
|
|
16
|
+
- **Значения по умолчанию** — поддержка начальных значений и функций-фабрик
|
|
17
|
+
- **Автоматическая инициализация** — загрузка существующих значений из URL при создании
|
|
18
|
+
|
|
19
|
+
## Функция
|
|
20
|
+
|
|
21
|
+
### `useHashRef`
|
|
22
|
+
|
|
23
|
+
Создаёт реактивную переменную, синхронизированную с параметром в URL hash.
|
|
24
|
+
|
|
25
|
+
**Параметры:**
|
|
26
|
+
- `name: string` — имя параметра в hash URL
|
|
27
|
+
- `defaultValue?: T | (() => T)` — значение по умолчанию или функция для его генерации (опционально)
|
|
28
|
+
|
|
29
|
+
**Возвращает:** `Ref<T>` — реактивная переменная Vue, связанная с hash параметром
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
import { useHashRef } from '@dxtmisha/functional'
|
|
33
|
+
|
|
34
|
+
// Простое использование без значения по умолчанию
|
|
35
|
+
const currentTab = useHashRef('tab')
|
|
36
|
+
console.log(currentTab.value) // undefined (если hash пустой)
|
|
37
|
+
|
|
38
|
+
// С значением по умолчанию
|
|
39
|
+
const activeView = useHashRef('view', 'grid')
|
|
40
|
+
console.log(activeView.value) // 'grid' (если hash не содержит 'view')
|
|
41
|
+
|
|
42
|
+
// С функцией-фабрикой для значения по умолчанию
|
|
43
|
+
const userId = useHashRef('userId', () => Math.floor(Math.random() * 1000))
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Основное использование
|
|
47
|
+
|
|
48
|
+
### Базовая синхронизация
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
import { useHashRef } from '@dxtmisha/functional'
|
|
52
|
+
|
|
53
|
+
// Создание ref, синхронизированного с hash
|
|
54
|
+
const currentPage = useHashRef('page', 1)
|
|
55
|
+
|
|
56
|
+
// При изменении ref - URL автоматически обновляется
|
|
57
|
+
currentPage.value = 2
|
|
58
|
+
// URL: #page=2
|
|
59
|
+
|
|
60
|
+
currentPage.value = 5
|
|
61
|
+
// URL: #page=5
|
|
62
|
+
|
|
63
|
+
// При изменении URL вручную - ref автоматически обновляется
|
|
64
|
+
// Пользователь меняет URL на: #page=10
|
|
65
|
+
console.log(currentPage.value) // 10
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Работа с несколькими параметрами
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
// Несколько независимых hash параметров
|
|
72
|
+
const searchQuery = useHashRef('q', '')
|
|
73
|
+
const sortOrder = useHashRef('sort', 'asc')
|
|
74
|
+
const pageNumber = useHashRef('page', 1)
|
|
75
|
+
|
|
76
|
+
searchQuery.value = 'vue композаблы'
|
|
77
|
+
sortOrder.value = 'desc'
|
|
78
|
+
pageNumber.value = 3
|
|
79
|
+
|
|
80
|
+
// URL: #q=vue композаблы;sort=desc;page=3
|
|
81
|
+
|
|
82
|
+
// Все параметры остаются синхронизированными
|
|
83
|
+
console.log(searchQuery.value) // 'vue композаблы'
|
|
84
|
+
console.log(sortOrder.value) // 'desc'
|
|
85
|
+
console.log(pageNumber.value) // 3
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Кеширование экземпляров
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
// При повторном вызове с тем же именем возвращается существующий ref
|
|
92
|
+
const tab1 = useHashRef('activeTab', 'home')
|
|
93
|
+
const tab2 = useHashRef('activeTab', 'profile')
|
|
94
|
+
|
|
95
|
+
console.log(tab1 === tab2) // true - тот же ref
|
|
96
|
+
|
|
97
|
+
tab1.value = 'settings'
|
|
98
|
+
console.log(tab2.value) // 'settings' - оба указывают на один ref
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Использование в компонентах
|
|
102
|
+
|
|
103
|
+
### Управление табами
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
import { useHashRef } from '@dxtmisha/functional'
|
|
107
|
+
|
|
108
|
+
export default {
|
|
109
|
+
setup() {
|
|
110
|
+
const activeTab = useHashRef('tab', 'overview')
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
activeTab,
|
|
114
|
+
tabs: ['overview', 'details', 'settings']
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Template:
|
|
120
|
+
// <div>
|
|
121
|
+
// <button
|
|
122
|
+
// v-for="tab in tabs"
|
|
123
|
+
// :key="tab"
|
|
124
|
+
// @click="activeTab = tab"
|
|
125
|
+
// :class="{ active: activeTab === tab }"
|
|
126
|
+
// >
|
|
127
|
+
// {{ tab }}
|
|
128
|
+
// </button>
|
|
129
|
+
// </div>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Пагинация с сохранением состояния
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
import { computed } from 'vue'
|
|
136
|
+
import { useHashRef } from '@dxtmisha/functional'
|
|
137
|
+
|
|
138
|
+
export default {
|
|
139
|
+
setup() {
|
|
140
|
+
const currentPage = useHashRef('page', 1)
|
|
141
|
+
const itemsPerPage = 20
|
|
142
|
+
const totalItems = 100
|
|
143
|
+
|
|
144
|
+
const totalPages = computed(() =>
|
|
145
|
+
Math.ceil(totalItems / itemsPerPage)
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
const nextPage = () => {
|
|
149
|
+
if (currentPage.value < totalPages.value) {
|
|
150
|
+
currentPage.value++
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const prevPage = () => {
|
|
155
|
+
if (currentPage.value > 1) {
|
|
156
|
+
currentPage.value--
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
currentPage,
|
|
162
|
+
totalPages,
|
|
163
|
+
nextPage,
|
|
164
|
+
prevPage
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Фильтры и поиск
|
|
171
|
+
|
|
172
|
+
```javascript
|
|
173
|
+
import { watch } from 'vue'
|
|
174
|
+
import { useHashRef } from '@dxtmisha/functional'
|
|
175
|
+
|
|
176
|
+
export default {
|
|
177
|
+
setup() {
|
|
178
|
+
const searchQuery = useHashRef('q', '')
|
|
179
|
+
const category = useHashRef('category', 'all')
|
|
180
|
+
const sortBy = useHashRef('sort', 'date')
|
|
181
|
+
|
|
182
|
+
// Отслеживание изменений для загрузки данных
|
|
183
|
+
watch([searchQuery, category, sortBy], () => {
|
|
184
|
+
console.log('Загрузка данных с параметрами:')
|
|
185
|
+
console.log('Поиск:', searchQuery.value)
|
|
186
|
+
console.log('Категория:', category.value)
|
|
187
|
+
console.log('Сортировка:', sortBy.value)
|
|
188
|
+
// Здесь выполняется запрос к API
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
searchQuery,
|
|
193
|
+
category,
|
|
194
|
+
sortBy
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Работа с типами данных
|
|
201
|
+
|
|
202
|
+
### Числовые значения
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
// Hash автоматически преобразует типы
|
|
206
|
+
const pageNumber = useHashRef<number>('page', 1)
|
|
207
|
+
|
|
208
|
+
pageNumber.value = 5
|
|
209
|
+
// URL: #page=5
|
|
210
|
+
|
|
211
|
+
// При загрузке из URL строка автоматически преобразуется
|
|
212
|
+
// URL: #page=10
|
|
213
|
+
console.log(typeof pageNumber.value) // 'number'
|
|
214
|
+
console.log(pageNumber.value) // 10
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Булевы значения
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
const isActive = useHashRef<boolean>('active', false)
|
|
221
|
+
|
|
222
|
+
isActive.value = true
|
|
223
|
+
// URL: #active=true
|
|
224
|
+
|
|
225
|
+
// Автоматическое преобразование из строки
|
|
226
|
+
// URL: #active=false
|
|
227
|
+
console.log(typeof isActive.value) // 'boolean'
|
|
228
|
+
console.log(isActive.value) // false
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Объекты и массивы
|
|
232
|
+
|
|
233
|
+
```javascript
|
|
234
|
+
// Для сложных типов используется сериализация
|
|
235
|
+
const filters = useHashRef('filters', { min: 0, max: 100 })
|
|
236
|
+
|
|
237
|
+
filters.value = { min: 20, max: 80 }
|
|
238
|
+
// URL будет содержать сериализованное представление
|
|
239
|
+
|
|
240
|
+
// Значения восстанавливаются при загрузке
|
|
241
|
+
console.log(filters.value) // { min: 20, max: 80 }
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Интеграция с классом Hash
|
|
245
|
+
|
|
246
|
+
Композабл использует класс `Hash` для управления URL hash:
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
import { Hash } from '@dxtmisha/functional'
|
|
250
|
+
|
|
251
|
+
// Прямое использование класса
|
|
252
|
+
Hash.set('tab', 'profile')
|
|
253
|
+
console.log(Hash.get('tab')) // 'profile'
|
|
254
|
+
|
|
255
|
+
// useHashRef автоматически синхронизируется с Hash
|
|
256
|
+
const tab = useHashRef('tab')
|
|
257
|
+
console.log(tab.value) // 'profile'
|
|
258
|
+
|
|
259
|
+
// Изменения через Hash отражаются в ref
|
|
260
|
+
Hash.set('tab', 'settings')
|
|
261
|
+
console.log(tab.value) // 'settings'
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Примеры использования
|
|
265
|
+
|
|
266
|
+
### Сохранение состояния формы
|
|
267
|
+
|
|
268
|
+
```javascript
|
|
269
|
+
const formData = {
|
|
270
|
+
name: useHashRef('name', ''),
|
|
271
|
+
email: useHashRef('email', ''),
|
|
272
|
+
role: useHashRef('role', 'user')
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// При заполнении формы состояние сохраняется в URL
|
|
276
|
+
formData.name.value = 'Иван'
|
|
277
|
+
formData.email.value = 'ivan@example.com'
|
|
278
|
+
formData.role.value = 'admin'
|
|
279
|
+
|
|
280
|
+
// URL: #name=Иван;email=ivan@example.com;role=admin
|
|
281
|
+
|
|
282
|
+
// При перезагрузке страницы состояние восстанавливается
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Управление модальными окнами
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
const modalOpen = useHashRef('modal', null)
|
|
289
|
+
|
|
290
|
+
const openModal = (modalName) => {
|
|
291
|
+
modalOpen.value = modalName
|
|
292
|
+
// URL: #modal=confirmation
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const closeModal = () => {
|
|
296
|
+
modalOpen.value = null
|
|
297
|
+
// URL: #modal=null или hash очищается
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Кнопка "Назад" в браузере закрывает модальное окно
|
|
301
|
+
```
|
|
302
|
+
|