preface
be careful
VUE3 is not recommended at this stage for the following reasons:
- No longer compatible with IE11
- The ecology of the three parties is not perfect
- The relevant documents are not perfect, and the problems encountered are relatively difficult to solve
However, the matching experience of VUE3 and TS is relatively good.
VUE3 official website
When Vue 3.2 was released, Youda already provided the best practice solution on Weibo:
< script setup > + TS + volatile = really fragrant
Volar is a plug-in of VS Code. Its biggest function is to solve the TS prompt problem of template.
be careful
When using it, you should first remove Vetur to avoid conflict.
< script setup > is a compile time syntax for using composite API s in single file components (SFC). Compared with ordinary script syntax, it has more advantages:
- Less template content, more concise code.
- Can declare props and emit events using pure Typescript.
- Better runtime performance (its template will be compiled into rendering functions with the same scope without any intermediate agents).
- Better IDE type inference performance (reducing the work of the language server to extract types from the code).
See official documents for details Single file component
Create project
Vite
Create project
Vite Is a web development and construction tool. Due to its native ES module import mode, it can realize lightning cold server startup.
You can use Vite to quickly build Vue projects by running the following commands in the terminal.
View npm version
npm -v
Create project
# npm 6.x npm init vite@latest vue3_demo01 --template vue cd vue3_demo01 npm install npm run dev
be careful:
# npm 7 +, additional double dashes are required npm init vite@latest vue3_demo01 -- --template vue
If an error is reported
Error: Cannot find module 'worker_threads'
as a result of:
Vite requires node JS version > = 12.0.0.
Switch Node version
View my own Node edition
node -v
Therefore, you can upgrade the Node version. Here, nvm is used to manage the Node version
nvm can be downloaded and installed through the following connection.
Set mirror address
Under the installation path of nvm, find settings txt
After addition, the contents are as follows:
root: D:\Tools\nvm path: D:\Tools\nodejs node_mirror: https://npm.taobao.org/mirrors/node/ npm_mirror: https://npm.taobao.org/mirrors/npm/
Or execute
nvm node_mirror https://npm.taobao.org/mirrors/node/ nvm npm_mirror https://npm.taobao.org/mirrors/npm/
Switch version
# View available versions nvm list # Latest version 12 installation nvm install 12.22.6 # Switch to 12.22.6 nvm use 12.22.6 node -v
Add TS / Vue router, etc
Install typescript, vue-router@next , axios, eslint plugin Vue, less and other related plug-ins
npm install axios npm install vue-router@next npm install typescript -D npm install less -D
vite.config.ts
vite.config.js renamed vite config. ts
import { UserConfig } from 'vite' const path = require('path') import vue from '@vitejs/plugin-vue' const config: UserConfig = { plugins: [vue()], optimizeDeps: { include: [ 'axios' ] }, resolve: { alias: { '/@': path.resolve( __dirname, './src' ) }, }, } export default config
router
Create a new router folder under src, and create index ts
import { createRouter, createWebHashHistory } from 'vue-router' const routes = [ { path: '/', name: 'Home', component: () => import('/@/views/Home.vue') } ] export default createRouter({ history: createWebHashHistory(), routes })
views
Add views folder under src
Add home vue
<script setup></script> <template> <div class="div1"> <div class="div2">Coder said</div> </div> </template> <style scoped lang="less"> .div1 { .div2 { font-size: 20px; } } </style>
App. Under src Add < router View > < / router View > to Vue
<script setup> import HelloWorld from "./components/HelloWorld.vue"; </script> <template> <img alt="Vue logo" src="./assets/logo.png" /> <HelloWorld msg="Hello Vue 3 + Vite" /> <router-view></router-view> </template> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
ts configuration
Create a new tsconfig. In the project root directory JSON write related configuration
{ "compilerOptions": { "allowJs": true, "target": "esnext", "module": "esnext", "strict": true, "jsx": "preserve", "importHelpers": true, "moduleResolution": "node", "experimentalDecorators": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "sourceMap": true, "baseUrl": ".", "types": ["vite/client"], "paths": { "/@/*": ["src/*"] }, "lib": ["esnext", "dom", "dom.iterable", "scripthost"] }, "include": [ "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx", "vite.config.ts" ], "exclude": ["node_modules"] }
Create a new types folder under the src directory, where you need to configure the type of ts
shims-vue.d.ts
declare module '*.vue' {}
images.d.ts
declare module '*.svg' declare module '*.png' declare module '*.jpg' declare module '*.jpeg' declare module '*.gif' declare module '*.bmp' declare module '*.tiff'
main.ts
Main under src JS to main ts
import { createApp } from 'vue' import router from '/@/router' import App from '/@/App.vue' const app = createApp(App) app.use(router) app.mount('#app')
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite App</title> </head> <body> <div id="app"></div> <script type="module" src="/src/main.ts"></script> </body> </html>
Mainly
<script type="module" src="/src/main.js"></script>
Change to
<script type="module" src="/src/main.ts"></script>
VUE3 knowledge
setup
vue3 integrates all APIs with setup function; It is executed only once and before the life cycle function, so the current instance this cannot be obtained in the setup function, and the method defined in vue2 writing method cannot be called with this
It will accept two parameters: props and context
// Context to context properties of props component setup(props, context) { return { // Data and methods to bind } }
props props in the setup function is responsive. When a new prop is passed in, it will be updated However, because props is responsive, ES6 deconstruction cannot be used because it will eliminate the responsiveness of props
If you need to deconstruct prop, you can do this safely by using toRefs in the setup function
import { toRefs } from 'vue' setup(props) { const { title } = toRefs(props) console.log(title.value) }
context context exposes the properties of three components: {attrs, slots, emit} It is an ordinary JavaScript object, not responsive, which means you can safely use ES6 to deconstruct the context
The setup method is equivalent to the following
<script setup> </script>
life cycle
Access the component's lifecycle hook by adding on before the lifecycle hook
Because setup runs around the beforeCreate and created lifecycle hooks, there is no need to explicitly define them In other words, any code written in these two hooks should be written directly in the setup function
setup() { onMounted(() => { console.log('Component mount') }) onUnmounted(() => { console.log('Component Uninstallation ') }) onUpdated(() => { console.log('Component update') }) onBeforeUpdate(() => { console.log('Component will be updated') }) onActivated(() => { console.log('keepAlive Component activation') }) onDeactivated(() => { console.log('keepAlive Component inactive') }) return {} }
ref,reactive
ref can wrap a common value into responsive data, which is limited to simple values. Internally, the value is wrapped into an object and processed through defineProperty When passing the value, value and setting value of ref package, you need to pass Value to set You can use ref to get the reference of the component instead of this$ Writing method of refs
reactive handles complex data responsively. Its return value is a proxy object. When it is returned in the setup function, you can use toRefs to structure the proxy object, which is convenient to use in the template
Use the following:
<template> <div> <div> <ul v-for="ele in eleList" :key="ele.id"> <li>{{ ele.name }}</li> </ul> <button @click="addEle">add to</button> </div> <div> <ul v-for="ele in todoList" :key="ele.id"> <li>{{ ele.name }}</li> </ul> <button @click="addTodo">add to</button> </div> </div> </template> <script> import { ref, reactive, toRefs } from 'vue' export default { setup() { // ref const eleList = ref([]) function addEle() { let len = eleList.value.length eleList.value.push({ id: len, name: 'ref Self increasing' + len }) } // reactive const dataObj = reactive({ todoList: [] }) function addTodo() { let len = dataObj.todoList.length dataObj.todoList.push({ id: len, name: 'reactive Self increasing' + len }) } return { eleList, addEle, addTodo, ...toRefs(dataObj) } } } </script>
computed,watch
// computed let sum = computed( () => dataObj.todoList.length + eleList.value.length ) console.log('setup quote computed want.value: ' + sum.value) // watch watch( eleList, (curVal, oldVal) => { console.log('monitor:', curVal, oldVal) }, { deep: true } )
watchEffect
The responsive data referenced in the function is tracked responsively. When the responsive data changes, the function is re executed
const count = ref(0) // When the value of count is modified, a callback is executed const stop = watchEffect(() => console.log(count.value)) // Stop listening stop()
You can also stop listening. watchEffect returns a function that can stop listening after execution
Same as vue2:
const unwatch = this.$watch('say', curVal => {}) // Stop listening unwatch()
useRoute,useRouter
import {useRoute, useRouter} from 'vue-router' const route = useRoute() // Equivalent to this in vue2$ route const router = useRouter() // Equivalent to this in vue2$ router // Route is used to obtain the current route data // router is used for route jump
vuex
When using useStore to obtain the value of the store object from vuex, it should be noted that calculated must be used for packaging, so that the response can be made in the page after the status in vuex is modified
import {useStore} from 'vuex' setup(){ const store = useStore() // Equivalent to this in vue2$ store store.dispatch() // dispatch asynchronous tasks through store object store.commit() // commit modify store data let category = computed(() => store.state.home.currentCagegory return { category } }
Vue Cli
vue ui
Vue3 can be selected for VUE version during installation