最近搭建了一个疫情车辆管理系统,采用的是vue3
+Arco Design
+vite
, 使用起来很不错,特别vite
也太快了吧,本文主要记录下vue3
、vite
.
Vite创建应用(vue/react)
npm create vite@latest
Vite配置环境变量
新建环境变量文件
// 开发环境
.env.development
# 必须指定
VITE_MODE_NAME=development
VITE_LOCAL_BASE_API = 'http://192.168.0.155:8090'
// 生产环境
.env.production
# 必须指定
VITE_MODE_NAME=production
VITE_LOCAL_BASE_API = 'http://192.168.0.155:8090'
在Axios
等文件中引用
import.meta.env.VITE_LOCAL_BASE_API
在vite.config.js
中引用
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, __dirname)
return {
server: {
host: '0.0.0.0',
port: '8090',
proxy: {
'/api': {
target: env.VUE_APP_LOCAL_BASE_API,
rewrite: (path) => path.replace(/^api/, '')
}
}
}
}
})
Vite
配置别名
// vite.config.js
import { resolve } from 'path'
resolve: {
alias: [{
find: '@',
replacement: resolve(__dirname, 'src')
}]
},
Vite配置局域网访问
在vite.config.js
中配置server
// vite.config.js
server: {
host: '0.0.0.0',
port: '8090',
}
vite更多配置项文档
vue3使用scss
安装
npm i sass -D
配置vite.config.js
// 全局css
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "./src/assets/reset.scss";`,
}
}
}
此时 全局css会不生效
解决办法:
在app.vue
中 随便写个样式即可, lang=scss
<style lang="scss">
a{
// do something
}
</style>
Vue3使用JSX
安装@vitejs/plugin-vue-jsx
npm i @vitejs/plugin-vue-jsx -D
配置vite.config.js
import vueJsx from '@vitejs/plugin-vue-jsx'
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, __dirname)
return {
plugins: [vue(), vueJsx({})],
}
})
使用:
script 标签一定要加
lang="jsx"
<script setup lang="jsx">
render: () => {
return (
<>
<dx-button status="warning" type="text">编辑</dx-button>
<dx-button status="danger" type="text">删除</dx-button>
</>
)
}
</script>
router
基本和vue2中使用区别不大
安装
npm i vue-router@4 -S
配置 router/index.js
import { createRouter, createWebHistory } from "vue-router";
import Layout from "../layout/index.vue";
const routes = [
{
path: "/",
redirect: 'home',
component: Layout,
children: [
{
path: '/home',
name: 'home',
component: () => import('../views/index.vue'),
meta: {
title: "首页"
}
},
{
path: '/404',
name: '404',
component: () => import('../views/error/404.vue'),
meta: {
title : '404 not found'
}
},
]
},
]
export default createRouter({
history: createWebHistory(),
routes,
});
挂载到main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './routers';
const app = createApp(App)
app.use(router)
app.mount("#app")
配置挂载点:
app.vue
<template>
<router-view />
</template>
layout.vue
<template>
<header></header>
<main>
<router-view />
</main>
</template>
router的使用:
跳转页面:
import { useRouter } from "vue-router";
const router = useRouter()
router.push('/')
获取router
参数
import { useRoute } from "vue-router";
const route = useRoute()
console.log(route.query)
console.log(route.matched)
vuex
安装
npm install vuex@next --save
配置store/index.js
import { createStore } from "vuex";
export default createStore({
state() {
return {
user: {},
};
},
mutations: {
SAVE_USER: (state, user) => {
state.user = user
},
},
actions: {
login({commit}, res) {
commit('SAVE_USER', res.user)
},
}
挂载到main.js
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';
const app = createApp(App)
app.use(store)
app.mount("#app")
使用
和在vue2
中使用一致,没区别, vue3
中据说推荐使用pinia
获取state参数
import store from "../store";
const user = store.state.user;
使用mutations
import store from "../store";
store.commit('SAVE_USER', user)
调用actions
import store from "../store";
store.dispatch("login");
Axios
Axios
在vue3
中使用和vue2
无异
vue3
使用echarts
安装
npm i echarts -S
使用
<template>
<div id="histogramChart"></div>
</template>
<script setup>
import * as echarts from 'echarts'
import {onMounted, nextTick} from "vue";
onMounted(() => { // 需要获取到element,所以是onMounted的Hook
nextTick(() => {
let myChart = echarts.init(document.getElementById("histogramChart"));
myChart.setOption({
legend: {},
grid: {
left: '1%',
right: '13%',
bottom: '3%',
containLabel: true
},
tooltip: {},
dataset: {
source: [
['product', '中高风险车辆', '营运车辆', '危险品车辆'],
['周一', 43.3, 85.8, 93.7],
['周二', 83.1, 73.4, 55.1],
['周三', 86.4, 65.2, 82.5],
['周四', 66, 53.9, 80],
['周五', 72.4, 60, 39.1],
['周六', 55, 69, 39.1],
['周日', 74, 59, 38],
]
},
xAxis: { type: 'category' },
yAxis: {},
series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }]
});
window.onresize = function () { // 自适应大小
myChart.resize();
};
})
</script>
响应式原理
Vue2-defineProperty
<script>
// 源数据
let person = {
name: 'san',
age: 18
}
// 模拟vue2 实现响应式
let p = {} // 先定义一个空对象
// ‘name’:操作的属性名, 多个属性时循环添加defineProperty
Object.defineProperty(p, 'name', {
configgurable:true,
get() {
return person.name
},
set(value) {
consoloe.log(`修改name属性`,to update page)
person.name = value
}
})
</script>
Vue3-Proxy
<script>
// 源数据
let person = {
name: 'san',
age: 18
}
// 模拟vue3 实现响应式
// new Proxy(代理的源数据, {监听操作:get, set, deleteProperty})
const p = new Proxy(person, {
// 读取p某个数据时
get(target, propName) {
console.log(`读取p的${propName}属性`)
// return target[propName]
return Reflect.get(target, propName)
},
// 修改 追加属性时候调用
set(target, propName, value) {
consoloe.log(`修改p的${propName}属性`,to update page)
//target[propName] = value
Reflect.set(target, propName, value)
},
// 删除p某个数据调用
deleteProperty(target, propName) {
console.log(`删除p的${propName}`,to update page)
// return delete target[propName]
return Reflect.deleteProperty(target, propName)
}
})
</script>
参考视频地址:
异步引入组件 与 Suspense
猜想:作用于 在数据未加载完时候,类似于骨架屏显示
<template>
<Suspense>
<template v-slot:default>
<Child />
</template>
<template v-slot:fallback>
加载中,稍后
</template>
</Suspense>
</template>
import { defineAsyncComponent } from 'vue'
const Child = defineAsyncComponent(() => import('./components/chid.vue'))
teleport
猜想; 用于全局模态框类似情况, 将在嵌套子组件的html 传送到指定元素下显示
// to: 要传送的位置,支持 html, css, id选择器,【html, body, div, .css, #id】
<teleport to="html">
// 模态框
</teleport>
才疏学浅,以上只是在搭建系统中遇到的,如有错误,还请赐教。
原文地址: https://blog.zhanghaoran.ren/article/html/vue3ChuBuShiYongBiJi.html
2022.2.21
2022.3.3 二次更新:依赖包版本、vite相关配置
2022.3.4 三次更新:vue响应式原理, vue3新增API:teleport
,Suspense