Vue¶
CLI¶
It's succeeded by Vite.
in node_modules/.bin/vue-cli-service
run with npx vue-cli-service
init¶
Install Node.js¶
See NodeJs
Create vue project¶
With vue-cli-service¶
With Vite¶
In your project root, run
If there's an error, try update node to the latest version, open a new shell and run again. See NodeJs.
import¶
@
= /src
It's defined in vue.config.js
or vite.config.js
e.g.
// they are the same
import Students from '@/components/Students.vue'
import Students from '/src/components/Students.vue'
environmental variables¶
https://vitejs.dev/guide/env-and-mode.html
It will use .env
. All keys starting with VITE_
can be accessed with import.meta.env.<env_key>
.
e.g.
Pinia¶
State management tool for Vue, successor of Vuex.
Example
https://codesandbox.io/s/pinia-vue-3-axios-interceptor-6jf11?file=/src/main.js
Init¶
Install pinia.
Add app.use(pinia)
in main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
const app = createApp(App)
const pinia = createPinia()
app.use(router)
app.use(pinia)
app.mount('#app')
Create a store¶
In src/stores/useStore.js
import { defineStore } from 'pinia'
export const useStore = defineStore('<id>', {
state: () => {
return {
counter: 0,
name: 'Eduardo',
isAdmin: true,
}
},
})
Use your store¶
To access & modify the store in a random component
First import it.
Then you can directly use it.
methods: {
test() {
// useStore().counter++
const haha = useStore();
haha.counter++;
console.log(haha.counter);
}
}
Or you can declare it with
or
Now you can access it with this.haha
like a normal component data.
Watch your store¶
<script>
export default {
computed: {
timeRange(){
return this.globe.timeRange;
},
},
watch: {
timeRange(newVal, oldVal) {
// do something
}
},
}
</script>
You can also use is directly as key
routing¶
vue-router doc
a nice tutorial
Install vue-router
Define routes in src/main.js
import { createApp } from 'vue'
import App from '@/App.vue'
// import router from '@/router'
import { createRouter, createWebHistory } from 'vue-router'
import Students from '@/views/Students_blade.vue'
import Home from '@/views/Home_blade.vue'
const routes = [
{ path: '/', component: Home},
{ path: '/students', component: Students },
{ path: "/:pathMatch(.*)", name: "not-found", component: Invalid },
];
const router = createRouter({
history: createWebHistory(),
// history: createWebHashHistory(),
routes,
});
// export default router;
// createApp(App).use(router).mount('#app')
const app = createApp(App)
app.use(router)
app.mount('#app')
You can put the routes in /src/router.js
and import it to make it cleaner.
To show the html of the routing target
You can put it in index.html
or App.vue
. Without this, the routing you've defined will do exactly nothing.
base url¶
Give base url in createWebHistory()
(or createWebHashHistory()
.
If you use vite, then it's
https://github.com/vitejs/vite/issues/2114#issuecomment-782727527
fallback route¶
Link to route¶
To link to this route,
Do this. It will match to the route with the same name
and pass the params
.
<router-link :to="{name: 'student', params: {id: student.student_id}}"> {{ student.student_name }}</router-link>
history mode¶
It defines how your url will look like. With HTML5 mode, url will look like domain/path
. With hash mode, url will look like domain/#/path
. See the comparison below.
- HTML5
- command:
createWebHistory
- pros: url looks natural
- cons: can't be directly accessed (because you don't actually have a file in that route)
- command:
- Hash
- command:
createWebHashHistory
- pros: can be directly accessed
- cons: url is different from the norm
- command:
There's also a memory mode, which doesn't change the url at all.
parameters¶
$route.params.<key>
to access url variables
$route.name
to access the route name
e.g.
For { path: '/std/:id', name: "student", component: Data }
,
$route.params.id
= the id
$route.name
= "student"
export default¶
data¶
Define values
computed¶
define values that need to be computed
will automatically be recomputed
methods¶
Define functions
mounted¶
execute when first load
directive¶
v-bind¶
To access data value in html tag, shorthand to :
v-on¶
Event listener, shorthand to @
.
v-model¶
<input v-model:"haha">
will automatically make haha
= input value
v-if¶
v-for¶
<div>
<ul>
<li v-for="student in students">
{{ student['student_id'] }} {{ student['student_name'] }}
</li>
</ul>
</div>
refresh¶
When text
is changed, this element will be refreshed.
Can also watch multiple variables.
You can manipulate it and put it on <router-view />
to refresh the page, or on whatever component to refresh that component, for example.
<script setup>
import Students from '@/components/Students.vue'
import Attendance from '../components/Attendance.vue';
</script>
<script>
export default {
data() {
return {
update: 0,
}
},
methods: {
refresh() {
this.update++;
}
}
}
</script>
<template>
<h1>Current State of the Classroom</h1>
<button class='btn' id="refresh" @click="refresh()">refresh</button>
<h2>Attendance</h2>
<Attendance :key="update"/>
<h2>Specific Students</h2>
<Students :key="update"/>
</template>
https://stackoverflow.com/a/54367510/15493213
run locally¶
dev¶
With Vite
run with express¶
var express = require('express');
var path = require('path');
var serveStatic = require('serve-static');
app = express();
app.use(serveStatic(__dirname + "/dist"));
var port = process.env.PORT || 7070;
var hostname = '127.0.0.1';
app.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
https://stackoverflow.com/a/53945050/15493213
build for production¶
It will produce static files in dist/
. To host your vue app, push these static files to whatever hosting option you like.
To disable file name hashing, add this in vite.config.js
in defineConfig
build: {
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`
}
}
}
or if you use vue-cli, see https://cli.vuejs.org/config/#filenamehashing.
With Flask¶
Modify Flask's template folder & static folder to vue's.
IDE¶
VsCode with Volar extension
sample¶
<script>
let id = 3;
let sample = {};
for(let i=0; i<id; i++){
sample[i] = "sample " + i;
}
export default {
data() {
return {
newTodo: '',
todos: sample,
}
},
methods: {
addTodo() {
this.todos[id++] = this.newTodo
},
removeTodo(id) {
console.log(id)
delete(this.todos[id])
}
}
}
</script>
<template>
<form @submit.prevent="addTodo">
<input v-model="newTodo">
<button>Add Todo</button>
</form>
<ul>
<li v-for="(text, id) in todos" :key="id">
{{text}} {{id}}
<button @click="removeTodo(id)">X</button>
</li>
</ul>
</template>
Troubleshooting¶
yarn dependency problem¶
ignore engines temporarily
or
https://github.com/vuejs/vue-cli/issues/7116
Uncaught TypeError: store.$id is undefined¶
or Uncaught TypeError: Cannot read properties of undefined (reading 'startsWith')
maybe you didn't give your pinia store a id