config axios

parent 811d164a
......@@ -31,3 +31,6 @@ yarn-error.log*
*.ntvs*
*.njsproj
*.sln
*.env
configurations.ts
.env
\ No newline at end of file
......@@ -10,8 +10,11 @@
"@quasar/extras": "^1.0.0",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"http-status-codes": "^2.1.4",
"quasar": "^2.0.0-beta.1",
"vue-i18n": "^9.0.0-beta.0"
"secure-ls": "^1.2.6",
"vue-i18n": "^9.0.0-beta.0",
"vuex-persistedstate": "^4.0.0-beta.3"
},
"devDependencies": {
"@quasar/app": "^3.0.0-beta.1",
......@@ -19,6 +22,7 @@
"@typescript-eslint/eslint-plugin": "^4.16.1",
"@typescript-eslint/parser": "^4.16.1",
"babel-eslint": "^10.0.1",
"dotenv": "^8.2.0",
"eslint": "^7.14.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-vue": "^7.0.0"
......@@ -4844,6 +4848,11 @@
"node": "*"
}
},
"node_modules/crypto-js": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
"integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q=="
},
"node_modules/css-color-names": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
......@@ -5695,7 +5704,6 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
......@@ -6038,6 +6046,15 @@
"node": ">=8"
}
},
"node_modules/dotenv": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
......@@ -8450,6 +8467,11 @@
"node": ">=8.0.0"
}
},
"node_modules/http-status-codes": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.1.4.tgz",
"integrity": "sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg=="
},
"node_modules/https-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
......@@ -9829,6 +9851,14 @@
"yallist": "^3.0.2"
}
},
"node_modules/lz-string": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
"integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=",
"bin": {
"lz-string": "bin/bin.js"
}
},
"node_modules/magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
......@@ -16811,6 +16841,15 @@
"url": "https://opencollective.com/webpack"
}
},
"node_modules/secure-ls": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/secure-ls/-/secure-ls-1.2.6.tgz",
"integrity": "sha512-g8vUSKl6elSfyAUHodybnNkuZW+mUYEOWj4SZIDg+xoQ1dq5ddktBoOFrtxQBUl88ZyAJOtGWQ1PRaOxkTAuZQ==",
"dependencies": {
"crypto-js": "^3.1.6",
"lz-string": "^1.4.4"
}
},
"node_modules/select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
......@@ -17097,6 +17136,11 @@
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
"dev": true
},
"node_modules/shvl": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.3.tgz",
"integrity": "sha512-V7C6S9Hlol6SzOJPnQ7qzOVEWUQImt3BNmmzh40wObhla3XOYMe4gGiYzLrJd5TFa+cI2f9LKIRJTTKZSTbWgw=="
},
"node_modules/signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
......@@ -19144,11 +19188,22 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.0.tgz",
"integrity": "sha512-56VPujlHscP5q/e7Jlpqc40sja4vOhC4uJD1llBCWolVI8ND4+VzisDVkUMl+z5y0MpIImW6HjhNc+ZvuizgOw==",
"dev": true,
"peerDependencies": {
"vue": "^3.0.2"
}
},
"node_modules/vuex-persistedstate": {
"version": "4.0.0-beta.3",
"resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-4.0.0-beta.3.tgz",
"integrity": "sha512-T4IRD27qoUWh+8qr6T6zVp15xO7x/nPgnU13OD0C2uUwA7U9PhGozrj6lvVmMYDyRgc36J0msMXn3GvwHjkIhA==",
"dependencies": {
"deepmerge": "^4.2.2",
"shvl": "^2.0.2"
},
"peerDependencies": {
"vuex": "^3.0 || ^4.0.0-rc"
}
},
"node_modules/watchpack": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
......@@ -25388,6 +25443,11 @@
"randomfill": "^1.0.3"
}
},
"crypto-js": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
"integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q=="
},
"css-color-names": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
......@@ -26053,8 +26113,7 @@
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
"dev": true
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
},
"default-gateway": {
"version": "4.2.0",
......@@ -26352,6 +26411,12 @@
"is-obj": "^2.0.0"
}
},
"dotenv": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
"dev": true
},
"duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
......@@ -28311,6 +28376,11 @@
"micromatch": "^4.0.2"
}
},
"http-status-codes": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.1.4.tgz",
"integrity": "sha512-MZVIsLKGVOVE1KEnldppe6Ij+vmemMuApDfjhVSLzyYP+td0bREEYyAoIw9yFePoBXManCuBqmiNP5FqJS5Xkg=="
},
"https-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
......@@ -29386,6 +29456,11 @@
"yallist": "^3.0.2"
}
},
"lz-string": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
"integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY="
},
"magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
......@@ -34908,6 +34983,15 @@
"ajv-keywords": "^3.5.2"
}
},
"secure-ls": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/secure-ls/-/secure-ls-1.2.6.tgz",
"integrity": "sha512-g8vUSKl6elSfyAUHodybnNkuZW+mUYEOWj4SZIDg+xoQ1dq5ddktBoOFrtxQBUl88ZyAJOtGWQ1PRaOxkTAuZQ==",
"requires": {
"crypto-js": "^3.1.6",
"lz-string": "^1.4.4"
}
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
......@@ -35159,6 +35243,11 @@
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
"dev": true
},
"shvl": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.3.tgz",
"integrity": "sha512-V7C6S9Hlol6SzOJPnQ7qzOVEWUQImt3BNmmzh40wObhla3XOYMe4gGiYzLrJd5TFa+cI2f9LKIRJTTKZSTbWgw=="
},
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
......@@ -36832,9 +36921,17 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.0.tgz",
"integrity": "sha512-56VPujlHscP5q/e7Jlpqc40sja4vOhC4uJD1llBCWolVI8ND4+VzisDVkUMl+z5y0MpIImW6HjhNc+ZvuizgOw==",
"dev": true,
"requires": {}
},
"vuex-persistedstate": {
"version": "4.0.0-beta.3",
"resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-4.0.0-beta.3.tgz",
"integrity": "sha512-T4IRD27qoUWh+8qr6T6zVp15xO7x/nPgnU13OD0C2uUwA7U9PhGozrj6lvVmMYDyRgc36J0msMXn3GvwHjkIhA==",
"requires": {
"deepmerge": "^4.2.2",
"shvl": "^2.0.2"
}
},
"watchpack": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
......@@ -19,7 +19,7 @@ module.exports = configure(function (ctx) {
enabled: true,
files: './src/**/*.{ts,tsx,js,jsx,vue}',
},
}
},
},
// https://v2.quasar.dev/quasar-cli/prefetch-feature
......@@ -28,15 +28,10 @@ module.exports = configure(function (ctx) {
// app boot file (/src/boot)
// --> boot files are part of "main.js"
// https://v2.quasar.dev/quasar-cli/boot-files
boot: [
'i18n',
'axios',
],
boot: ['i18n', 'axios'],
// https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
css: [
'app.scss'
],
css: ['app.scss'],
// https://github.com/quasarframework/quasar/tree/dev/extras
extras: [
......@@ -74,16 +69,19 @@ module.exports = configure(function (ctx) {
// https://v2.quasar.dev/quasar-cli/handling-webpack
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpack (/* chain */) {
chainWebpack(/* chain */) {
//
},
env: {
api: 'test',
},
},
// Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer
devServer: {
https: false,
port: 8080,
open: true // opens browser window automatically
open: true, // opens browser window automatically
},
// https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework
......@@ -101,7 +99,7 @@ module.exports = configure(function (ctx) {
// directives: [],
// Quasar plugins
plugins: []
plugins: ['Notify'],
},
// animations: 'all', // --- includes all animations
......@@ -113,19 +111,19 @@ module.exports = configure(function (ctx) {
pwa: false,
// manualStoreHydration: true,
prodPort: 3000, // The default port that the production server should use
// (gets superseded if process.env.PORT is specified at runtime)
// (gets superseded if process.env.PORT is specified at runtime)
maxAge: 1000 * 60 * 60 * 24 * 30,
// Tell browser when a file from the server should expire from cache (in ms)
// Tell browser when a file from the server should expire from cache (in ms)
chainWebpackWebserver (/* chain */) {
chainWebpackWebserver(/* chain */) {
//
},
middlewares: [
ctx.prod ? 'compression' : '',
'render' // keep this as last one
]
'render', // keep this as last one
],
},
// https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa
......@@ -135,7 +133,7 @@ module.exports = configure(function (ctx) {
// for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts])
// if using workbox in InjectManifest mode
chainWebpackCustomSW (/* chain */) {
chainWebpackCustomSW(/* chain */) {
//
},
......@@ -151,30 +149,30 @@ module.exports = configure(function (ctx) {
{
src: 'icons/icon-128x128.png',
sizes: '128x128',
type: 'image/png'
type: 'image/png',
},
{
src: 'icons/icon-192x192.png',
sizes: '192x192',
type: 'image/png'
type: 'image/png',
},
{
src: 'icons/icon-256x256.png',
sizes: '256x256',
type: 'image/png'
type: 'image/png',
},
{
src: 'icons/icon-384x384.png',
sizes: '384x384',
type: 'image/png'
type: 'image/png',
},
{
src: 'icons/icon-512x512.png',
sizes: '512x512',
type: 'image/png'
}
]
}
type: 'image/png',
},
],
},
},
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova
......@@ -184,7 +182,7 @@ module.exports = configure(function (ctx) {
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor
capacitor: {
hideSplashscreen: true
hideSplashscreen: true,
},
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-electron-apps/configuring-electron
......@@ -193,13 +191,11 @@ module.exports = configure(function (ctx) {
packager: {
// https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
// OS X / Mac App Store
// appBundleId: '',
// appCategoryType: '',
// osxSign: '',
// protocol: 'myapp://path',
// Windows only
// win32metadata: { ... }
},
......@@ -207,20 +203,20 @@ module.exports = configure(function (ctx) {
builder: {
// https://www.electron.build/configuration/configuration
appId: 'quasar-web-base'
appId: 'quasar-web-base',
},
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpack (/* chain */) {
chainWebpack(/* chain */) {
// do something with the Electron main process Webpack cfg
// extendWebpackMain also available besides this chainWebpackMain
},
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpackPreload (/* chain */) {
chainWebpackPreload(/* chain */) {
// do something with the Electron main process Webpack cfg
// extendWebpackPreload also available besides this chainWebpackPreload
},
}
}
},
};
});
export const config = {
API_ENDPOINT: 'http://cms.vab.xteldev.com/api/',
API_RES_CODE: {
OK: {
code: 0,
},
TOKEN_INVALID: {
code: 1,
},
TOKEN_EXPIRES: {
code: 2,
},
},
};
import { boot } from 'quasar/wrappers';
import axios, { AxiosInstance } from 'axios';
import axios, {
AxiosError,
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
} from 'axios';
import { config } from 'src/assets/configurations';
import { StateInterface } from 'src/store';
import { Store } from 'vuex';
import { Notify } from 'quasar';
import { i18n } from './i18n';
import { StatusCodes } from 'http-status-codes';
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
......@@ -7,11 +18,74 @@ declare module '@vue/runtime-core' {
}
}
const api = axios.create({ baseURL: 'https://api.example.com' });
const api = axios.create({ baseURL: config.API_ENDPOINT });
export default boot(({ app }) => {
export type BaseResponseBody = {
error: {
code: number;
message: string;
};
data: unknown;
};
export default boot(({ app, store }) => {
// for use inside Vue files (Options API) through this.$axios and this.$api
const $store = store as Store<StateInterface>;
const onRequest = (config: AxiosRequestConfig) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
config.headers.Authorization = `Bearer ${
$store.state.authentication.token || ''
}`;
return config;
};
const onRequestError = (error: Error) => {
Notify.create({
type: 'negative',
message: i18n.global.t('requestErrorMessage'),
});
console.log('[REQUEST ERROR]: ', error);
return Promise.reject(error);
};
const onResponse = (res: AxiosResponse<BaseResponseBody>) => {
if (
res.data.error.code === config.API_RES_CODE.TOKEN_INVALID.code ||
res.data.error.code === config.API_RES_CODE.TOKEN_EXPIRES.code
) {
// ...
Notify.create({
type: 'warning',
message: i18n.global.t('tokenInvalidMessage'),
});
// ... Logout
}
return res;
};
const onResponseError = (error: Error | AxiosError) => {
if (error instanceof Error) {
Notify.create({
type: 'negative',
message: i18n.global.t('responseErrorMessage'),
});
} else {
const axiosError = error as AxiosError;
const response = axiosError.response as AxiosResponse<BaseResponseBody>;
if (response.status === StatusCodes.NOT_FOUND) {
// ...
}
}
console.log('[RESPONSE ERROR]: ', error);
return Promise.reject(error);
};
api.interceptors.request.use(onRequest, onRequestError);
api.interceptors.response.use(onResponse, onResponseError);
app.config.globalProperties.$axios = axios;
// ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form)
// so you won't necessarily have to import axios in each vue file
......
......@@ -4,7 +4,7 @@ import { createI18n } from 'vue-i18n';
import messages from 'src/i18n';
const i18n = createI18n({
locale: 'en-US',
locale: 'vi',
messages,
});
......
// This is just an example,
// so you can safely delete all default props below
import vi from '../vi';
export default {
failed: 'Action failed',
success: 'Action was successful'
...vi,
};
import enUS from './en-US';
import vi from './vi';
export default {
'en-US': enUS
'en-US': enUS,
vi,
};
// This is just an example,
// so you can safely delete all default props below
export default {
failed: 'Action failed',
success: 'Action was successful',
requestErrorMessage: 'Không thể kết nối đến server',
responseErrorMessage: '',
tokenInvalidMessage: 'Phiên đăng nhập hết hạn. Vui lòng đăng nhập lại',
};
......@@ -6,18 +6,24 @@
:todos="todos"
:meta="meta"
></example-component>
{{ config }}
</q-page>
</template>
<script lang="ts">
import { Todo, Meta } from '../components/models';
import ExampleComponent from '../components/CompositionComponent.vue';
import { defineComponent, ref } from 'vue';
import { defineComponent, ref, onMounted } from 'vue';
import { useStore } from '../store';
export default defineComponent({
name: 'PageIndex',
components: { ExampleComponent },
setup() {
const $store = useStore();
onMounted(() => {
$store.commit('authentication/setToken');
});
const todos = ref<Todo[]>([
{
id: 1,
......@@ -43,6 +49,7 @@ export default defineComponent({
const meta = ref<Meta>({
totalCount: 1200,
});
return { todos, meta };
},
});
......
import { ActionTree } from 'vuex';
import { StateInterface } from '../index';
import { AuthenticationState } from './state';
const actions: ActionTree<AuthenticationState, StateInterface> = {
someAction (/* context */) {
// your code
}
};
export default actions;
import { GetterTree } from 'vuex';
import { StateInterface } from '../index';
import { AuthenticationState } from './state';
const getters: GetterTree<AuthenticationState, StateInterface> = {
someGetter (/* context */) {
// your code
}
};
export default getters;
import { Module } from 'vuex';
import { StateInterface } from '../index';
import state, { AuthenticationState } from './state';
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
const exampleModule: Module<AuthenticationState, StateInterface> = {
namespaced: true,
actions,
getters,
mutations,
state
};
export default exampleModule;
import { MutationTree } from 'vuex';
import { AuthenticationState } from './state';
const mutation: MutationTree<AuthenticationState> = {
setToken(state) {
state.token = 'aksjhdkajshdk';
},
};
export default mutation;
export interface AuthenticationState {
token?: string
}
function state(): AuthenticationState {
return {
token: ''
};
}
export default state;
import { store } from 'quasar/wrappers'
import { InjectionKey } from 'vue'
import { store } from 'quasar/wrappers';
import { InjectionKey } from 'vue';
import {
createStore,
Store as VuexStore,
useStore as vuexUseStore,
} from 'vuex'
} from 'vuex';
// import example from './module-example'
// import { ExampleStateInterface } from './module-example/state';
import authentication from './authentication';
import { AuthenticationState } from './authentication/state';
import SecureLS from 'secure-ls';
import createPersistedState from 'vuex-persistedstate';
// eslint-disable-next-line
const ls = new SecureLS({ isCompression: true });
/*
* If not building with SSR mode, you can
......@@ -22,33 +26,50 @@ export interface StateInterface {
// Define your own store structure, using submodules if needed
// example: ExampleStateInterface;
// Declared as unknown to avoid linting issue. Best to strongly type as per the line above.
example: unknown
authentication: AuthenticationState;
}
// provide typings for `this.$store`
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$store: VuexStore<StateInterface>
$store: VuexStore<StateInterface>;
}
}
// provide typings for `useStore` helper
export const storeKey: InjectionKey<VuexStore<StateInterface>> = Symbol('vuex-key')
export const storeKey: InjectionKey<VuexStore<StateInterface>> = Symbol(
'vuex-key'
);
export default store(function (/* { ssrContext } */) {
const Store = createStore<StateInterface>({
modules: {
// example
authentication,
},
plugins: [
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
createPersistedState({
storage: {
// eslint-disable-next-line
getItem: (key: string) => ls.get(key),
// eslint-disable-next-line
setItem: (key: string, value: unknown) => ls.set(key, value),
// eslint-disable-next-line
removeItem: (key: string) => ls.remove(key),
},
}),
],
// enable strict mode (adds overhead!)
// for dev mode and --debug builds only
strict: !!process.env.DEBUGGING
})
strict: !!process.env.DEBUGGING,
});
return Store;
})
});
export function useStore() {
return vuexUseStore(storeKey)
}
\ No newline at end of file
return vuexUseStore(storeKey);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment