赞
踩
npm install element-plus --save
Volar 支持
如果您使用 Volar,请在 tsconfig.json 中通过 compilerOptions.type 指定全局组件类型。
// tsconfig.json
{
"compilerOptions": {
// ...
"types": ["element-plus/global"]
}
}
全局配置
在引入 Element Plus 时,可以传入一个包含 size 和 zIndex 属性的全局配置对象。 size 用于设置表单组件的默认尺寸,zIndex 用于设置弹出组件的层级,zIndex 的默认值为 2000。
Element Plus 提供了全局配置国际化的配置。
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus, { size: 'small', zIndex: 3000, locale: zhCn })
app.mount('#app')
按需导入(自动导入)
首先需要安装 unplugin-vue-components
和 unplugin-auto-import
这两款插件
npm install -D unplugin-vue-components unplugin-auto-import
然后把下列代码插入到你的 Vite 的配置文件中 (使用 Webpack 可访问官网查看配置)
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
在官网文档对应组件代码,复制粘贴即可
npm install vue-router@4
在项目中的使用流程
也可以从其他文件导入
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }
每个路由都需要映射到一个组件。
// /src/router/route.ts
import Home from '/src/views/home.vue'
import About from '/src/views/about.vue'
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
]
export default routes
routes
配置// /src/router/index.js
import routes from '/src/router/route.ts'
const router = VueRouter.createRouter({
// 配置路由模式
history: VueRouter.createWebHashHistory(), // hash 模式
// history: VueRouter.createWebHistory() // history 模式
routes, // `routes: routes` 的缩写
})
// 路由加载前,使用 router.beforeEach 注册一个全局前置守卫
router.beforeEach((to, from, next) => {
// ...
// 返回 false 以取消导航
return false
})
// 路由加载后,注册全局后置钩子
router.afterEach((to, from, failure) => {
if (!failure) sendToAnalytics(to.fullPath)
// ...
});
// 导出路由
export default router;
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from '/src/router/index.ts';
const app = createApp(App)
//确保 _use_ 路由实例使整个应用支持路由。
app.use(router)
app.mount('#app')
Vue Router 和 组合式 API
在 setup 中访问路由和当前路由
因为我们在 setup 里面没有访问 this,所以我们不能再直接访问 this. r o u t e r 或 t h i s . router 或 this. router或this.route。作为替代,我们使用 useRouter 函数:
import { useRouter, useRoute } from 'vue-router'
export default {
setup() {
const router = useRouter()
const route = useRoute()
function pushWithQuery(query) {
router.push({
name: 'search',
query: {
...route.query,
},
})
}
},
}
route 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该避免监听整个 route 对象。在大多数情况下,你应该直接监听你期望改变的参数。
import { useRoute } from 'vue-router'
import { ref, watch } from 'vue'
export default {
setup() {
const route = useRoute()
const userData = ref()
// 当参数更改时获取用户信息
watch(
() => route.params.id,
async newId => {
userData.value = await fetchUser(newId)
}
)
},
}
请注意,在模板中我们仍然可以访问 $router 和 $route,所以不需要在 setup 中返回 router 或 route。
npm install pinia
// /src/stores/index.ts
// https://pinia.vuejs.org/
import { createPinia } from 'pinia';
// 创建
const pinia = createPinia();
// 导出
export default pinia;
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import pinia from '/@/stores/index';
const app = createApp(App)
// 将根存储其传递给应用程序
app.use(pinia)
app.mount('#app')
// /src/stores/userInfos.ts
import { defineStore } from 'pinia'
// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {
// 定义应用程序的状态
state: (): UserInfosStates => ({
userInfos: {
userName: '',
photo: '',
time: 0,
roles: [],
},
}),
// 定义业务逻辑, Actions 相当于组件中的 methods,
actions: {
setThemeConfig(data: ThemeConfigState) {
this.themeConfig = data;
},
async setUserInfos() {
const userName = Cookies.get('userName');
// ...
},
},
// other options...
})
import { useStore } from '/@/stores/userInfos.ts'
export default {
setup() {
const store = useStore()
const userInfo = store.userInfos
return {
// 您可以返回整个 store 实例以在模板中使用它
store,
}
},
}
request.ts
// request.ts
import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Session } from '/@/utils/storage';
// 1、配置新建一个 axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_API_URL as any,
timeout: 50000,
headers: { 'Content-Type': 'application/json' },
});
// 2、添加请求拦截器
service.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么 token
if (Session.get('token')) {
(<any>config.headers).common['Authorization'] = `${Session.get('token')}`;
}
return config;
},
(error) => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 3、添加响应拦截器
service.interceptors.response.use(
(response) => {
// 对响应数据做点什么
const res = response.data;
if (res.code && res.code !== 0) {
// `token` 过期或者账号已在别处登录
if (res.code === 401 || res.code === 4001) {
Session.clear(); // 清除浏览器全部临时缓存
window.location.href = '/'; // 去登录页
ElMessageBox.alert('你已被登出,请重新登录', '提示', {})
.then(() => {})
.catch(() => {});
}
return Promise.reject(service.interceptors.response);
} else {
return response.data;
}
},
(error) => {
// 对响应错误做点什么
if (error.message.indexOf('timeout') != -1) {
ElMessage.error('网络超时');
} else if (error.message == 'Network Error') {
ElMessage.error('网络连接错误');
} else {
if (error.response.data) ElMessage.error(error.response.statusText);
else ElMessage.error('接口路径找不到');
}
return Promise.reject(error);
}
);
// 4、导出 axios 实例
export default service;
// /api/login.ts
import request from '/@/utils/request';
/**
* 用户登录
* @param params 要传的参数值
* @returns 返回接口数据
* 登录api接口集合
* @method signIn 用户登录
* @method signOut 用户退出登录
*/
export function useLoginApi() {
return {
signIn: (params: object) => {
return request({
url: '/user/signIn',
method: 'post',
data: params,
});
},
signOut: (params: object) => {
return request({
url: '/user/signOut',
method: 'post',
data: params,
});
},
};
}
// ...
useLoginApi(params)
.then(() => {})
.catch(err => {})
.finally(() => {})
// /src/components/echarts/index.vue
/**
* 使用说明:用户只需传入options即可,options请参照官网示例中的options
* 本组件采用整包引入echarts的方法,用于适配所有的echarts控件
* 如需按需加载引入echarts,可参照写法:echarts官网/在打包环境中使用ECharts
*/
<template>
<div ref="chart" class="chart" />
</template>
<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue'
import type { Ref } from 'vue'
import * as echarts from 'echarts'
import { useEventListener } from '@vueuse/core'
const props = defineProps({
option: Object
})
console.log(props)
const chart: Ref<HTMLDivElement|null> = ref(null)
// 在onMounted事件才能拿到真实dom
onMounted(() => {
const dom = chart.value
if (dom) {
let option: any = props.option
// 需要在页面Dom元素加载后再初始化echarts对象
let myChart = echarts.init(dom)
myChart.setOption(option)
// 自动监听加自动销毁
useEventListener('resize', () => myChart.resize())
watch(() => props.option, (newVal: any) => {
myChart.setOption(newVal)
},{deep:true})
}
})
</script>
<style lang="scss" scoped>
.chart {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
}
</style>
// /src/views/home/index.vue
<template>
<div class="box">
<Chart :option="options" />
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive } from 'vue'
import Chart from '/src/components/charts/index.vue'
import option from './modules/option.ts'
export default defineComponent({
components: {
Chart
},
setup() {
const datar = [100,200,300,400,500,600,700,800,900,1000,1100,1200]
const options = reactive(option)
onMounted(() => {
// 模拟异步请求
setTimeout(() => {
options.series[0].data = datar
},1000)
})
return {
options
}
}
})
</script>
<style lang="scss" scoped>
.box {
margin: 10px auto 0;
width: calc(100% - 40px);
height: 400px;
background: var(--system-page-background);
padding: 20px;
overflow: hidden;
}
</style>
// /src/home/modules/option.ts
var xAxis_data = ["01月", "02月", "03月", "04月", "05月", "06月", "07月", "08月", "09月", "10月", "11月", "12月"]
var data_A = [820, 932, 901, 934, 1290, 1330, 1320, 720, 832, 501, 334, 990]
var data_B = [720, 832, 501, 334, 990, 830, 720, 620, 732, 801, 1134, 908]
var data_C = [620, 732, 801, 1134, 908, 930, 920, 820, 932, 901, 934, 1290]
var names = ['2018年实际管理费用', '2019年预算费用', '2020年实际使用预算']
var color = ['#4D8EFF', '#84BFFF', '#FE9D9A']
const option = {
tooltip: {
trigger: 'axis',
},
grid: { //页边距
top: '20%',
left: '1%',
right: '1%',
bottom: '1%',
containLabel: true
},
legend: { // 图例
top: '5%',
// right:'20%',
data: names
},
xAxis: {
type: 'category',
data: xAxis_data,
axisLine: {//坐标线
lineStyle: {
type: 'solid',
color: '#E3E3E3', //轴线的颜色
width: '2' //坐标线的宽度
}
},
axisLabel: {
formatter: '{value}',
},
textStyle: {
fontSize: 12,
fontFamily: 'PingFang SC',
fontWeight: 400,
lineHeight: 17,
color: '#646464', //坐标值的具体的颜色
opacity: 1,
},
axisTick: {
show: false
}
},
yAxis: {
type: 'value',
axisLine: {//线
show: false
},
axisTick: {//刻度
show: false
},
axisLabel: {
formatter: '{value}',
},
textStyle: {
fontSize: 12,
fontFamily: 'PingFang SC',
fontWeight: 400,
lineHeight: 17,
color: '#979A9F', //坐标值的具体的颜色
opacity: 1,
},
splitLine: {
lineStyle: {
type: 'dashed',
width: 2,
color: ['#E3E3E3'] //分割线的颜色
// color: ['#5d5d5d'] //分割线的颜色
}
}
},
series: [
{
type: 'bar',
name: names[1],
data: data_A,
symbolSize: 9, //设置拐点大小
itemStyle: {
color: color[0]
},
lineStyle: {
width: 2,
type: 'solid' //'dotted'虚线 'solid'实线
}
}, {
type: 'bar',
name: names[2],
data: data_B,
symbolSize: 9, //设置拐点大小
itemStyle: {
color: color[1]
},
lineStyle: {
width: 2,
type: 'solid' //'dotted'虚线 'solid'实线
}
}, {
type: 'line',
name: names[0],
data: data_C,
symbolSize: 9, //设置拐点大小
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: '#fe9d9a66' // 0% 处的颜色
}, {
offset: 1, color: '#fe9d9a00' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
color: color[2], //设置颜色
lineStyle: {
width: 2,
type: 'solid' //'dotted'虚线 'solid'实线
}
},
]
}
export default option
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。