mirror of
https://git.hmsn.ink/coin/chart.git
synced 2026-03-19 15:55:03 +09:00
first
This commit is contained in:
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Vue 3 + TypeScript + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup).
|
||||||
8
coin.iml
Normal file
8
coin.iml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Vue + TS</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
14257
package-lock.json
generated
Normal file
14257
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
62
package.json
Normal file
62
package.json
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"name": "coin",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc -b && vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@cssninja/bulma": "^0.9.4",
|
||||||
|
"@cssninja/bulma-css-vars": "0.9.2",
|
||||||
|
"@fontsource/noto-sans-kr": "^5.2.5",
|
||||||
|
"@intlify/unplugin-vue-i18n": "^6.0.8",
|
||||||
|
"@unhead/addons": "^2.0.14",
|
||||||
|
"@unhead/vue": "^2.0.14",
|
||||||
|
"@vueuse/core": "10.9.0",
|
||||||
|
"@vueuse/router": "10.9.0",
|
||||||
|
"bulma": "npm:@cssninja/bulma@0.9.4",
|
||||||
|
"lightweight-charts": "^5.0.8",
|
||||||
|
"node-path": "^0.0.3",
|
||||||
|
"notyf": "3.10.0",
|
||||||
|
"pinia": "2.1.7",
|
||||||
|
"std-env": "^3.9.0",
|
||||||
|
"unplugin-vue-router": "^0.15.0",
|
||||||
|
"vite-plugin-pwa": "^1.0.3",
|
||||||
|
"vue": "^3.5.18",
|
||||||
|
"vue-i18n": "9.13.1",
|
||||||
|
"vue-router": "4.3.2",
|
||||||
|
"yarn": "^1.22.22"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
|
"@vue/tsconfig": "^0.7.0",
|
||||||
|
"@vueuse/integrations": "10.9.0",
|
||||||
|
"eslint": "8.57.0",
|
||||||
|
"eslint-plugin-frontmatter": "0.0.8",
|
||||||
|
"eslint-plugin-md": "1.0.19",
|
||||||
|
"eslint-plugin-sonarjs": "0.25.1",
|
||||||
|
"eslint-plugin-vue": "9.25.0",
|
||||||
|
"eslint-plugin-vuejs-accessibility": "2.3.0",
|
||||||
|
"postcss-html": "1.6.0",
|
||||||
|
"postcss-scss": "4.0.9",
|
||||||
|
"rollup-plugin-purgecss": "6.0.0",
|
||||||
|
"sass": "npm:sass-embedded@1.75.0",
|
||||||
|
"shiki": "1.4.0",
|
||||||
|
"stylelint": "16.5.0",
|
||||||
|
"stylelint-config-recommended-vue": "1.5.0",
|
||||||
|
"stylelint-config-standard": "36.0.0",
|
||||||
|
"stylelint-config-standard-scss": "13.1.0",
|
||||||
|
"stylelint-scss": "6.3.0",
|
||||||
|
"typescript": "~5.8.3",
|
||||||
|
"unified": "11.0.4",
|
||||||
|
"unplugin-auto-import": "0.17.5",
|
||||||
|
"unplugin-vue-components": "0.27.0",
|
||||||
|
"vite": "^7.1.2",
|
||||||
|
"vite-plugin-vue-devtools": "7.7.6",
|
||||||
|
"vue-component-meta": "2.0.16",
|
||||||
|
"vue-tsc": "^3.0.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
public/vite.svg
Normal file
1
public/vite.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
138
src/App.vue
Normal file
138
src/App.vue
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<script setup>
|
||||||
|
// This starter template is using Vue 3 <script setup> SFCs
|
||||||
|
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are example components in both API styles: Options API, and Composition API
|
||||||
|
*
|
||||||
|
* Select your preferred style from the imports below:
|
||||||
|
*/
|
||||||
|
import LWChart from './components/LWChart.vue';
|
||||||
|
// import LWChart from './components/options-api/LWChart.vue';
|
||||||
|
import candleData from '/@src/utils/data'
|
||||||
|
/**
|
||||||
|
* Generates sample data for the lightweight chart
|
||||||
|
* @param {Boolean} ohlc Whether generated dat should include open, high, low, and close values
|
||||||
|
* @returns {Array} sample data
|
||||||
|
*/
|
||||||
|
|
||||||
|
const chartOptions = ref({
|
||||||
|
layout: {
|
||||||
|
textColor: 'black',
|
||||||
|
background: { type: 'solid', color: 'white' },
|
||||||
|
},
|
||||||
|
height: 500
|
||||||
|
});
|
||||||
|
const data = ref(candleData);
|
||||||
|
const seriesOptions = ref({
|
||||||
|
upColor: '#26a69a',
|
||||||
|
downColor: '#ef5350',
|
||||||
|
borderVisible: false,
|
||||||
|
wickUpColor: '#26a69a',
|
||||||
|
wickDownColor: '#ef5350',
|
||||||
|
});
|
||||||
|
const chartType = ref('candlestick');
|
||||||
|
const lwChart = ref();
|
||||||
|
|
||||||
|
function randomShade() {
|
||||||
|
return Math.round(Math.random() * 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
const randomColor = (alpha = 1) => {
|
||||||
|
return `rgba(${randomShade()}, ${randomShade()}, ${randomShade()}, ${alpha})`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const colorsTypeMap = {
|
||||||
|
area: [
|
||||||
|
['topColor', 0.4],
|
||||||
|
['bottomColor', 0],
|
||||||
|
['lineColor', 1],
|
||||||
|
],
|
||||||
|
bar: [
|
||||||
|
['upColor', 1],
|
||||||
|
['downColor', 1],
|
||||||
|
],
|
||||||
|
baseline: [
|
||||||
|
['topFillColor1', 0.28],
|
||||||
|
['topFillColor2', 0.05],
|
||||||
|
['topLineColor', 1],
|
||||||
|
['bottomFillColor1', 0.28],
|
||||||
|
['bottomFillColor2', 0.05],
|
||||||
|
['bottomLineColor', 1],
|
||||||
|
],
|
||||||
|
candlestick: [
|
||||||
|
['upColor', 1],
|
||||||
|
['downColor', 1],
|
||||||
|
['borderUpColor', 1],
|
||||||
|
['borderDownColor', 1],
|
||||||
|
['wickUpColor', 1],
|
||||||
|
['wickDownColor', 1],
|
||||||
|
],
|
||||||
|
histogram: [['color', 1]],
|
||||||
|
line: [['color', 1]],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set a random colour for the series as an example of how
|
||||||
|
// to apply new options to series. A similar appraoch will work on the
|
||||||
|
// option properties.
|
||||||
|
const changeColors = () => {
|
||||||
|
const options = {};
|
||||||
|
const colorsToSet = colorsTypeMap[chartType.value];
|
||||||
|
colorsToSet.forEach((c) => {
|
||||||
|
options[c[0]] = randomColor(c[1]);
|
||||||
|
});
|
||||||
|
seriesOptions.value = options;
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeData = () => {
|
||||||
|
const candlestickTypeData = ['candlestick', 'bar'].includes(chartType.value);
|
||||||
|
const newData = generateSampleData(candlestickTypeData);
|
||||||
|
data.value = newData;
|
||||||
|
if (chartType.value === 'baseline') {
|
||||||
|
const average =
|
||||||
|
newData.reduce((s, c) => {
|
||||||
|
return s + c.value;
|
||||||
|
}, 0) / newData.length;
|
||||||
|
seriesOptions.value = { baseValue: { type: 'price', price: average } };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeType = () => {
|
||||||
|
const types = [
|
||||||
|
'line',
|
||||||
|
'area',
|
||||||
|
'baseline',
|
||||||
|
'histogram',
|
||||||
|
'candlestick',
|
||||||
|
'bar',
|
||||||
|
].filter((t) => t !== chartType.value);
|
||||||
|
const randIndex = Math.round(Math.random() * (types.length - 1));
|
||||||
|
chartType.value = types[randIndex];
|
||||||
|
changeData();
|
||||||
|
|
||||||
|
// call a method on the component.
|
||||||
|
lwChart.value.fitContent();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="chart-container">
|
||||||
|
<LWChart
|
||||||
|
:type="chartType"
|
||||||
|
:data="data"
|
||||||
|
:autosize="true"
|
||||||
|
:chart-options="chartOptions"
|
||||||
|
:series-options="seriesOptions"
|
||||||
|
ref="lwChart"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button type="button" @click="changeColors">Set Random Colors</button>
|
||||||
|
<button type="button" @click="changeType">Change Chart Type</button>
|
||||||
|
<button type="button" @click="changeData">Change Data</button>
|
||||||
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
.chart-container {
|
||||||
|
height: calc(100% - 3.2em);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1
src/assets/vue.svg
Normal file
1
src/assets/vue.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 496 B |
210
src/components/LWChart.vue
Normal file
210
src/components/LWChart.vue
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
onUnmounted,
|
||||||
|
watch,
|
||||||
|
defineExpose,
|
||||||
|
defineProps,
|
||||||
|
} from 'vue';
|
||||||
|
import {
|
||||||
|
createChart,
|
||||||
|
LineSeries,
|
||||||
|
AreaSeries,
|
||||||
|
BarSeries,
|
||||||
|
CandlestickSeries,
|
||||||
|
HistogramSeries,
|
||||||
|
BaselineSeries,
|
||||||
|
} from 'lightweight-charts';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'line',
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
autosize: {
|
||||||
|
default: true,
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
chartOptions: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
seriesOptions: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
timeScaleOptions: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
priceScaleOptions: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function getChartSeriesDefinition(type) {
|
||||||
|
switch (type.toLowerCase()) {
|
||||||
|
case 'line':
|
||||||
|
return LineSeries;
|
||||||
|
case 'area':
|
||||||
|
return AreaSeries;
|
||||||
|
case 'bar':
|
||||||
|
return BarSeries;
|
||||||
|
case 'candlestick':
|
||||||
|
return CandlestickSeries;
|
||||||
|
case 'histogram':
|
||||||
|
return HistogramSeries;
|
||||||
|
case 'baseline':
|
||||||
|
return BaselineSeries;
|
||||||
|
}
|
||||||
|
return LineSeries;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lightweight Charts™ instances are stored as normal JS variables
|
||||||
|
// If you need to use a ref then it is recommended that you use `shallowRef` instead
|
||||||
|
let series;
|
||||||
|
let chart;
|
||||||
|
|
||||||
|
const chartContainer = ref();
|
||||||
|
|
||||||
|
const fitContent = () => {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.timeScale().fitContent();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getChart = () => {
|
||||||
|
return chart;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ fitContent, getChart });
|
||||||
|
|
||||||
|
// Auto resizes the chart when the browser window is resized.
|
||||||
|
const resizeHandler = () => {
|
||||||
|
if (!chart || !chartContainer.value) return;
|
||||||
|
const dimensions = chartContainer.value.getBoundingClientRect();
|
||||||
|
chart.resize(dimensions.width, dimensions.height);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Creates the chart series and sets the data.
|
||||||
|
const addSeriesAndData = props => {
|
||||||
|
const seriesDefinition = getChartSeriesDefinition(props.type);
|
||||||
|
series = chart.addSeries(seriesDefinition, props.seriesOptions);
|
||||||
|
series.setData(props.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// Create the Lightweight Charts Instance using the container ref.
|
||||||
|
chart = createChart(chartContainer.value, props.chartOptions);
|
||||||
|
console.log(props)
|
||||||
|
addSeriesAndData(props);
|
||||||
|
|
||||||
|
if (props.priceScaleOptions) {
|
||||||
|
chart.priceScale().applyOptions(props.priceScaleOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.timeScaleOptions) {
|
||||||
|
chart.timeScale().applyOptions(props.timeScaleOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
chart.timeScale().fitContent();
|
||||||
|
|
||||||
|
if (props.autosize) {
|
||||||
|
window.addEventListener('resize', resizeHandler);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (chart) {
|
||||||
|
chart.remove();
|
||||||
|
chart = null;
|
||||||
|
}
|
||||||
|
if (series) {
|
||||||
|
series = null;
|
||||||
|
}
|
||||||
|
window.removeEventListener('resize', resizeHandler);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Watch for changes to any of the component properties.
|
||||||
|
|
||||||
|
* If an options property is changed then we will apply those options
|
||||||
|
* on top of any existing options previously set (since we are using the
|
||||||
|
* `applyOptions` method).
|
||||||
|
*
|
||||||
|
* If there is a change to the chart type, then the existing series is removed
|
||||||
|
* and the new series is created, and assigned the data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
() => props.autosize,
|
||||||
|
enabled => {
|
||||||
|
if (!enabled) {
|
||||||
|
window.removeEventListener('resize', resizeHandler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', resizeHandler);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.type,
|
||||||
|
newType => {
|
||||||
|
if (series && chart) {
|
||||||
|
chart.removeSeries(series);
|
||||||
|
}
|
||||||
|
addSeriesAndData(props);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.data,
|
||||||
|
newData => {
|
||||||
|
if (!series) return;
|
||||||
|
series.setData(newData);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.chartOptions,
|
||||||
|
newOptions => {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.applyOptions(newOptions);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.seriesOptions,
|
||||||
|
newOptions => {
|
||||||
|
if (!series) return;
|
||||||
|
series.applyOptions(newOptions);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.priceScaleOptions,
|
||||||
|
newOptions => {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.priceScale().applyOptions(newOptions);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.timeScaleOptions,
|
||||||
|
newOptions => {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.timeScale().applyOptions(newOptions);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="lw-chart" ref="chartContainer"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.lw-chart {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
156
src/components/LWChartOption.vue
Normal file
156
src/components/LWChartOption.vue
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<script>
|
||||||
|
import { createChart } from 'lightweight-charts';
|
||||||
|
|
||||||
|
// Lightweight Chart instances are stored as normal JS variables
|
||||||
|
// If you need to use a ref then it is recommended that you use `shallowRef` instead
|
||||||
|
let series;
|
||||||
|
let chart;
|
||||||
|
|
||||||
|
// Function to get the correct series constructor name for current series type.
|
||||||
|
function getChartSeriesConstructorName(type) {
|
||||||
|
return `add${type.charAt(0).toUpperCase() + type.slice(1)}Series`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates the chart series and sets the data.
|
||||||
|
const addSeriesAndData = (type, seriesOptions, data) => {
|
||||||
|
const seriesConstructor = getChartSeriesConstructorName(type);
|
||||||
|
series = chart[seriesConstructor](seriesOptions);
|
||||||
|
series.setData(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Auto resizes the chart when the browser window is resized.
|
||||||
|
const resizeHandler = (container) => {
|
||||||
|
if (!chart || !container) return;
|
||||||
|
const dimensions = container.getBoundingClientRect();
|
||||||
|
chart.resize(dimensions.width, dimensions.height);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'line',
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
autosize: {
|
||||||
|
default: true,
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
chartOptions: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
seriesOptions: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
timeScaleOptions: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
priceScaleOptions: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// Create the Lightweight Charts Instance using the container ref.
|
||||||
|
chart = createChart(this.$refs.chartContainer, this.chartOptions);
|
||||||
|
addSeriesAndData(this.type, this.seriesOptions, this.data);
|
||||||
|
|
||||||
|
if (this.priceScaleOptions) {
|
||||||
|
chart.priceScale().applyOptions(this.priceScaleOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.timeScaleOptions) {
|
||||||
|
chart.timeScale().applyOptions(this.timeScaleOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
chart.timeScale().fitContent();
|
||||||
|
|
||||||
|
if (this.autosize) {
|
||||||
|
window.addEventListener('resize', () =>
|
||||||
|
resizeHandler(this.$refs.chartContainer)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unmounted() {
|
||||||
|
if (chart) {
|
||||||
|
chart.remove();
|
||||||
|
chart = null;
|
||||||
|
}
|
||||||
|
if (series) {
|
||||||
|
series = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
* Watch for changes to any of the component properties.
|
||||||
|
*
|
||||||
|
* If an options property is changed then we will apply those options
|
||||||
|
* on top of any existing options previously set (since we are using the
|
||||||
|
* `applyOptions` method).
|
||||||
|
*
|
||||||
|
* If there is a change to the chart type, then the existing series is removed
|
||||||
|
* and the new series is created, and assigned the data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
watch: {
|
||||||
|
autosize(enabled) {
|
||||||
|
if (!enabled) {
|
||||||
|
window.removeEventListener('resize', () =>
|
||||||
|
resizeHandler(this.$refs.chartContainer)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', () =>
|
||||||
|
resizeHandler(this.$refs.chartContainer)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
type(newType) {
|
||||||
|
if (series && chart) {
|
||||||
|
chart.removeSeries(series);
|
||||||
|
}
|
||||||
|
addSeriesAndData(this.type, this.seriesOptions, this.data);
|
||||||
|
},
|
||||||
|
data(newData) {
|
||||||
|
if (!series) return;
|
||||||
|
series.setData(newData);
|
||||||
|
},
|
||||||
|
chartOptions(newOptions) {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.applyOptions(newOptions);
|
||||||
|
},
|
||||||
|
seriesOptions(newOptions) {
|
||||||
|
if (!series) return;
|
||||||
|
series.applyOptions(newOptions);
|
||||||
|
},
|
||||||
|
priceScaleOptions(newOptions) {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.priceScale().applyOptions(newOptions);
|
||||||
|
},
|
||||||
|
timeScaleOptions(newOptions) {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.timeScale().applyOptions(newOptions);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fitContent() {
|
||||||
|
if (!chart) return;
|
||||||
|
chart.timeScale().fitContent();
|
||||||
|
},
|
||||||
|
getChart() {
|
||||||
|
return chart;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expose: ['fitContent', 'getChart'],
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="lw-chart" ref="chartContainer"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.lw-chart {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
5
src/main.ts
Normal file
5
src/main.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import './style.css'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
createApp(App).mount('#app')
|
||||||
79
src/style.css
Normal file
79
src/style.css
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
:root {
|
||||||
|
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
color-scheme: light dark;
|
||||||
|
color: rgba(255, 255, 255, 0.87);
|
||||||
|
background-color: #242424;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #646cff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #535bf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3.2em;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 0.6em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-family: inherit;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.25s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
border-color: #646cff;
|
||||||
|
}
|
||||||
|
button:focus,
|
||||||
|
button:focus-visible {
|
||||||
|
outline: 4px auto -webkit-focus-ring-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
max-width: 1280px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
color: #213547;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #747bff;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
}
|
||||||
712
src/utils/data.ts
Normal file
712
src/utils/data.ts
Normal file
@@ -0,0 +1,712 @@
|
|||||||
|
|
||||||
|
const candleData = [
|
||||||
|
{
|
||||||
|
close: 108.9974612905403,
|
||||||
|
high: 121.20998259466148,
|
||||||
|
low: 96.65376292551082,
|
||||||
|
open: 104.5614412226746,
|
||||||
|
time: { year: 2018, month: 9, day: 22 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 110.46815600023501,
|
||||||
|
high: 111.3650273696516,
|
||||||
|
low: 82.65543461471314,
|
||||||
|
open: 110.16538466099634,
|
||||||
|
time: { year: 2018, month: 9, day: 23 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 90.62131977740425,
|
||||||
|
high: 109.19838270252615,
|
||||||
|
low: 82.30106956144076,
|
||||||
|
open: 105.03104735287424,
|
||||||
|
time: { year: 2018, month: 9, day: 24 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 96.80120024431532,
|
||||||
|
high: 101.92074283374939,
|
||||||
|
low: 89.25819769856513,
|
||||||
|
open: 89.25819769856513,
|
||||||
|
time: { year: 2018, month: 9, day: 25 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 94.87113928076117,
|
||||||
|
high: 104.12503365679314,
|
||||||
|
low: 85.42405005240111,
|
||||||
|
open: 104.12503365679314,
|
||||||
|
time: { year: 2018, month: 9, day: 26 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 100.76494087674855,
|
||||||
|
high: 102.60508417239113,
|
||||||
|
low: 80.76268547064865,
|
||||||
|
open: 92.93299948659636,
|
||||||
|
time: { year: 2018, month: 9, day: 27 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 101.45855928883597,
|
||||||
|
high: 110.26727325817173,
|
||||||
|
low: 91.10348900896837,
|
||||||
|
open: 93.4362185148034,
|
||||||
|
time: { year: 2018, month: 9, day: 28 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 91.68871815146144,
|
||||||
|
high: 103.73263644407702,
|
||||||
|
low: 73.5329263610334,
|
||||||
|
open: 92.96467883926464,
|
||||||
|
time: { year: 2018, month: 9, day: 29 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 89.39633140354033,
|
||||||
|
high: 101.06569518834237,
|
||||||
|
low: 81.71149885084162,
|
||||||
|
open: 83.08248758612376,
|
||||||
|
time: { year: 2018, month: 9, day: 30 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 93.09498513675378,
|
||||||
|
high: 93.09498513675378,
|
||||||
|
low: 76.81138276012628,
|
||||||
|
open: 91.97280452613565,
|
||||||
|
time: { year: 2018, month: 10, day: 1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 89.26733004009083,
|
||||||
|
high: 89.26733004009083,
|
||||||
|
low: 76.27851645958225,
|
||||||
|
open: 85.83860311023625,
|
||||||
|
time: { year: 2018, month: 10, day: 2 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 89.66035763006947,
|
||||||
|
high: 89.66035763006947,
|
||||||
|
low: 67.63677527399729,
|
||||||
|
open: 77.79584976144585,
|
||||||
|
time: { year: 2018, month: 10, day: 3 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 89.59687813884807,
|
||||||
|
high: 97.05916949817754,
|
||||||
|
low: 72.9823390058379,
|
||||||
|
open: 77.37388423995716,
|
||||||
|
time: { year: 2018, month: 10, day: 4 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 83.6425403120788,
|
||||||
|
high: 91.72593377862522,
|
||||||
|
low: 65.27208271740422,
|
||||||
|
open: 85.92711686401718,
|
||||||
|
time: { year: 2018, month: 10, day: 5 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 82.99053929200655,
|
||||||
|
high: 93.4482645370556,
|
||||||
|
low: 65.98920655616067,
|
||||||
|
open: 71.8940788814462,
|
||||||
|
time: { year: 2018, month: 10, day: 6 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 73.09595957510754,
|
||||||
|
high: 86.65935598412881,
|
||||||
|
low: 62.710852488609326,
|
||||||
|
open: 80.78945254092527,
|
||||||
|
time: { year: 2018, month: 10, day: 7 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 80.12127692112905,
|
||||||
|
high: 87.49034842093855,
|
||||||
|
low: 60.09987438133361,
|
||||||
|
open: 70.2408873110499,
|
||||||
|
time: { year: 2018, month: 10, day: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 77.60439116240829,
|
||||||
|
high: 83.20908153481327,
|
||||||
|
low: 68.56836128158209,
|
||||||
|
open: 75.83440719565763,
|
||||||
|
time: { year: 2018, month: 10, day: 9 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 73.8952889203428,
|
||||||
|
high: 81.89987377779327,
|
||||||
|
low: 57.8891283348631,
|
||||||
|
open: 66.51904017615065,
|
||||||
|
time: { year: 2018, month: 10, day: 10 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 75.08452506029613,
|
||||||
|
high: 75.08452506029613,
|
||||||
|
low: 59.208194031968155,
|
||||||
|
open: 72.14475369395771,
|
||||||
|
time: { year: 2018, month: 10, day: 11 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 73.08898607472305,
|
||||||
|
high: 73.08898607472305,
|
||||||
|
low: 63.05632280826725,
|
||||||
|
open: 66.93050765469924,
|
||||||
|
time: { year: 2018, month: 10, day: 12 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 58.993371469509704,
|
||||||
|
high: 73.08872095153116,
|
||||||
|
low: 53.52204433018574,
|
||||||
|
open: 66.12840939191403,
|
||||||
|
time: { year: 2018, month: 10, day: 13 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 57.150755012485,
|
||||||
|
high: 74.57414896810235,
|
||||||
|
low: 52.6552427480398,
|
||||||
|
open: 68.50876667562338,
|
||||||
|
time: { year: 2018, month: 10, day: 14 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 58.03147289822832,
|
||||||
|
high: 69.62445357159157,
|
||||||
|
low: 53.8260018823565,
|
||||||
|
open: 61.62298899368165,
|
||||||
|
time: { year: 2018, month: 10, day: 15 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 60.6852855399041,
|
||||||
|
high: 69.02095441024431,
|
||||||
|
low: 54.00939224622043,
|
||||||
|
open: 64.81901552322648,
|
||||||
|
time: { year: 2018, month: 10, day: 16 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 57.508820449565285,
|
||||||
|
high: 63.82926565242872,
|
||||||
|
low: 54.07370975509682,
|
||||||
|
open: 54.07370975509682,
|
||||||
|
time: { year: 2018, month: 10, day: 17 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 51.60796818909221,
|
||||||
|
high: 64.88712939579875,
|
||||||
|
low: 51.60796818909221,
|
||||||
|
open: 53.489226476218434,
|
||||||
|
time: { year: 2018, month: 10, day: 18 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 55.139520748382864,
|
||||||
|
high: 59.161320710177925,
|
||||||
|
low: 52.228139922762765,
|
||||||
|
open: 52.228139922762765,
|
||||||
|
time: { year: 2018, month: 10, day: 19 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 47.47868992247237,
|
||||||
|
high: 58.0836625917653,
|
||||||
|
low: 46.43213518526832,
|
||||||
|
open: 47.59258635788406,
|
||||||
|
time: { year: 2018, month: 10, day: 20 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 47.22596723150508,
|
||||||
|
high: 51.55468175560989,
|
||||||
|
low: 45.22654435521185,
|
||||||
|
open: 47.452459556200054,
|
||||||
|
time: { year: 2018, month: 10, day: 21 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 53.39724151191295,
|
||||||
|
high: 58.256006746786035,
|
||||||
|
low: 46.40105667413804,
|
||||||
|
open: 53.41548527476272,
|
||||||
|
time: { year: 2018, month: 10, day: 22 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 45.015877277800854,
|
||||||
|
high: 51.2955426978105,
|
||||||
|
low: 40.26534748806228,
|
||||||
|
open: 43.90158660063875,
|
||||||
|
time: { year: 2018, month: 10, day: 23 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 49.307312373439665,
|
||||||
|
high: 49.93643636637581,
|
||||||
|
low: 43.20705757075934,
|
||||||
|
open: 45.672934511555795,
|
||||||
|
time: { year: 2018, month: 10, day: 24 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 45.15418019295631,
|
||||||
|
high: 48.59676744409583,
|
||||||
|
low: 37.628047445918504,
|
||||||
|
open: 40.33862825788268,
|
||||||
|
time: { year: 2018, month: 10, day: 25 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 43.2972018283068,
|
||||||
|
high: 43.2972018283068,
|
||||||
|
low: 36.335943004352245,
|
||||||
|
open: 42.605991542720965,
|
||||||
|
time: { year: 2018, month: 10, day: 26 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 39.1153643552137,
|
||||||
|
high: 44.311406627923844,
|
||||||
|
low: 35.31457011784855,
|
||||||
|
open: 42.00000202357808,
|
||||||
|
time: { year: 2018, month: 10, day: 27 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 36.06960076896885,
|
||||||
|
high: 42.89041111567749,
|
||||||
|
low: 33.58326637182405,
|
||||||
|
open: 37.40942817102858,
|
||||||
|
time: { year: 2018, month: 10, day: 28 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 35.8981036950969,
|
||||||
|
high: 42.19793419602979,
|
||||||
|
low: 33.62190962880232,
|
||||||
|
open: 36.87246325249825,
|
||||||
|
time: { year: 2018, month: 10, day: 29 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 31.378205119641457,
|
||||||
|
high: 37.33501102832602,
|
||||||
|
low: 31.30137162225214,
|
||||||
|
open: 35.651275660713694,
|
||||||
|
time: { year: 2018, month: 10, day: 30 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 33.574536057730576,
|
||||||
|
high: 37.30152570719593,
|
||||||
|
low: 27.369689193426243,
|
||||||
|
open: 34.330180925654936,
|
||||||
|
time: { year: 2018, month: 10, day: 31 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 28.91735096504839,
|
||||||
|
high: 32.62196350117741,
|
||||||
|
low: 27.072564759401843,
|
||||||
|
open: 29.398552328599372,
|
||||||
|
time: { year: 2018, month: 11, day: 1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 28.44143154172122,
|
||||||
|
high: 31.042019861166594,
|
||||||
|
low: 23.383320830495375,
|
||||||
|
open: 27.275885037308072,
|
||||||
|
time: { year: 2018, month: 11, day: 2 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 25.92162714418916,
|
||||||
|
high: 30.57604443170622,
|
||||||
|
low: 25.418671641150752,
|
||||||
|
open: 26.775196275924657,
|
||||||
|
time: { year: 2018, month: 11, day: 3 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 26.376994016637433,
|
||||||
|
high: 28.198647836523744,
|
||||||
|
low: 21.492969733673334,
|
||||||
|
open: 26.27980943059139,
|
||||||
|
time: { year: 2018, month: 11, day: 4 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 28.60834088674494,
|
||||||
|
high: 28.60834088674494,
|
||||||
|
low: 21.89002840571941,
|
||||||
|
open: 25.376464895884993,
|
||||||
|
time: { year: 2018, month: 11, day: 5 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 31.103861067101136,
|
||||||
|
high: 31.103861067101136,
|
||||||
|
low: 24.39227668420513,
|
||||||
|
open: 28.994785427089838,
|
||||||
|
time: { year: 2018, month: 11, day: 6 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 28.6308138310307,
|
||||||
|
high: 35.430817482769164,
|
||||||
|
low: 24.069515410358232,
|
||||||
|
open: 27.109407394069084,
|
||||||
|
time: { year: 2018, month: 11, day: 7 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 29.468889521733466,
|
||||||
|
high: 37.54082586961352,
|
||||||
|
low: 27.90833873315644,
|
||||||
|
open: 33.16901271715577,
|
||||||
|
time: { year: 2018, month: 11, day: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 35.887823124204296,
|
||||||
|
high: 39.21804237580939,
|
||||||
|
low: 30.951078044055627,
|
||||||
|
open: 30.951078044055627,
|
||||||
|
time: { year: 2018, month: 11, day: 9 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 34.361137347097575,
|
||||||
|
high: 35.27083445807796,
|
||||||
|
low: 27.825889562160082,
|
||||||
|
open: 34.86040182980157,
|
||||||
|
time: { year: 2018, month: 11, day: 10 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 36.61336645243868,
|
||||||
|
high: 40.31460537175622,
|
||||||
|
low: 33.96383400053921,
|
||||||
|
open: 39.70037560142739,
|
||||||
|
time: { year: 2018, month: 11, day: 11 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 41.321693986803055,
|
||||||
|
high: 44.45481986667003,
|
||||||
|
low: 35.67563772228475,
|
||||||
|
open: 38.67059795413642,
|
||||||
|
time: { year: 2018, month: 11, day: 12 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 40.15038854039306,
|
||||||
|
high: 41.50912000191902,
|
||||||
|
low: 32.610637769394444,
|
||||||
|
open: 41.50912000191902,
|
||||||
|
time: { year: 2018, month: 11, day: 13 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 44.092601065208015,
|
||||||
|
high: 44.092601065208015,
|
||||||
|
low: 37.778306506100726,
|
||||||
|
open: 38.99045898154136,
|
||||||
|
time: { year: 2018, month: 11, day: 14 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 41.42426637839382,
|
||||||
|
high: 44.72189614841937,
|
||||||
|
low: 41.42426637839382,
|
||||||
|
open: 44.72189614841937,
|
||||||
|
time: { year: 2018, month: 11, day: 15 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 41.19513795258408,
|
||||||
|
high: 49.08084695291049,
|
||||||
|
low: 36.24282165100056,
|
||||||
|
open: 44.909248500660254,
|
||||||
|
time: { year: 2018, month: 11, day: 16 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 44.24935708161703,
|
||||||
|
high: 53.028535501565486,
|
||||||
|
low: 40.32056743060158,
|
||||||
|
open: 46.198546801109984,
|
||||||
|
time: { year: 2018, month: 11, day: 17 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 43.18555863372182,
|
||||||
|
high: 52.34250206788521,
|
||||||
|
low: 43.18555863372182,
|
||||||
|
open: 49.58135271619679,
|
||||||
|
time: { year: 2018, month: 11, day: 18 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 50.8568887039091,
|
||||||
|
high: 52.60441957102357,
|
||||||
|
low: 39.917719271944364,
|
||||||
|
open: 48.197532365645806,
|
||||||
|
time: { year: 2018, month: 11, day: 19 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 48.79128595974164,
|
||||||
|
high: 52.45087789296739,
|
||||||
|
low: 46.80633073487828,
|
||||||
|
open: 52.45087789296739,
|
||||||
|
time: { year: 2018, month: 11, day: 20 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 46.97300046781947,
|
||||||
|
high: 55.80689868049132,
|
||||||
|
low: 46.97300046781947,
|
||||||
|
open: 55.80689868049132,
|
||||||
|
time: { year: 2018, month: 11, day: 21 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 55.58129861112469,
|
||||||
|
high: 55.58129861112469,
|
||||||
|
low: 49.087279242343996,
|
||||||
|
open: 53.16719476594961,
|
||||||
|
time: { year: 2018, month: 11, day: 22 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 50.058979311730226,
|
||||||
|
high: 62.55333249171461,
|
||||||
|
low: 50.058979311730226,
|
||||||
|
open: 52.628489607588826,
|
||||||
|
time: { year: 2018, month: 11, day: 23 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 51.193155229085995,
|
||||||
|
high: 59.08949991997865,
|
||||||
|
low: 51.193155229085995,
|
||||||
|
open: 55.352594157474755,
|
||||||
|
time: { year: 2018, month: 11, day: 24 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 60.099338327208436,
|
||||||
|
high: 66.93510126958154,
|
||||||
|
low: 55.27299867222781,
|
||||||
|
open: 61.05897620044226,
|
||||||
|
time: { year: 2018, month: 11, day: 25 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 58.3802630890727,
|
||||||
|
high: 71.50922937699602,
|
||||||
|
low: 50.95210438359451,
|
||||||
|
open: 62.4679688326532,
|
||||||
|
time: { year: 2018, month: 11, day: 26 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 57.875350873413225,
|
||||||
|
high: 65.59903214448208,
|
||||||
|
low: 57.875350873413225,
|
||||||
|
open: 62.747405667247016,
|
||||||
|
time: { year: 2018, month: 11, day: 27 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 61.231150731698605,
|
||||||
|
high: 66.3829902228434,
|
||||||
|
low: 61.231150731698605,
|
||||||
|
open: 65.01028486919516,
|
||||||
|
time: { year: 2018, month: 11, day: 28 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 64.9698540874806,
|
||||||
|
high: 77.09783903299783,
|
||||||
|
low: 58.455031795628194,
|
||||||
|
open: 58.455031795628194,
|
||||||
|
time: { year: 2018, month: 11, day: 29 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 72.40978471883417,
|
||||||
|
high: 72.40978471883417,
|
||||||
|
low: 53.05804901549206,
|
||||||
|
open: 65.907298021202,
|
||||||
|
time: { year: 2018, month: 11, day: 30 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 74.60745731538934,
|
||||||
|
high: 78.33742117000789,
|
||||||
|
low: 54.42067144918077,
|
||||||
|
open: 73.20930147914103,
|
||||||
|
time: { year: 2018, month: 12, day: 1 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 64.10866184869924,
|
||||||
|
high: 76.14506447001202,
|
||||||
|
low: 61.5224432669736,
|
||||||
|
open: 69.33984127682314,
|
||||||
|
time: { year: 2018, month: 12, day: 2 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 65.92038759928786,
|
||||||
|
high: 76.98479070362022,
|
||||||
|
low: 65.92038759928786,
|
||||||
|
open: 69.32298264631615,
|
||||||
|
time: { year: 2018, month: 12, day: 3 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 68.23682161095334,
|
||||||
|
high: 77.6723729460968,
|
||||||
|
low: 68.23682161095334,
|
||||||
|
open: 74.39471534484744,
|
||||||
|
time: { year: 2018, month: 12, day: 4 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 67.45035792565862,
|
||||||
|
high: 83.53728553118547,
|
||||||
|
low: 67.45035792565862,
|
||||||
|
open: 74.79418570077237,
|
||||||
|
time: { year: 2018, month: 12, day: 5 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 79.26722967320323,
|
||||||
|
high: 79.26722967320323,
|
||||||
|
low: 68.40654829383521,
|
||||||
|
open: 68.40654829383521,
|
||||||
|
time: { year: 2018, month: 12, day: 6 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 74.95305464030587,
|
||||||
|
high: 81.65884414224071,
|
||||||
|
low: 64.08761481290135,
|
||||||
|
open: 81.65884414224071,
|
||||||
|
time: { year: 2018, month: 12, day: 7 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 86.30802154315482,
|
||||||
|
high: 91.21953112925642,
|
||||||
|
low: 65.46112304993535,
|
||||||
|
open: 77.82514647663533,
|
||||||
|
time: { year: 2018, month: 12, day: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 82.67218208289492,
|
||||||
|
high: 92.45833377442081,
|
||||||
|
low: 76.80728739647081,
|
||||||
|
open: 87.18916937056241,
|
||||||
|
time: { year: 2018, month: 12, day: 9 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 73.86125805398967,
|
||||||
|
high: 83.68952750914036,
|
||||||
|
low: 73.86125805398967,
|
||||||
|
open: 75.76119064173785,
|
||||||
|
time: { year: 2018, month: 12, day: 10 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 79.00109311074502,
|
||||||
|
high: 88.74271558831151,
|
||||||
|
low: 69.00900811612337,
|
||||||
|
open: 88.74271558831151,
|
||||||
|
time: { year: 2018, month: 12, day: 11 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 80.98779620162513,
|
||||||
|
high: 97.07429720104427,
|
||||||
|
low: 73.76970378608283,
|
||||||
|
open: 88.57288529720472,
|
||||||
|
time: { year: 2018, month: 12, day: 12 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 87.83619759370346,
|
||||||
|
high: 91.29759438607132,
|
||||||
|
low: 74.00740214639268,
|
||||||
|
open: 87.51853658661781,
|
||||||
|
time: { year: 2018, month: 12, day: 13 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 87.50134898892377,
|
||||||
|
high: 102.95635188637507,
|
||||||
|
low: 81.0513723219724,
|
||||||
|
open: 94.74009794290814,
|
||||||
|
time: { year: 2018, month: 12, day: 14 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 92.40159548029843,
|
||||||
|
high: 103.24363067710844,
|
||||||
|
low: 75.44605394394573,
|
||||||
|
open: 95.99903495559444,
|
||||||
|
time: { year: 2018, month: 12, day: 15 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 87.43619322092951,
|
||||||
|
high: 99.39349139000474,
|
||||||
|
low: 80.24624983473528,
|
||||||
|
open: 99.39349139000474,
|
||||||
|
time: { year: 2018, month: 12, day: 16 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 84.42724177432086,
|
||||||
|
high: 95.57485075893881,
|
||||||
|
low: 84.42724177432086,
|
||||||
|
open: 90.71070399095831,
|
||||||
|
time: { year: 2018, month: 12, day: 17 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 96.04408990868804,
|
||||||
|
high: 101.02158248010466,
|
||||||
|
low: 94.38544669520195,
|
||||||
|
open: 101.02158248010466,
|
||||||
|
time: { year: 2018, month: 12, day: 18 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 97.2120815653703,
|
||||||
|
high: 103.35830035963959,
|
||||||
|
low: 78.72594316029567,
|
||||||
|
open: 86.98009038330306,
|
||||||
|
time: { year: 2018, month: 12, day: 19 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 105.23366706522204,
|
||||||
|
high: 106.56174456393981,
|
||||||
|
low: 94.6658899187065,
|
||||||
|
open: 106.56174456393981,
|
||||||
|
time: { year: 2018, month: 12, day: 20 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 89.53750874231946,
|
||||||
|
high: 112.27917367188074,
|
||||||
|
low: 87.13586952228918,
|
||||||
|
open: 96.0857985693989,
|
||||||
|
time: { year: 2018, month: 12, day: 21 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 88.55787263435407,
|
||||||
|
high: 112.62138454627025,
|
||||||
|
low: 80.42783344898223,
|
||||||
|
open: 88.34340019789849,
|
||||||
|
time: { year: 2018, month: 12, day: 22 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 86.00639650371167,
|
||||||
|
high: 110.94532193307279,
|
||||||
|
low: 74.78703575498496,
|
||||||
|
open: 92.4275741143068,
|
||||||
|
time: { year: 2018, month: 12, day: 23 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 90.45119640254379,
|
||||||
|
high: 92.51500970997435,
|
||||||
|
low: 82.69475430846728,
|
||||||
|
open: 86.21662699549296,
|
||||||
|
time: { year: 2018, month: 12, day: 24 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 93.38124264891343,
|
||||||
|
high: 93.38124264891343,
|
||||||
|
low: 84.5674956907938,
|
||||||
|
open: 87.54923273867136,
|
||||||
|
time: { year: 2018, month: 12, day: 25 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 87.88725775527871,
|
||||||
|
high: 90.14253631595105,
|
||||||
|
low: 77.28638555494503,
|
||||||
|
open: 83.93199044032968,
|
||||||
|
time: { year: 2018, month: 12, day: 26 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 71.77940077333062,
|
||||||
|
high: 89.25710176370582,
|
||||||
|
low: 67.74278646676306,
|
||||||
|
open: 78.5346198695072,
|
||||||
|
time: { year: 2018, month: 12, day: 27 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 72.08757207606054,
|
||||||
|
high: 79.36518615067514,
|
||||||
|
low: 69.18787486704672,
|
||||||
|
open: 69.18787486704672,
|
||||||
|
time: { year: 2018, month: 12, day: 28 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 73.87977927793119,
|
||||||
|
high: 77.62891475860795,
|
||||||
|
low: 70.42293039125319,
|
||||||
|
open: 70.42293039125319,
|
||||||
|
time: { year: 2018, month: 12, day: 29 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 74.86330345366132,
|
||||||
|
high: 75.88473282167168,
|
||||||
|
low: 62.89549355427313,
|
||||||
|
open: 74.86554252962132,
|
||||||
|
time: { year: 2018, month: 12, day: 30 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
close: 71.00787215611817,
|
||||||
|
high: 71.00787215611817,
|
||||||
|
low: 57.29681995441558,
|
||||||
|
open: 60.04464694823929,
|
||||||
|
time: { year: 2018, month: 12, day: 31 },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default candleData
|
||||||
1
src/vite-env.d.ts
vendored
Normal file
1
src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
15
tsconfig.app.json
Normal file
15
tsconfig.app.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||||
|
}
|
||||||
7
tsconfig.json
Normal file
7
tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{ "path": "./tsconfig.node.json" }
|
||||||
|
]
|
||||||
|
}
|
||||||
25
tsconfig.node.json
Normal file
25
tsconfig.node.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"target": "ES2023",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
18
types/components.d.ts
vendored
Normal file
18
types/components.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
export {}
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
CoinChart: typeof import('./../src/components/CoinChart.vue')['default']
|
||||||
|
HelloWorld: typeof import('./../src/components/HelloWorld.vue')['default']
|
||||||
|
LwChart: typeof import('./../src/components/lw-chart.vue')['default']
|
||||||
|
LWChart: typeof import('./../src/components/LWChart.vue')['default']
|
||||||
|
LWChartOption: typeof import('./../src/components/LWChartOption.vue')['default']
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
}
|
||||||
|
}
|
||||||
304
types/imports.d.ts
vendored
Normal file
304
types/imports.d.ts
vendored
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
// Generated by unplugin-auto-import
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
|
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
|
||||||
|
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
|
||||||
|
const computed: typeof import('vue')['computed']
|
||||||
|
const computedAsync: typeof import('@vueuse/core')['computedAsync']
|
||||||
|
const computedEager: typeof import('@vueuse/core')['computedEager']
|
||||||
|
const computedInject: typeof import('@vueuse/core')['computedInject']
|
||||||
|
const computedWithControl: typeof import('@vueuse/core')['computedWithControl']
|
||||||
|
const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
|
||||||
|
const controlledRef: typeof import('@vueuse/core')['controlledRef']
|
||||||
|
const createApp: typeof import('vue')['createApp']
|
||||||
|
const createEventHook: typeof import('@vueuse/core')['createEventHook']
|
||||||
|
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
|
||||||
|
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
|
||||||
|
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
|
||||||
|
const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate']
|
||||||
|
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
|
||||||
|
const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise']
|
||||||
|
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
|
||||||
|
const customRef: typeof import('vue')['customRef']
|
||||||
|
const data: typeof import('../src/utils/data')['default']
|
||||||
|
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
|
||||||
|
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
|
||||||
|
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||||
|
const defineComponent: typeof import('vue')['defineComponent']
|
||||||
|
const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
|
||||||
|
const effectScope: typeof import('vue')['effectScope']
|
||||||
|
const extendRef: typeof import('@vueuse/core')['extendRef']
|
||||||
|
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||||
|
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||||
|
const h: typeof import('vue')['h']
|
||||||
|
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
|
||||||
|
const inject: typeof import('vue')['inject']
|
||||||
|
const injectHead: typeof import('@unhead/vue')['injectHead']
|
||||||
|
const injectLocal: typeof import('@vueuse/core')['injectLocal']
|
||||||
|
const isDefined: typeof import('@vueuse/core')['isDefined']
|
||||||
|
const isProxy: typeof import('vue')['isProxy']
|
||||||
|
const isReactive: typeof import('vue')['isReactive']
|
||||||
|
const isReadonly: typeof import('vue')['isReadonly']
|
||||||
|
const isRef: typeof import('vue')['isRef']
|
||||||
|
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
|
||||||
|
const markRaw: typeof import('vue')['markRaw']
|
||||||
|
const nextTick: typeof import('vue')['nextTick']
|
||||||
|
const onActivated: typeof import('vue')['onActivated']
|
||||||
|
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||||
|
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
|
||||||
|
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
|
||||||
|
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||||
|
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||||
|
const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
|
||||||
|
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||||
|
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||||
|
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
|
||||||
|
const onLongPress: typeof import('@vueuse/core')['onLongPress']
|
||||||
|
const onMounted: typeof import('vue')['onMounted']
|
||||||
|
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||||
|
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||||
|
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||||
|
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||||
|
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
|
||||||
|
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||||
|
const onUpdated: typeof import('vue')['onUpdated']
|
||||||
|
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
|
||||||
|
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
|
||||||
|
const provide: typeof import('vue')['provide']
|
||||||
|
const provideLocal: typeof import('@vueuse/core')['provideLocal']
|
||||||
|
const reactify: typeof import('@vueuse/core')['reactify']
|
||||||
|
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
|
||||||
|
const reactive: typeof import('vue')['reactive']
|
||||||
|
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
|
||||||
|
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
|
||||||
|
const reactivePick: typeof import('@vueuse/core')['reactivePick']
|
||||||
|
const readonly: typeof import('vue')['readonly']
|
||||||
|
const ref: typeof import('vue')['ref']
|
||||||
|
const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
|
||||||
|
const refDebounced: typeof import('@vueuse/core')['refDebounced']
|
||||||
|
const refDefault: typeof import('@vueuse/core')['refDefault']
|
||||||
|
const refThrottled: typeof import('@vueuse/core')['refThrottled']
|
||||||
|
const refWithControl: typeof import('@vueuse/core')['refWithControl']
|
||||||
|
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||||
|
const resolveRef: typeof import('@vueuse/core')['resolveRef']
|
||||||
|
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
|
||||||
|
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||||
|
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||||
|
const shallowRef: typeof import('vue')['shallowRef']
|
||||||
|
const syncRef: typeof import('@vueuse/core')['syncRef']
|
||||||
|
const syncRefs: typeof import('@vueuse/core')['syncRefs']
|
||||||
|
const templateRef: typeof import('@vueuse/core')['templateRef']
|
||||||
|
const throttledRef: typeof import('@vueuse/core')['throttledRef']
|
||||||
|
const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
|
||||||
|
const toRaw: typeof import('vue')['toRaw']
|
||||||
|
const toReactive: typeof import('@vueuse/core')['toReactive']
|
||||||
|
const toRef: typeof import('vue')['toRef']
|
||||||
|
const toRefs: typeof import('vue')['toRefs']
|
||||||
|
const toValue: typeof import('vue')['toValue']
|
||||||
|
const triggerRef: typeof import('vue')['triggerRef']
|
||||||
|
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
|
||||||
|
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
|
||||||
|
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
|
||||||
|
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
|
||||||
|
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
|
||||||
|
const unref: typeof import('vue')['unref']
|
||||||
|
const unrefElement: typeof import('@vueuse/core')['unrefElement']
|
||||||
|
const until: typeof import('@vueuse/core')['until']
|
||||||
|
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
|
||||||
|
const useAnimate: typeof import('@vueuse/core')['useAnimate']
|
||||||
|
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
|
||||||
|
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
|
||||||
|
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
|
||||||
|
const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
|
||||||
|
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
|
||||||
|
const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast']
|
||||||
|
const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes']
|
||||||
|
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
|
||||||
|
const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
|
||||||
|
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
|
||||||
|
const useArraySome: typeof import('@vueuse/core')['useArraySome']
|
||||||
|
const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique']
|
||||||
|
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
|
||||||
|
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
|
||||||
|
const useAttrs: typeof import('vue')['useAttrs']
|
||||||
|
const useBase64: typeof import('@vueuse/core')['useBase64']
|
||||||
|
const useBattery: typeof import('@vueuse/core')['useBattery']
|
||||||
|
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
|
||||||
|
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
|
||||||
|
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
|
||||||
|
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
|
||||||
|
const useCached: typeof import('@vueuse/core')['useCached']
|
||||||
|
const useClipboard: typeof import('@vueuse/core')['useClipboard']
|
||||||
|
const useClipboardItems: typeof import('@vueuse/core')['useClipboardItems']
|
||||||
|
const useCloned: typeof import('@vueuse/core')['useCloned']
|
||||||
|
const useColorMode: typeof import('@vueuse/core')['useColorMode']
|
||||||
|
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
|
||||||
|
const useCounter: typeof import('@vueuse/core')['useCounter']
|
||||||
|
const useCssModule: typeof import('vue')['useCssModule']
|
||||||
|
const useCssVar: typeof import('@vueuse/core')['useCssVar']
|
||||||
|
const useCssVars: typeof import('vue')['useCssVars']
|
||||||
|
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
|
||||||
|
const useCycleList: typeof import('@vueuse/core')['useCycleList']
|
||||||
|
const useDark: typeof import('@vueuse/core')['useDark']
|
||||||
|
const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
|
||||||
|
const useDebounce: typeof import('@vueuse/core')['useDebounce']
|
||||||
|
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
|
||||||
|
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
|
||||||
|
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
|
||||||
|
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
|
||||||
|
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
|
||||||
|
const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
|
||||||
|
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
|
||||||
|
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
|
||||||
|
const useDraggable: typeof import('@vueuse/core')['useDraggable']
|
||||||
|
const useDropZone: typeof import('@vueuse/core')['useDropZone']
|
||||||
|
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
|
||||||
|
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
|
||||||
|
const useElementHover: typeof import('@vueuse/core')['useElementHover']
|
||||||
|
const useElementSize: typeof import('@vueuse/core')['useElementSize']
|
||||||
|
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
|
||||||
|
const useEventBus: typeof import('@vueuse/core')['useEventBus']
|
||||||
|
const useEventListener: typeof import('@vueuse/core')['useEventListener']
|
||||||
|
const useEventSource: typeof import('@vueuse/core')['useEventSource']
|
||||||
|
const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
|
||||||
|
const useFavicon: typeof import('@vueuse/core')['useFavicon']
|
||||||
|
const useFetch: typeof import('@vueuse/core')['useFetch']
|
||||||
|
const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
|
||||||
|
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
|
||||||
|
const useFocus: typeof import('@vueuse/core')['useFocus']
|
||||||
|
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
|
||||||
|
const useFps: typeof import('@vueuse/core')['useFps']
|
||||||
|
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
|
||||||
|
const useGamepad: typeof import('@vueuse/core')['useGamepad']
|
||||||
|
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
|
||||||
|
const useHead: typeof import('@unhead/vue')['useHead']
|
||||||
|
const useHeadSafe: typeof import('@unhead/vue')['useHeadSafe']
|
||||||
|
const useI18n: typeof import('vue-i18n')['useI18n']
|
||||||
|
const useId: typeof import('vue')['useId']
|
||||||
|
const useIdle: typeof import('@vueuse/core')['useIdle']
|
||||||
|
const useImage: typeof import('@vueuse/core')['useImage']
|
||||||
|
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
|
||||||
|
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
|
||||||
|
const useInterval: typeof import('@vueuse/core')['useInterval']
|
||||||
|
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
|
||||||
|
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
|
||||||
|
const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
|
||||||
|
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
|
||||||
|
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
|
||||||
|
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
|
||||||
|
const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
|
||||||
|
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
|
||||||
|
const useMemoize: typeof import('@vueuse/core')['useMemoize']
|
||||||
|
const useMemory: typeof import('@vueuse/core')['useMemory']
|
||||||
|
const useModel: typeof import('vue')['useModel']
|
||||||
|
const useMounted: typeof import('@vueuse/core')['useMounted']
|
||||||
|
const useMouse: typeof import('@vueuse/core')['useMouse']
|
||||||
|
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
|
||||||
|
const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
|
||||||
|
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
|
||||||
|
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
|
||||||
|
const useNetwork: typeof import('@vueuse/core')['useNetwork']
|
||||||
|
const useNow: typeof import('@vueuse/core')['useNow']
|
||||||
|
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
|
||||||
|
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
|
||||||
|
const useOnline: typeof import('@vueuse/core')['useOnline']
|
||||||
|
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
|
||||||
|
const useParallax: typeof import('@vueuse/core')['useParallax']
|
||||||
|
const useParentElement: typeof import('@vueuse/core')['useParentElement']
|
||||||
|
const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver']
|
||||||
|
const usePermission: typeof import('@vueuse/core')['usePermission']
|
||||||
|
const usePointer: typeof import('@vueuse/core')['usePointer']
|
||||||
|
const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
|
||||||
|
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
|
||||||
|
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
|
||||||
|
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
|
||||||
|
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
|
||||||
|
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
|
||||||
|
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
|
||||||
|
const usePrevious: typeof import('@vueuse/core')['usePrevious']
|
||||||
|
const useRafFn: typeof import('@vueuse/core')['useRafFn']
|
||||||
|
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
|
||||||
|
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
|
||||||
|
const useRoute: typeof import('vue-router')['useRoute']
|
||||||
|
const useRouter: typeof import('vue-router')['useRouter']
|
||||||
|
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
|
||||||
|
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
|
||||||
|
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
|
||||||
|
const useScroll: typeof import('@vueuse/core')['useScroll']
|
||||||
|
const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
|
||||||
|
const useSeoMeta: typeof import('@unhead/vue')['useSeoMeta']
|
||||||
|
const useServerHead: typeof import('@unhead/vue')['useServerHead']
|
||||||
|
const useServerHeadSafe: typeof import('@unhead/vue')['useServerHeadSafe']
|
||||||
|
const useServerSeoMeta: typeof import('@unhead/vue')['useServerSeoMeta']
|
||||||
|
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
|
||||||
|
const useShare: typeof import('@vueuse/core')['useShare']
|
||||||
|
const useSlots: typeof import('vue')['useSlots']
|
||||||
|
const useSorted: typeof import('@vueuse/core')['useSorted']
|
||||||
|
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
|
||||||
|
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
|
||||||
|
const useStepper: typeof import('@vueuse/core')['useStepper']
|
||||||
|
const useStorage: typeof import('@vueuse/core')['useStorage']
|
||||||
|
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
|
||||||
|
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
|
||||||
|
const useSupported: typeof import('@vueuse/core')['useSupported']
|
||||||
|
const useSwipe: typeof import('@vueuse/core')['useSwipe']
|
||||||
|
const useTemplateRef: typeof import('vue')['useTemplateRef']
|
||||||
|
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
|
||||||
|
const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
|
||||||
|
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
|
||||||
|
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
|
||||||
|
const useThrottle: typeof import('@vueuse/core')['useThrottle']
|
||||||
|
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
|
||||||
|
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
|
||||||
|
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
|
||||||
|
const useTimeout: typeof import('@vueuse/core')['useTimeout']
|
||||||
|
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
|
||||||
|
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
|
||||||
|
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
|
||||||
|
const useTitle: typeof import('@vueuse/core')['useTitle']
|
||||||
|
const useToNumber: typeof import('@vueuse/core')['useToNumber']
|
||||||
|
const useToString: typeof import('@vueuse/core')['useToString']
|
||||||
|
const useToggle: typeof import('@vueuse/core')['useToggle']
|
||||||
|
const useTransition: typeof import('@vueuse/core')['useTransition']
|
||||||
|
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
|
||||||
|
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
|
||||||
|
const useVModel: typeof import('@vueuse/core')['useVModel']
|
||||||
|
const useVModels: typeof import('@vueuse/core')['useVModels']
|
||||||
|
const useVibrate: typeof import('@vueuse/core')['useVibrate']
|
||||||
|
const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
|
||||||
|
const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
|
||||||
|
const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
|
||||||
|
const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
|
||||||
|
const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
|
||||||
|
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
|
||||||
|
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
|
||||||
|
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
|
||||||
|
const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
|
||||||
|
const watch: typeof import('vue')['watch']
|
||||||
|
const watchArray: typeof import('@vueuse/core')['watchArray']
|
||||||
|
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
|
||||||
|
const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
|
||||||
|
const watchDeep: typeof import('@vueuse/core')['watchDeep']
|
||||||
|
const watchEffect: typeof import('vue')['watchEffect']
|
||||||
|
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
|
||||||
|
const watchImmediate: typeof import('@vueuse/core')['watchImmediate']
|
||||||
|
const watchOnce: typeof import('@vueuse/core')['watchOnce']
|
||||||
|
const watchPausable: typeof import('@vueuse/core')['watchPausable']
|
||||||
|
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||||
|
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||||
|
const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
|
||||||
|
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
|
||||||
|
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
|
||||||
|
const whenever: typeof import('@vueuse/core')['whenever']
|
||||||
|
}
|
||||||
|
// for type re-export
|
||||||
|
declare global {
|
||||||
|
// @ts-ignore
|
||||||
|
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||||
|
import('vue')
|
||||||
|
}
|
||||||
46
types/router.d.ts
vendored
Normal file
46
types/router.d.ts
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️
|
||||||
|
// It's recommended to commit this file.
|
||||||
|
// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
|
||||||
|
|
||||||
|
declare module 'vue-router/auto-routes' {
|
||||||
|
import type {
|
||||||
|
RouteRecordInfo,
|
||||||
|
ParamValue,
|
||||||
|
ParamValueOneOrMore,
|
||||||
|
ParamValueZeroOrMore,
|
||||||
|
ParamValueZeroOrOne,
|
||||||
|
} from 'vue-router'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route name map generated by unplugin-vue-router
|
||||||
|
*/
|
||||||
|
export interface RouteNamedMap {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route file to route info map by unplugin-vue-router.
|
||||||
|
* Used by the volar plugin to automatically type useRoute()
|
||||||
|
*
|
||||||
|
* Each key is a file path relative to the project root with 2 properties:
|
||||||
|
* - routes: union of route names of the possible routes when in this page (passed to useRoute<...>())
|
||||||
|
* - views: names of nested views (can be passed to <RouterView name="...">)
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export interface _RouteFileInfoMap {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a union of possible route names in a certain route component file.
|
||||||
|
* Used by the volar plugin to automatically type useRoute()
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export type _RouteNamesForFilePath<FilePath extends string> =
|
||||||
|
_RouteFileInfoMap extends Record<FilePath, infer Info>
|
||||||
|
? Info['routes']
|
||||||
|
: keyof RouteNamedMap
|
||||||
|
}
|
||||||
264
vite.config.ts
Normal file
264
vite.config.ts
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import {isProduction, isDebug, env, process} from 'std-env'
|
||||||
|
import Vue from '@vitejs/plugin-vue'
|
||||||
|
import VueRouter from 'unplugin-vue-router/vite'
|
||||||
|
import { VueRouterAutoImports } from 'unplugin-vue-router'
|
||||||
|
import Components from 'unplugin-vue-components/vite'
|
||||||
|
import Imports from 'unplugin-auto-import/vite'
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
|
import PurgeCSS from 'rollup-plugin-purgecss'
|
||||||
|
import Unhead from '@unhead/addons/vite'
|
||||||
|
import DevTools from 'vite-plugin-vue-devtools'
|
||||||
|
import { unheadVueComposablesImports } from '@unhead/vue'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the main configuration file for vitejs
|
||||||
|
*
|
||||||
|
* @see https://vitejs.dev/config
|
||||||
|
*/
|
||||||
|
export default defineConfig(({ isSsrBuild }) => ({
|
||||||
|
// Project root directory (where index.html is located).
|
||||||
|
root: process.cwd(),
|
||||||
|
// Base public path when served in development or production.
|
||||||
|
// You also need to add this base like `history: createWebHistory('my-subdirectory')`
|
||||||
|
// in ./src/router.ts
|
||||||
|
// base: '/my-subdirectory/',
|
||||||
|
base: '/',
|
||||||
|
publicDir: 'public',
|
||||||
|
logLevel: 'info',
|
||||||
|
resolve: {
|
||||||
|
alias: [
|
||||||
|
{
|
||||||
|
find: '/@src/',
|
||||||
|
replacement: `/src/`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: '/@server/',
|
||||||
|
replacement: `/server/`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// development server configuration
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 3000,
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'https://svcm.hmsn.ink',
|
||||||
|
// target: 'http://localhost:8010',
|
||||||
|
changeOrigin: true,
|
||||||
|
// rewrite: (path) => path.replace(/^\/api/, ''),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ssr: {
|
||||||
|
// adding those dependencies to the ssr build allow to use compile time flags
|
||||||
|
noExternal: isProduction
|
||||||
|
? ['vue', 'vue-i18n', 'vue-router']
|
||||||
|
: ['vue-i18n', 'vue-router'],
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
// compile time flags - allow to tree shake ssr code if not needed
|
||||||
|
__VUERO_SSR_BUILD__: env.SSR_BUILD
|
||||||
|
? 'true'
|
||||||
|
: 'false',
|
||||||
|
// https://vuejs.org/api/compile-time-flags.html
|
||||||
|
__VUE_OPTIONS_API__: 'true',
|
||||||
|
__VUE_PROD_DEVTOOLS__: isDebug
|
||||||
|
? 'true'
|
||||||
|
: 'false',
|
||||||
|
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: isDebug
|
||||||
|
? 'true'
|
||||||
|
: 'false',
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
target: 'esnext',
|
||||||
|
cssMinify: isDebug
|
||||||
|
? false
|
||||||
|
: 'esbuild',
|
||||||
|
minify: isDebug
|
||||||
|
? false
|
||||||
|
: 'terser',
|
||||||
|
sourcemap: isDebug,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
format: 'esm',
|
||||||
|
entryFileNames: isSsrBuild ? '[name].mjs' : '[name]-[hash].js',
|
||||||
|
// Using only hash to prevent adblockers from blocking assets that match their patterns.
|
||||||
|
chunkFileNames: isDebug
|
||||||
|
? `assets/_/[name].${isSsrBuild ? 'mjs' : 'js'}`
|
||||||
|
: `assets/_/[hash].${isSsrBuild ? 'mjs' : 'js'}`,
|
||||||
|
assetFileNames: isDebug
|
||||||
|
? 'assets/[name][extname]'
|
||||||
|
: 'assets/[hash][extname]',
|
||||||
|
// Using manualChunks to group layout scss in one chunk to avoid Cumulative Layout Shift (CLS)
|
||||||
|
manualChunks(id) {
|
||||||
|
if (id.endsWith('scss/main.scss')) {
|
||||||
|
return 'layouts'
|
||||||
|
}
|
||||||
|
if (id.endsWith('.scss') && id.match(/components\/layouts\/(?:.*?)scss$/)) {
|
||||||
|
return 'layouts'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
/**
|
||||||
|
* Shows a quick overview of your app, including the Vue version, pages and components.
|
||||||
|
*
|
||||||
|
* @see https://devtools-next.vuejs.org/
|
||||||
|
*/
|
||||||
|
DevTools(),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unplugin-vue-router plugin generate routes based on file system
|
||||||
|
* allow to use typed routes and usage of defineLoader
|
||||||
|
*
|
||||||
|
* @see https://uvr.esm.is/rfcs/data-loaders/
|
||||||
|
*/
|
||||||
|
VueRouter({
|
||||||
|
routesFolder: 'src/pages',
|
||||||
|
dts: './types/router.d.ts',
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* plugin-vue plugin inject vue library and allow sfc files to work (*.vue)
|
||||||
|
*
|
||||||
|
* @see https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/README.md
|
||||||
|
*/
|
||||||
|
Vue({
|
||||||
|
include: [/\.vue$/],
|
||||||
|
template: {
|
||||||
|
compilerOptions: {
|
||||||
|
isCustomElement: tag => ['iconify-icon'].includes(tag),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unhead provides a Vite plugin to optimise your builds, by removing composables that aren't needed and simplifying your code.
|
||||||
|
*
|
||||||
|
* @see https://unhead.harlanzw.com/guide/getting-started/vite-plugin
|
||||||
|
*/
|
||||||
|
Unhead(),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unplugin-auto-import allow to automaticaly import modules/components
|
||||||
|
*
|
||||||
|
* @see https://github.com/antfu/unplugin-auto-import
|
||||||
|
*/
|
||||||
|
Imports({
|
||||||
|
dts: './types/imports.d.ts',
|
||||||
|
imports: [
|
||||||
|
'vue',
|
||||||
|
'@vueuse/core',
|
||||||
|
'vue-i18n',
|
||||||
|
VueRouterAutoImports,
|
||||||
|
unheadVueComposablesImports,
|
||||||
|
],
|
||||||
|
dirs: ['src/composables', 'src/stores', 'src/utils'],
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unplugin-vue-components plugin is responsible of autoloading components
|
||||||
|
* documentation and md file are loaded for elements and components sections
|
||||||
|
*
|
||||||
|
* @see https://github.com/antfu/unplugin-vue-components
|
||||||
|
*/
|
||||||
|
Components({
|
||||||
|
dirs: ['documentation', 'src/components'],
|
||||||
|
extensions: ['vue', 'md'],
|
||||||
|
dts: './types/components.d.ts',
|
||||||
|
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vite-plugin-pwa generate manifest.json and register services worker to enable PWA
|
||||||
|
*
|
||||||
|
* @see https://github.com/antfu/vite-plugin-pwa
|
||||||
|
*/
|
||||||
|
VitePWA({
|
||||||
|
base: '/',
|
||||||
|
includeAssets: ['favicon.ico', 'robots.txt'],
|
||||||
|
manifest: {
|
||||||
|
name: '소액계약관리 플랫폼',
|
||||||
|
short_name: '소액계약관리',
|
||||||
|
start_url: '/?utm_source=pwa',
|
||||||
|
display: 'standalone',
|
||||||
|
theme_color: '#ffffff',
|
||||||
|
background_color: '#ffffff',
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
src: 'pwa-192x192.png',
|
||||||
|
sizes: '192x192',
|
||||||
|
type: 'image/png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'pwa-512x512.png',
|
||||||
|
sizes: '512x512',
|
||||||
|
type: 'image/png',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'pwa-512x512.png',
|
||||||
|
sizes: '512x512',
|
||||||
|
type: 'image/png',
|
||||||
|
purpose: 'any maskable',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
mode: isProduction
|
||||||
|
? 'production'
|
||||||
|
: 'development',
|
||||||
|
workbox: {
|
||||||
|
/**
|
||||||
|
* precache files that match the glob pattern
|
||||||
|
*
|
||||||
|
* @see https://vite-pwa-org.netlify.app/guide/service-worker-precache.html
|
||||||
|
*/
|
||||||
|
globPatterns: ['**/*.{js,mjs,css,ico,png,svg,webp,jpg,jpeg,html}'],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rollup-plugin-purgecss plugin is responsible of purging css rules
|
||||||
|
* that are not used in the bundle
|
||||||
|
*
|
||||||
|
* @see https://github.com/FullHuman/purgecss/tree/main/packages/rollup-plugin-purgecss
|
||||||
|
*/
|
||||||
|
PurgeCSS({
|
||||||
|
output: false,
|
||||||
|
content: [`./src/**/*.vue`],
|
||||||
|
variables: false,
|
||||||
|
safelist: {
|
||||||
|
standard: [
|
||||||
|
/(autv|lnil|lnir|fas?)/,
|
||||||
|
/-(leave|enter|appear)(|-(to|from|active))$/,
|
||||||
|
/^(?!(|.*?:)cursor-move).+-move$/,
|
||||||
|
/^router-link(|-exact)-active$/,
|
||||||
|
/data-v-.*/,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
defaultExtractor(content) {
|
||||||
|
const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, '')
|
||||||
|
return contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) || []
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
// Predefine dependencies in order to prevent reloading them in the browser during development.
|
||||||
|
optimizeDeps: {
|
||||||
|
include: [
|
||||||
|
'@vee-validate/zod',
|
||||||
|
'@vueuse/core',
|
||||||
|
'@vueuse/router',
|
||||||
|
'@vueuse/integrations/useCookies',
|
||||||
|
'notyf',
|
||||||
|
'vue',
|
||||||
|
'vue-i18n',
|
||||||
|
'vue-router',
|
||||||
|
'unplugin-vue-router/runtime',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}))
|
||||||
Reference in New Issue
Block a user