Initial commit
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
import MyCounter from "./components/MyCounter.vue"
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<MyCounter />
|
||||
|
||||
</template>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script setup>
|
||||
|
||||
import useToggleTheme from '../composables/useToggleTheme.js';
|
||||
|
||||
const [toggleTheme, themeStyles] = useToggleTheme(
|
||||
{color:"red", backgroundColor:"black"},
|
||||
{color:"green", textAlign:"right", backgroundColor:"gainsboro"}
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<h3>MyCounter Component</h3>
|
||||
<div>
|
||||
<button @click="toggleTheme">Toggle Theme</button>
|
||||
<p :style="themeStyles">Paragraph 1</p>
|
||||
<p :style="themeStyles">Paragraph 2</p>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
p {
|
||||
height : 30px;
|
||||
padding-top: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,15 @@
|
||||
<script setup>
|
||||
|
||||
import MyCounter from "./MyCounter.vue";
|
||||
import { defineProps } from "vue";
|
||||
|
||||
const props = defineProps(["nb"]);
|
||||
const nb = props.nb || 1;
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<MyCounter v-for="i in nb" :key="i" :index="i" />
|
||||
|
||||
</template>
|
||||
@@ -0,0 +1,25 @@
|
||||
<script setup>
|
||||
import useFetchCountries from "../composables/useFetchCountries"
|
||||
|
||||
import { ref } from "vue";
|
||||
const data = ref();
|
||||
|
||||
const url = "https://restcountries.com/v3.1/all";
|
||||
const [startFetch] = useFetchCountries(url);
|
||||
|
||||
const initData = async () => {
|
||||
data.value = await startFetch();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<button @click="initData">Start Fetch</button>
|
||||
<br><br>
|
||||
<b>Data</b> :
|
||||
<ul>
|
||||
<li v-for="(country, i) in data" :key="i">{{country}}</li>
|
||||
</ul>
|
||||
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<script setup>
|
||||
|
||||
import { ref } from "vue"
|
||||
|
||||
const name = ref("");
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<h3>Input Form</h3>
|
||||
Name: <input type="text" v-model.lazy="name" />
|
||||
<br/><br/>
|
||||
|
||||
<h3>Reactive Variables</h3>
|
||||
name: <b>{{name}}</b>
|
||||
<br/><br/>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
h3 {
|
||||
background-color: gainsboro;
|
||||
padding: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,14 @@
|
||||
import { ref } from "vue";
|
||||
|
||||
const useCounter = (init) => {
|
||||
const count = ref(init);
|
||||
const increment = () => {
|
||||
count.value++;
|
||||
}
|
||||
const decrement = () => {
|
||||
count.value--;
|
||||
}
|
||||
return [count, increment, decrement];
|
||||
}
|
||||
|
||||
export default useCounter;
|
||||
@@ -0,0 +1,16 @@
|
||||
import useCounter from "../composables/useCounter";
|
||||
|
||||
const useCounterMax = (init, max) => {
|
||||
const [count, increment, decrement] = useCounter(init);
|
||||
const incrementMax = () => {
|
||||
if (count.value >= max) {
|
||||
return; // Avoid incrementing
|
||||
}
|
||||
else {
|
||||
increment(); // Increment
|
||||
}
|
||||
}
|
||||
return [count, incrementMax, decrement];
|
||||
}
|
||||
|
||||
export default useCounterMax;
|
||||
@@ -0,0 +1,28 @@
|
||||
import useCounter from "../composables/useCounter";
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
const useCounterMaxWithError = (init, max) => {
|
||||
const [count, increment, decrement] = useCounter(init);
|
||||
const error = ref("");
|
||||
const incrementMax = () => {
|
||||
if (count.value >= max) {
|
||||
error.value = "Maximum value reached!";
|
||||
}
|
||||
else {
|
||||
increment();
|
||||
error.value = "";
|
||||
}
|
||||
}
|
||||
const decrementMax = () => {
|
||||
decrement();
|
||||
if (count.value <= max) {
|
||||
error.value = "";
|
||||
}
|
||||
}
|
||||
onMounted(()=> {
|
||||
if (count.value > max) error.value = "Maximum value reached!";
|
||||
});
|
||||
return [count, incrementMax, decrementMax, error];
|
||||
}
|
||||
|
||||
export default useCounterMaxWithError;
|
||||
@@ -0,0 +1,10 @@
|
||||
const useFetch = (url) => {
|
||||
const startFetch = async () => {
|
||||
const res = await fetch(url);
|
||||
const d = await res.text();
|
||||
return JSON.parse(d); // Returning the data read from the server in JSON format
|
||||
}
|
||||
return [startFetch];
|
||||
}
|
||||
|
||||
export default useFetch;
|
||||
@@ -0,0 +1,17 @@
|
||||
import useFetch from "./useFetch";
|
||||
|
||||
const useFetchCountries = (url) => {
|
||||
const [startFetch] = useFetch(url);
|
||||
let countries;
|
||||
const startFetchCountries = async () => {
|
||||
const data = await startFetch();
|
||||
countries = data.map(function(elem) {
|
||||
return elem.name.common; // Retain only the common.name property
|
||||
});
|
||||
countries = countries.sort((n1, n2) => (n1 > n2)); // In ascending alphabetical order
|
||||
return countries;
|
||||
}
|
||||
return [startFetchCountries];
|
||||
}
|
||||
|
||||
export default useFetchCountries;
|
||||
@@ -0,0 +1,34 @@
|
||||
import { customRef } from "vue";
|
||||
|
||||
const formatDate = (date, format) => {
|
||||
const options = { year: 'numeric', month: '2-digit', day: '2-digit' };
|
||||
|
||||
if (format == "MM-DD-YYYY")
|
||||
return date.toLocaleDateString('en-US', options).replace(/\//g, '-');
|
||||
else if (format == "DD-MM-YYYY")
|
||||
return date.toLocaleDateString('en-GB', options).replace(/\//g, '-');
|
||||
else if (format == "MM/DD/YYYY")
|
||||
return date.toLocaleDateString('en-US', options);
|
||||
else if (format == "DD/MM/YYYY")
|
||||
return date.toLocaleDateString('en-GB', options);
|
||||
}
|
||||
|
||||
const useFormatDate = (date, format) => {
|
||||
return customRef((track, trigger) => {
|
||||
let value = date; // value will be the tracked variable
|
||||
return {
|
||||
get() {
|
||||
// track the dependency when the value is read
|
||||
track();
|
||||
return formatDate(value, format);
|
||||
},
|
||||
set(newValue) {
|
||||
// update the value and trigger reactivity
|
||||
value = newValue;
|
||||
trigger();
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export default useFormatDate;
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
const useGeolocation = () => {
|
||||
const latitude = ref(null);
|
||||
const longitude = ref(null);
|
||||
|
||||
const handleGeolocation = (position) => {
|
||||
latitude.value = position.coords.latitude;
|
||||
longitude.value = position.coords.longitude;
|
||||
};
|
||||
|
||||
const errorGeolocation = (error) => {
|
||||
console.log("Geolocation error:", error.message);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(handleGeolocation, errorGeolocation);
|
||||
} else {
|
||||
console.log("Geolocation is not available in this browser.");
|
||||
}
|
||||
});
|
||||
|
||||
return [latitude, longitude];
|
||||
}
|
||||
|
||||
export default useGeolocation;
|
||||
@@ -0,0 +1,29 @@
|
||||
import { ref, watchEffect } from "vue";
|
||||
|
||||
import useGeolocation from '../composables/useGeolocation';
|
||||
|
||||
const useGeolocationWithDetails = () => {
|
||||
const [latitude, longitude] = useGeolocation();
|
||||
const country = ref("");
|
||||
const city = ref("");
|
||||
|
||||
// To find the country and city corresponding to the latitude/longitude
|
||||
watchEffect(async ()=>{
|
||||
if (latitude.value && longitude.value) {
|
||||
const response = await fetch(
|
||||
`https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude.value}&lon=${longitude.value}`
|
||||
);
|
||||
const data = await response.json();
|
||||
if (data && data.address && data.address.country) {
|
||||
country.value = data.address.country;
|
||||
}
|
||||
if (data && data.address) {
|
||||
city.value = data.address.city || data.address.town;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return [latitude, longitude, country, city];
|
||||
}
|
||||
|
||||
export default useGeolocationWithDetails;
|
||||
@@ -0,0 +1,21 @@
|
||||
import L from "leaflet"
|
||||
|
||||
const useMap = (latitude, longitude, idMap) => {
|
||||
const zoom = 13;
|
||||
|
||||
// To position the map at the indicated location
|
||||
const map = L.map(idMap).setView([latitude, longitude], zoom);
|
||||
|
||||
// To display the corresponding map
|
||||
L.tileLayer("https://a.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
maxZoom: 20,
|
||||
}).addTo(map);
|
||||
|
||||
// To display a marker on the map to indicate the specified location
|
||||
L.marker([latitude, longitude]).addTo(map);
|
||||
|
||||
// We return the map object created by Leaflet
|
||||
return map;
|
||||
}
|
||||
|
||||
export default useMap;
|
||||
@@ -0,0 +1,22 @@
|
||||
import { customRef } from "vue";
|
||||
|
||||
const useMaximum = (max) => {
|
||||
// Create a custom reference (customRef)
|
||||
return customRef((track, trigger) => {
|
||||
let value = 0; // value will be the variable being tracked, initialized here to 0.
|
||||
return {
|
||||
get() {
|
||||
// Track the dependency when the value is read.
|
||||
track();
|
||||
return value;
|
||||
},
|
||||
set(newValue) {
|
||||
// Update the value and trigger reactivity.
|
||||
if (newValue <= max) value = newValue;
|
||||
trigger();
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default useMaximum;
|
||||
@@ -0,0 +1,17 @@
|
||||
import { ref } from 'vue';
|
||||
|
||||
const useThemeToggle = (theme0, theme1) => {
|
||||
const themes = [theme0, theme1];
|
||||
let theme = 0; // theme0 by default
|
||||
const themeStyles = ref(themes[theme]);
|
||||
|
||||
const toggleTheme = () => {
|
||||
if (theme == 0) theme = 1;
|
||||
else theme = 0;
|
||||
themeStyles.value = themes[theme];
|
||||
};
|
||||
|
||||
return [toggleTheme, themeStyles];
|
||||
}
|
||||
|
||||
export default useThemeToggle;
|
||||
@@ -0,0 +1,21 @@
|
||||
import { customRef } from 'vue';
|
||||
|
||||
const useUpperCase = (initValue) => {
|
||||
return customRef((track, trigger) => {
|
||||
let value = initValue; // value will be the tracked variable
|
||||
return {
|
||||
get() {
|
||||
// track the dependency when the value is read
|
||||
track();
|
||||
return value.toUpperCase();
|
||||
},
|
||||
set(newValue) {
|
||||
// update the value and trigger reactivity
|
||||
value = newValue;
|
||||
trigger();
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export default useUpperCase;
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ref, onMounted, onBeforeUnmount } from "vue";
|
||||
|
||||
const useWindowSize = () => {
|
||||
const windowSize = ref({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
});
|
||||
|
||||
const updateWindowSize = () => {
|
||||
windowSize.value = {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
};
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', updateWindowSize);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', updateWindowSize);
|
||||
});
|
||||
|
||||
return windowSize;
|
||||
}
|
||||
|
||||
export default useWindowSize;
|
||||
@@ -0,0 +1,18 @@
|
||||
import focus from "./directives/focus";
|
||||
import integersOnly from "./directives/integers-only";
|
||||
import maxValue from "./directives/max-value";
|
||||
import clearable from "./directives/clearable";
|
||||
import timer from "./directives/timer";
|
||||
import map from "./directives/map";
|
||||
import color from "./directives/color";
|
||||
|
||||
export default {
|
||||
focus,
|
||||
integersOnly,
|
||||
maxValue,
|
||||
clearable,
|
||||
timer,
|
||||
map,
|
||||
color,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
const clearable = {
|
||||
mounted(el) {
|
||||
const clearButton = document.createElement("button");
|
||||
clearButton.innerHTML = "Clear";
|
||||
clearButton.style = "position:relative; left:10px;";
|
||||
|
||||
// Handle the click on the button (clear the content of the input field).
|
||||
clearButton.addEventListener("click", () => {
|
||||
// Clear the content of the input field.
|
||||
el.value = "";
|
||||
// Simulate an input event to mimic a keyboard key press
|
||||
// (mandatory to ensure that the reactive variable linked to the input field is updated)
|
||||
el.dispatchEvent(new Event("input"));
|
||||
// Give focus to the input field
|
||||
el.focus();
|
||||
});
|
||||
|
||||
// Insert the button after the input field
|
||||
el.parentNode.insertBefore(clearButton, el.nextSibling);
|
||||
}
|
||||
};
|
||||
|
||||
export default clearable;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
const color = {
|
||||
mounted(el, binding) {
|
||||
let colorStyle;
|
||||
if (binding.modifiers.toggle) {
|
||||
const colors = binding.value;
|
||||
el.addEventListener("click", () => {
|
||||
if (colorStyle == colors[0]) colorStyle = colors[1];
|
||||
else if (colorStyle == colors[1]) colorStyle = colors[0];
|
||||
else colorStyle = colors[0];
|
||||
// Change the background color of the element
|
||||
el.style.backgroundColor = colorStyle;
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default color;
|
||||
@@ -0,0 +1,27 @@
|
||||
const focusDirective = {
|
||||
mounted(el, binding) {
|
||||
const arg = binding.arg;
|
||||
const value = binding.value;
|
||||
// Position the handling of the focus and blur events
|
||||
el.addEventListener("focus", () => {
|
||||
if (arg == "color") el.style.color = value;
|
||||
if (arg == "backgroundcolor") el.style.backgroundColor = value;
|
||||
if (arg == "colors") {
|
||||
el.style.color = value.color;
|
||||
el.style.backgroundColor = value.backgroundcolor;
|
||||
}
|
||||
});
|
||||
el.addEventListener("blur", () => {
|
||||
if (arg == "color") el.style.color = "";
|
||||
if (arg == "backgroundcolor") el.style.backgroundColor = "";
|
||||
if (arg == "colors") {
|
||||
el.style.color = "";
|
||||
el.style.backgroundColor = "";
|
||||
}
|
||||
});
|
||||
// and then give focus to the input field
|
||||
el.focus();
|
||||
}
|
||||
};
|
||||
|
||||
export default focusDirective;
|
||||
@@ -0,0 +1,56 @@
|
||||
const integersOnly = {
|
||||
mounted(el, binding) {
|
||||
|
||||
if (binding.modifiers.upper) {
|
||||
// Convert the displayed field to uppercase with an initial value
|
||||
// (for this to work, the v-model directive must be written before this one in the input field)
|
||||
el.value = el.value.toUpperCase();
|
||||
|
||||
// Simulate an input event to mimic a keyboard keypress
|
||||
// (necessary for the reactive variable linked to the field to be updated)
|
||||
el.dispatchEvent(new Event("input"));
|
||||
}
|
||||
|
||||
el.addEventListener("keydown", (event) => {
|
||||
const numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
||||
const letters = ["a", "b", "c", "d", "e", "f", "A", "B", "C", "D", "E", "F"];
|
||||
const moves = ["Backspace", "ArrowLeft", "ArrowRight",
|
||||
"Delete", "Tab", "Home", "End"];
|
||||
|
||||
let authorized; // Allowed keys in the input field
|
||||
|
||||
// Allow hexadecimal characters if the hexa modifier is present
|
||||
if (binding.modifiers.hexa) authorized = [...numbers, ...letters, ...moves];
|
||||
else authorized = [...numbers, ...moves];
|
||||
|
||||
// If the key is not allowed, do not take it into account
|
||||
if (!authorized.includes(event.key)) event.preventDefault();
|
||||
|
||||
// Handle the upper modifier
|
||||
if (binding.modifiers.upper) {
|
||||
// If the key is a hexadecimal letter, convert it to uppercase
|
||||
if (letters.includes(event.key)) {
|
||||
const start = el.selectionStart;
|
||||
const end = el.selectionEnd;
|
||||
const text = el.value;
|
||||
|
||||
// Insert the character at the cursor position
|
||||
const newText = text.substring(0, start) + event.key + text.substring(end);
|
||||
// Update the value of the input field (in uppercase)
|
||||
el.value = newText.toUpperCase();
|
||||
// Move the cursor after the inserted character
|
||||
el.setSelectionRange(start + 1, start + 1);
|
||||
|
||||
// Prevent further processing of the key (as it has already been handled above)
|
||||
event.preventDefault();
|
||||
|
||||
// Simulate an input event to mimic a keyboard keypress
|
||||
// (necessary for the reactive variable linked to the field to be updated)
|
||||
el.dispatchEvent(new Event("input"));
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
export default integersOnly;
|
||||
@@ -0,0 +1,19 @@
|
||||
import useMap from "../composables/useMap.js"
|
||||
|
||||
const map = {
|
||||
updated(el, binding) {
|
||||
const latitude = binding.value.latitude;
|
||||
const longitude = binding.value.longitude;
|
||||
if (latitude && longitude) {
|
||||
if (el._map) el._map.remove();
|
||||
el._map = useMap(latitude, longitude, el.id);
|
||||
}
|
||||
else if (el._map) {
|
||||
el._map.remove();
|
||||
el._map = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default map;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
const treatment = (el, binding) => {
|
||||
const maxValue = binding.value || 100; // 100 by default
|
||||
const value = el.value || 0; // Value in the field
|
||||
const bold = binding.modifiers.bold;
|
||||
if (value > maxValue) {
|
||||
el.style.color = "red";
|
||||
if (bold) {
|
||||
el.style.fontWeight = "bold";
|
||||
el.style.fontFamily = "arial";
|
||||
}
|
||||
}
|
||||
else {
|
||||
el.style.color = "";
|
||||
el.style.fontWeight = ""; // Removal of "bold"
|
||||
el.style.fontFamily = ""; // Removal of "arial"
|
||||
}
|
||||
}
|
||||
|
||||
const maxValue = {
|
||||
mounted(el, binding) {
|
||||
treatment(el, binding);
|
||||
},
|
||||
updated(el, binding) {
|
||||
treatment(el, binding);
|
||||
},
|
||||
}
|
||||
|
||||
export default maxValue;
|
||||
@@ -0,0 +1,141 @@
|
||||
const timer = {
|
||||
mounted(el, binding) {
|
||||
const ms = binding.modifiers.ms;
|
||||
const chrono = binding.modifiers.chrono;
|
||||
|
||||
// Initialization of the clock or stopwatch.
|
||||
if (!chrono) {
|
||||
let time = getCurrentTime(ms);
|
||||
el.innerHTML = time;
|
||||
}
|
||||
else {
|
||||
if (!ms) el.innerHTML = "00:00:00";
|
||||
else el.innerHTML = "00:00:00.0";
|
||||
}
|
||||
|
||||
setInterval(()=>{
|
||||
if (!chrono) {
|
||||
let time = getCurrentTime(ms);
|
||||
el.innerHTML = time;
|
||||
}
|
||||
else {
|
||||
const chronoTime = getChronoTime(ms);
|
||||
el.innerHTML = chronoTime;
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
}
|
||||
|
||||
function getCurrentTime(ms = false) {
|
||||
const now = new Date();
|
||||
const hours = now.getHours().toString().padStart(2, '0');
|
||||
const minutes = now.getMinutes().toString().padStart(2, '0');
|
||||
const seconds = now.getSeconds().toString().padStart(2, '0');
|
||||
let formattedTime = `${hours}:${minutes}:${seconds}`;
|
||||
|
||||
if (ms) {
|
||||
const milliseconds = now.getMilliseconds().toString().slice(0, 1); // Obtaining tenths of a second
|
||||
formattedTime += `.${milliseconds}`;
|
||||
}
|
||||
|
||||
return formattedTime;
|
||||
}
|
||||
|
||||
let startChronoTime = new Date(); // Starting time of the stopwatch
|
||||
|
||||
function getChronoTime(ms = false) {
|
||||
const now = new Date();
|
||||
const elapsedMilliseconds = now.getTime() - startChronoTime.getTime();
|
||||
|
||||
const hours = Math.floor(elapsedMilliseconds / (3600 * 1000));
|
||||
const remainingMilliseconds1 = elapsedMilliseconds % (3600 * 1000);
|
||||
|
||||
const minutes = Math.floor(remainingMilliseconds1 / (60 * 1000));
|
||||
const remainingMilliseconds2 = remainingMilliseconds1 % (60 * 1000);
|
||||
|
||||
const seconds = Math.floor(remainingMilliseconds2 / 1000);
|
||||
|
||||
let formattedTime = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||||
|
||||
if (ms) {
|
||||
const milliseconds = Math.floor(remainingMilliseconds2 % 1000);
|
||||
const tenthsOfSecond = Math.floor((milliseconds % 1000) / 100);
|
||||
formattedTime += `.${tenthsOfSecond.toString()}`;
|
||||
}
|
||||
|
||||
return formattedTime;
|
||||
}
|
||||
|
||||
export default timer;
|
||||
|
||||
|
||||
|
||||
//~ const timer = {
|
||||
//~ mounted(el, binding) {
|
||||
//~ const ms = binding.modifiers.ms;
|
||||
//~ const chrono = binding.modifiers.chrono;
|
||||
|
||||
//~ // Initialization of the clock or stopwatch.
|
||||
//~ if (!chrono) {
|
||||
//~ let time = getCurrentTime(ms);
|
||||
//~ el.innerHTML = time;
|
||||
//~ }
|
||||
//~ else {
|
||||
//~ if (!ms) el.innerHTML = "00:00:00";
|
||||
//~ else el.innerHTML = "00:00:00.0";
|
||||
//~ }
|
||||
|
||||
//~ setInterval(()=>{
|
||||
//~ if (!chrono) {
|
||||
//~ let time = getCurrentTime(ms);
|
||||
//~ el.innerHTML = time;
|
||||
//~ }
|
||||
//~ else {
|
||||
//~ const chronoTime = getChronoTime(ms);
|
||||
//~ el.innerHTML = chronoTime;
|
||||
//~ }
|
||||
//~ }, 100);
|
||||
//~ },
|
||||
//~ }
|
||||
|
||||
//~ function getCurrentTime(ms = false) {
|
||||
//~ const now = new Date();
|
||||
//~ const hours = now.getHours().toString().padStart(2, '0');
|
||||
//~ const minutes = now.getMinutes().toString().padStart(2, '0');
|
||||
//~ const seconds = now.getSeconds().toString().padStart(2, '0');
|
||||
//~ let formattedTime = `${hours}:${minutes}:${seconds}`;
|
||||
|
||||
//~ if (ms) {
|
||||
//~ const milliseconds = now.getMilliseconds().toString().slice(0, 1); // Obtaining tenths of a second.
|
||||
//~ formattedTime += `.${milliseconds}`;
|
||||
//~ }
|
||||
|
||||
//~ return formattedTime;
|
||||
//~ }
|
||||
|
||||
//~ let startChronoTime = new Date(); // Starting time of the stopwatch.
|
||||
|
||||
//~ function getChronoTime(ms = false) {
|
||||
//~ const now = new Date();
|
||||
//~ const elapsedMilliseconds = now.getTime() - startChronoTime.getTime();
|
||||
|
||||
//~ const hours = Math.floor(elapsedMilliseconds / (3600 * 1000));
|
||||
//~ const remainingMilliseconds1 = elapsedMilliseconds % (3600 * 1000);
|
||||
|
||||
//~ const minutes = Math.floor(remainingMilliseconds1 / (60 * 1000));
|
||||
//~ const remainingMilliseconds2 = remainingMilliseconds1 % (60 * 1000);
|
||||
|
||||
//~ const seconds = Math.floor(remainingMilliseconds2 / 1000);
|
||||
|
||||
//~ let formattedTime = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||||
|
||||
//~ if (ms) {
|
||||
//~ const milliseconds = Math.floor(remainingMilliseconds2 % 1000);
|
||||
//~ const tenthsOfSecond = Math.floor((milliseconds % 1000) / 100);
|
||||
//~ formattedTime += `.${tenthsOfSecond.toString()}`;
|
||||
//~ }
|
||||
|
||||
//~ return formattedTime;
|
||||
//~ }
|
||||
|
||||
//~ export default timer;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import directives from "./directives.js"
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
for (let name in directives) {
|
||||
// Creation of the directive name within the application
|
||||
app.directive(name, directives[name]);
|
||||
}
|
||||
|
||||
app.mount('#app');
|
||||
Reference in New Issue
Block a user