Project Dome Address
Gitee.com/Jaction/vit…
vite
cn.vitejs.dev/
First taste of Vue3.0 && Vue3.0 juejin.cn/post/684790…
The installation
Cn. Vitejs. Dev/guide / # scaf…
yarn create @vitejs/app
Copy the code
vite.config.js
import {
defineConfig
} from 'vite'
import vue from '@vitejs/plugin-vue'
const path = require('path')
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: {
// Keys must start and end with a slash
"@": path.resolve(__dirname, "./src"),}},base: '/'.outDir: 'dist'.plugins: [vue()]
})
Copy the code
Environment configuration
The first:
yarn add cross-env -D
"scripts": {
"dev": "cross-env NODE_ENV=development vite"."build": "cross-env NODE_ENV=development vite build"."build": "cross-env NODE_ENV=production vite build"."serve": "vite preview"
},
Copy the code
The second:
"scripts": {
"dev": "vite --mode development"."build:uat": "vite build --mode staging"."build:prd":"vite build --mode production"."serve": "vite preview"
},
Copy the code
# .env.development
NODE_ENV=development
VITE_APP_TITLE=My App (staging)
Copy the code
# .env.staging
NODE_ENV=production
VITE_APP_TITLE=My App (staging)
Copy the code
# .env.production
NODE_ENV=production
VITE_APP_TITLE=My App (staging)
Copy the code
Write VITE_ are a must
use
let title = import.meta.env.VITE_APP_TITLE
Copy the code
The tutorial
The setup function
The Setup function is a new Vue component that is the Composition API entry point
<template>
</template>
<script>
import { setup } from 'vue'
export default {
setup(props, context) {
// Props is the function passed by the parent
// What is context?
We can't use this in setup()
$emit, this.$psrent, this.$refs in vue2.0 do not apply to this.
// Context is a set of these parameters
//context.attrs
//context.slots
//context.parent = this.$psrent
//context.root is equivalent to this in 2.0
//context.emit corresponds to this.$emit in 2.0
//context.refs corresponds to this.$refs in 2.0. }}</script>
<style>
</style>
Copy the code
Route Router/Route parameter Route
import { useRouter, useRoute } from 'vue-router'
import { setup } from 'vue'
export default {
setup(props, context) {
// Get parameters
const route = useRoute()
const { id } = route.query
// Route the hook function
const router = useRouter()
router.beforeEach((to, from) = > {
if (to.meta.index > from.meta.index) {
state.transitionName = 'slide-left' // Swipe left
} else if (to.meta.index < from.meta.index) {
// From secondary to primary
state.transitionName = 'slide-right'
} else {
state.transitionName = ' ' // Level has no transition effect}})const onAdd = () = > {
router.push({ path: '/address-edit'.query: { type: 'add'.from: state.from }})
}
return {
onAdd
}
}
}
Copy the code
Declare the variable ref reactive
Ref and Reactive are both ways of implementing responsive data
- Reactive must pass an object
- ref()
import { setup, Reactive, torefs } from 'vue'
export default {
setup(props, context) {
let count = ref(0) // ref(initial value) None The initial value is set to null
let name = ref('jeff')
const obj = reacttive({
data1: '123'.data2: {}})return{ count, name, ... torefs(obj)// change obj to a responsive ref, otherwise it will not be available in template}}}Copy the code
Dom
<div class="search-wrap" ref="searchWrap">
</div>
import { onMounted } from 'vue'
export default {
setup() {
const searchWrap = ref(null)
onMounted(async() = > {let $screenHeight = document.documentElement.clientHeight
console.log('searchWrap.value', searchWrap.value)
searchWrap.value.style.height = $screenHeight - 100 + 'px'
})
return {
searchWrap
}
}
}
Copy the code
nextTick
export default {
setup() {
nextTick(() = >{})}}Copy the code
Method function
There are no methods in VUe3.0
Methods should also be placed inside return
export default {
setup() {
/ / method
const goToDetail = (item) = > {
router.push({ path: `/product/${item.goodsId}`})}/ / method 2
const tips = () = > {
Toast('Stay tuned');
}
return {
goToDetail
tips
}
}
}
Copy the code
components / props
Same as vue 2.0
import ziComp from './ziComp.vue'
import { setup } from 'vue'
export default {
props: ['val'].// As with 2.0, props can also be used as objectsComponents: {ziComp},// Components is the same as 2.0
setup(props, context) {
const value = ref(props.val)
const goBack = () = > {
if(! props.val) {/ / processing}}return {
value
goBack
}
}
}
Copy the code
Emit events
// Parent component
<s-header :name="' Generate order '" @callback="deleteLocal"></s-header>
// Subcomponent
<div>{{name}}</div>
export detault {
props: {
name: {
type: String.default: ' '
},
back: {
type: String.detault: ' '}},emits: ['callback'].setup(props, ctx) {
const goBack = () = > {
if(! props.name) { router.go(-1)}else {
router.push({ path: props.back })
}
ctx.emit('callback')}return {
goBack
}
}
}
Copy the code
WatchEffect listening props
<template>
<div>{{obj.data1}}</div>
</template>
<script>
import { Reactive, watchEffect } from 'vue'
export default {
props: ['val'].// As with 2.0, props can also be used as objects
setup(props, context) {
watchEffect(() = > { // The first time and the props change will execute the code below
console.log(props.val)
})
}
}
</script>
<style>
</style>
Copy the code
The watch () listener
import { Reactive } from 'vue'
export detault {
setup(props, context) {
let count = ref(0)
let state = reactive({
count2: 1
})
// Listen for the ref type
watch(count, (countNew, preCount)) => { //count new value, preCount old value (count)
console.log(' ') // This is a function that executes after listening for data changes
}
// Listen to reactive
watch(() = > state.count2, (count2New, preCount) = > {
console.log(' ') // This is a function that executes after listening for data changes}, {lazy:false}) // // does not listen on the first creation
}
return{ count countNew, count2New ... toRefs(state) } }Copy the code
Listening for multiple data
import { setup, Reactive } from 'vue'
export default {
setup(props, context) {
let count1 = ref(0)
let name1 = ref(0)
let state = reactive({
count2: 0, name2:'yangy'
)
// Listen to multiple reactive types
watch(
[() = > state.count2, () = >State.name2] ([count, name], [preCount, preName]) => {//count new value, preCount old value
console.log(' ') // This is a function that executes after listening for data changes}, {lazy:false
})// Do not listen on the first creation
// Listen for the ref typeWatch ([count2, name2] ([count, name], [preCount, preName]) => {//count new value, preCount old value
console.log(' ') // This is a function that executes after listening for data changes}, {lazy:false}// do not listen on the first creation)
return{count,... toRefs(state) } } }Copy the code
Computed () Computes attributes
Can be created read-only, and readable and writable
import { setup, Reactive } from 'vue'
export default {
setup(props, context) {
let count = ref(0)
setup () {
const state = reactive({
list: []})const count = ref(0)
const addCount = computed(() = > count.value + 1) // Read only, count. Value changes to increment 1
const addCount2 = computed({
get:() = > count.value + 1.set: (value) = > count.value = value
})
Addcount2. value = 10 // Assignment method
const total = computed(() = > {
let sum = 0
let _list = state.list.filter(item= > state.result.includes(item.cartItemId))
_list.forEach(item= > {
sum += item.goodsCount * item.sellingPrice
})
return sum
})
return {
total
count
addCount
addCount2
}
}
}
}
Copy the code
script setup
<HelloWorld></HelloWorld>
<div @click='doClick'></div>
<script setup>
import HelloWorld from './components/HelloWorld.vue'
import msg from "./components/msg.vue"
// props
import { defineProps, defineEmit } from "vue";// props emit
let props = defineProps({
msg: String});let emit = defineEmit(['callback'])
/ / event
function doClick() {}// Get the context
import {useContext} from 'vue'
// Lifecycle and declarations
import { reactive, onMounted } from "vue";
const msg = ' '
const state = reactive({
mag: "I love my country"
});
onMounted(() = > {
initData()
})
const initData = () = > {
console.log(state.mag)
}
Vue provides getCurrentInstance Proxy in this, Script Setup similar to Vue2.0
import { reactive, onMounted, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const init = () = > {
proxy.$alert('This is a piece of content.'.'Title name', {
confirmButtonText: 'sure'.callback: action= > {
proxy.$message({
type: 'info'.message: `action: ${ action }`}); }}); };// Get the route and route parameters
import { reactive, onMounted, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const init = () = > {
let { id } = proxy.$route.query
}
// Or use useRoute useRouter
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
let { id } = route.query
</script>
Copy the code
Vue3 life cycle
import { onMounted, onUpdated, onUnmounted } from 'vue'
Copy the code
In addition to beforeCreate and Created, there are nine old lifecycle hooks that we can access in our setup method
- onBeforeMount
- onMounted
- onBeforeUpdate
- onUpdated
- onBeforeUnmount
- onUnmounted
- onActivated
- onDeactivated
- onErrorCaptured
We import them and access them in our code
import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onActivated, onDeactivated, onErrorCaptured } from 'vue'
export default {
setup() {
onBeforeMount(() = > {
// ...
})
onMounted(() = > { / / asynchronous
// ...
})
onBeforeUpdate(() = > {
// ...
})
onUpdated(() = > {
// ...
})
onBeforeUnmount(() = > {
// ...
})
onUnmounted(() = > {
// ...
})
onActivated(() = > {
// ...
})
onDeactivated(() = > {
// ...
})
onErrorCaptured(() = > {
// ... })}Copy the code
- beforeCreate -> use setup()
- created -> use setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
Store Status Management
Yran add [email protected]
index.js
state.js
mutation.js
action.js
// index.js
import { createStore } from 'vuex'
import state from './state'
import actions from './actions'
import mutations from './mutations'
export default createStore({
state,
mutations,
actions,
modules: {}})// state.js
export default {
cartCount: 0
}
// mutation.js
export default {
addCart (state, payload) {
state.cartCount = payload.count
}
}
// action.js
import { getCart } from '.. /service/cart'
export default {
async updateCart(ctx) {
const { data } = await getCart()
ctx.commit('addCart', {
count: data.length || 0}}})Copy the code
// main.js
import App from './App.vue'
import store from './store'
const app = createApp(App) // Create an instance
app.use(store)
app.mount('#app')
Copy the code
In the page
import { useStore } from 'vuex'
export detault {
setup() {
const store = useStore()
onMounted(() = > {
store.dispatch('updateCart')})const handleAddCart = async () => {
store.dispatch('updateCart')})return {
handleAddCart
}
}
}
Copy the code
vue-jsx
yarn add @vitejs/plugin-vue-jsx
// vite.config.js
import {
defineConfig
} from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJxs from '@vitejs/plugin-vue-jsx'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJxs()]
})
Copy the code
/ / setup
<script lang='jsx'>
import { ref } from 'vue'
export default {
setup() {
let counter = ref(0)
let onclick = () = > {
counter.value ++
}
return () = > {
<>
<div>comp</div>
<p onClick={onclick}>{counter.value}</p>
</>
}
}
}
</script>
Copy the code
The mock data
yarn add vite-plugin-mock -D
yarn add mockjs -S
// vite.config.js
// vite.config.js
import {
defineConfig
} from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJxs from '@vitejs/plugin-vue-jsx'
import { viteMockServe } from 'vite-plugin-mock';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJxs(), viteMockServe({ supportTs: false})]})Copy the code
Create a mock in the root directory
For example, create a new JS file, such as user.js
export default[{url: '/api/createUser'.method: 'post'.response: ({ body }) = > {
console.log('body>>>>>>>>', body);
return {
code: 0.message: 'ok'.data: null}; }},];Copy the code
role.js
export default[{url: '/api/getRoleById'.method: 'get'.response: ({ query }) = > {
console.log('id>>>>>>>>', query.id);
return {
code: 0.message: 'ok'.data: {
roleName: 'admin'.roleValue: 'admin',}}; }},];Copy the code
vue-router
yarn add vue-router@next -S
router/index.js
import { createRouter, createWebHashHistory } from "vue-router";
const router = createRouter({
history: createWebHashHistory(),
routes: [{path: "/".component: () = > import(".. /views/index.vue"),},]});export default router
Copy the code
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router/index";
const app = createApp(App)
app.use(router)
app.mount("#app");
Copy the code
vuex
yarn add vuex@nest -S
// store/index.js
import { createStore } from 'vuex'
export detault createStore({
state: {
counter: 0
},
mutations: {
add(state)=> {
state.counter ++
}
}
})
Copy the code
import { createApp } from "vue";
import App from "./App.vue";
import store from './store'
const app = createApp(App)
app.use(store)
app.mount("#app");
Copy the code
<p @click="$store.commit('add')">
{{$store.state.counter}}
</p>
Copy the code
Style of management
Install the sass
yarn add sass -D
@import './element-ui.scss'
@import './index.scss'
@import './mixin.scss'
@import './sidebar.scss'
Copy the code
The styles directory holds various styles
element-ui.scss
index.scss
mixin.scss
sidebar.scss
Pack to build
yarn build
Copy the code
Cors errors are reported when the build is packaged and opened directly in the browser
Directly on the server will not report errors, normal operation
Blog.csdn.net/sayyy/artic…
npm install http-server -g
http-server [path] [options]
Copy the code
Go directly to the packaged dist file and execute the http-server command (default 8080)
Directly open http://127.0.0.1:8080/index.html#/