环境准备
确保系统已安装npm
一、创建
1、cdm 进入项目目录,执行
vue create allin-design
2、选择vue3,回车,等待加载完成
3、根据提示执行
cd allin-design
yarn serve
4、项目启动后,根据提示进入Vue初始界面
二、安装插件
1、sass
安装
VueCLI4版本用的webpack版本依赖和sass-loader用的webpack依赖冲突,需要更新依赖或者降级sass-loader版本
npm install -D sass-loader@^10 sass
2、vue-router
安装
npm install vue-router
封装
在src 目录下新建 router/index.js
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
//按需添加
{
path: '/',
redirect: '/home'
},
{
path: '/home',
name: 'home',
component: () => import('../views/Home.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),// hash模式:createWebHashHistory,history模式:createWebHistory
routes,
});
export default router
main.js挂载
import router from './router/index'
const app = createApp(App)
app.use(router)
app.mount('#app')
测试
修改App.vue,template中添加<router-view></router-view>
在src 目录下新建 views/Home.vue
<template>
<div class="content">hello login !</div>
</template>
<script>
</script>
<style lang="scss">
.content{
color: aqua;
font-size: 20px;
}
</style>
返回浏览器,底部显示"hello login !",路径被修改为"http://localhost:8080/#/home"
3、# Vue Unicons
安装
npm i vue-unicons
使用
main.js
import Unicon from 'vue-unicons'
import { uniAngry } from 'vue-unicons/dist/icons'
Unicon.add([uniAngry])
Home.vue添加
<unicon name="angry" fill="limegreen"></unicon>
效果
4、自定义主题切换
在src 目录下新建 assets/scss/_theme.scss
$themes: (
light: (
color: #000000,
bg_color: #FFFFFF,
border_color: #000000
),
dark: (
color: #EE6666,
bg_color: #9DD3E8,
border_color: #879BD7
)
);
在src 目录下新建 assets/scss/_mixin.scss
@import '_themes.scss';
//生成对应元素的主题样式代码
@mixin theme {
@each $themes-key, $themes-map in $themes {
$themes-map: $themes-map !global;
[data-theme=#{$themes-key}] & {
@content;
}
}
}
//获取对应的主题数据
@function setTheme($key){
@return map-get($themes-map, $key);
};
修改APP.vue,点击切换主题查看效果
<template>
<div class="container">
<img alt="Vue logo" src="./assets/logo.png">
<router-view></router-view>
<button @click="themeChange">切换主题</button>
</div>
</template>
<script>
import {reactive, toRefs,onBeforeMount} from 'vue'
export default {
name: 'App',
setup() {
const state = reactive({
theme:'light'
})
const themeChange = ()=>{
state.theme = state.theme == 'dark'? 'light':'dark';
window.document.body.setAttribute("data-theme", state.theme);
}
onBeforeMount(() => {
window.document.body.setAttribute("data-theme", state.theme);
})
return {
...toRefs(state),
themeChange
}
}
}
</script>
<style lang="scss">
@import '~@/assets/scss/_mixin.scss';
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
body,html {
padding: 0;
margin: 0;
box-sizing: border-box;
height: 100vh;
width: 100vw;
}
.container{
height: 100vh;
width: 100vw;
box-sizing: border-box;
transition: color,background-color 0.5s;
@include theme{
color: setTheme('color');
background-color: setTheme('bg_color');
}
}
</style>
5、ElementPlus
“element-plus.gitee.io/zh-CN/”
安装
yarn add element-plus
完整引入,按需引入参考官方文档
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
使用
直接使用
<el-button type="primary">Primary</el-button>
使用useDark主题切换
参考官网
<template>
<div class="header-slider-btn" @click="toggleDark()">
<unicon name="bars"></unicon>
</div>
</template>
<script>
import { useDark, useToggle } from '@vueuse/core'
export default {
name: 'Header',
setup() {
const isDark = useDark()
const toggleDark = useToggle(isDark)
return {
isDark,
toggleDark
}
}
}
</script>
修改暗黑主题样式
新建样式文件 src\styles\element\_dark.css 在mian.js 引入
在文件中修改暗黑主题样式,直接将element-plus/theme-chalk/dark/css-vars.css中的内容复制到_dark.css,然后根据需要修改,后期发现有时候修改的变量不生效,改为通过scss修改,参考 https://element-plus.gitee.io/zh-CN/guide/dark-mode.html#%E9%80%9A%E8%BF%87-scss
修改默认主题样式
新建样式文件 src\styles\element\_index.css 在mian.js 引入,删除import 'element-plus/dist/index.css'
修改默认主题样式,将@import 'element-plus/theme-chalk/src/index.scss';在_index.scss末尾引入,否则会影响其它样式,参考 https://element-plus.gitee.io/zh-CN/guide/theming.html#%E9%80%9A%E8%BF%87-scss-%E5%8F%98%E9%87%8F
修改样式示例
// element plus默认定义
// node_modules/element-plus/theme-chalk/src/common/var.scss
$colors: () !default;
$colors: map.deep-merge(
(
'white': #ffffff,
'black': #000000,
'primary': (
'base': #409eff,
),
'success': (
'base': #67c23a,
),
'warning': (
'base': #e6a23c,
),
'danger': (
'base': #f56c6c,
),
'error': (
'base': #f56c6c,
),
'info': (
'base': #909399,
),
),
$colors
);
需要修改 primary 为 #727cf5
// src/styles/element/_index.scss
/* 只需要重写你需要的即可 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
'base': #727cf5,
),
),
);
修改某个颜色变量 --el-menu-hover-bg-color
在var.scss搜索menu hover-bg-color,找到
在之前的_index.scss中加入
// src/styles/element/_index.scss
/* 只需要重写你需要的即可 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': (
'base': #727cf5,
),
),
$menu: (
'hover-bg-color': #727cf5,
)
);
新增的样式需要自己写入css/scss
插件汉化
import 'element-plus/dist/index.css'
app.use(ElementPlus, {
locale: zhCn,
})
ElementPlus icon
安装
参考官网
使用
Tips:全局注册后,图标按钮需要将icon前冒号去掉,否则不显示,与官网示例不同
<el-button icon="search"></el-button>
7、echarts
安装
https://github.com/ecomfe/vue-echarts#readme
npm install echarts vue-echarts
使用
参考 https://github.com/ecomfe/vue-echarts#sfc-example
主题修改
添加属性theme,绑定变量,例:
:theme="theme? 'dark':'light'"
自适应窗口
参考 https://github.com/ecomfe/vue-echarts#props 添加属性 autoresize
词云
npm install echarts-wordcloud
import 'echarts-wordcloud'
//template
<div id="main" class="bar"></div>
//script
import 'echarts-wordcloud';
const initWorldCloud = ()=>{
const map = document.getElementById('main')
const chart = echarts.init(map);
const option = {
tooltip: {},
series: [ {
type: 'wordCloud',
gridSize: 2,
sizeRange: [12, 50],
rotationRange: [-90, 90],
shape: 'pentagon',
width: '80%',
height: '80%',
drawOutOfBound: true,
textStyle: {
color: function () {
return 'rgb(' + [
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
Math.round(Math.random() * 250)
].join(',') + ')';
}
},
emphasis: {
textStyle: {
shadowBlur: 10,
shadowColor: '#333',
color: 'red'
}
},
data: [
{
name: 'Sam S Club',
value: 10000,
// textStyle: {
// color: 'white'
// },
// emphasis: {
// textStyle: {
// color: 'red'
// }
// }
},
{
name: 'Macys',
value: 6181
}
]
} ]
};
chart.setOption(option);
}
onMounted(()=>{
initWorldCloud()
})
8、FullCalendar 日历组件
安装
https://github.com/fullcalendar/fullcalendar-vue/tree/vue3
npm install @fullcalendar/vue3
npm install @fullcalendar/core
npm install @fullcalendar/daygrid
npm install @fullcalendar/timegrid
npm install @fullcalendar/list
npm install @fullcalendar/interaction
使用
https://fullcalendar.io/docs
<template>
<div class="content">
<el-card>
<FullCalendar :options="calendarOptions" />
</el-card>
</div>
</template>
<script>
import '@fullcalendar/core/vdom' // solves problem with Vite
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
export default{
components:{
FullCalendar
},
setup() {
const calendarOptions = {
plugins: [ dayGridPlugin, interactionPlugin ],
initialView: 'dayGridMonth'
}
return {
calendarOptions
}
}
}
</script>
汉化
import zh from '@fullcalendar/core/locales/zh-cn';
const calendarOptions = {
plugins: [ dayGridPlugin, interactionPlugin ],
initialView: 'dayGridMonth',
locale: zh
}
修改样式
找到文件这两个文件,找到类名,修改样式保存
.\node_modules\@fullcalendar\common\main.css
.\node_modules\@fullcalendar\daygrid\main.css
模式切换,写到main.css中,修改变量的值
html.dark{
--fc-border-color:#464f5b;
}
9、vuex
安装
https://vuex.vuejs.org/zh/installation.html#yarn
yarn add vuex@next --save
创建 src/store 文件夹 添加 src/store/index.js
import { createStore } from 'vuex'
import user from './modules/user'
import getters from './getters'
const store = createStore({
modules: {
user
},
getters
})
export default store
添加 src/store/getters.js
const getters = {
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permissions: state => state.user.permissions,
}
export default getters
添加 src/store/modules/user.js
import { createStore } from 'vuex'
import {login} from '@/api/login'
const user = {
state: {
token: getToken(),
name: '',
avatar: '',
roles: [],
permissions: []
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_EXPIRES_IN: (state, time) => {
state.expires_in = time
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
}
},
actions: {
// 登录
Login({commit}, userInfo) {
return new Promise((resolve, reject) => {
//请求登录
login(userInfo).then(res => {
resolve()
}).catch(error => {
reject(error)
})
})
}
}
}
export default user
挂载
main.js
import store from './store'
app.use(store)
使用
import store from '@/store'
store.dispatch("Login", ruleForm).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
});
10、pinia
安装
npm install pinia
使用
https://pinia.web3doc.top/core-concepts/
11、unplugin-auto-import
可自动导入 Vite、Webpack、Rollup 和 esbuild 的 API
https://www.npmjs.com/package/unplugin-auto-import
使用
// vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [
AutoImport({ /* options */ }),
],
})
12、tinymce self-localhosted
下载
引入
解压到public路径下,将汉化包langs也解压到该文件夹
修改index.html ,添加
<script src="/tinymce/tinymce.min.js"></script>
<template>
<div>
<editor
:init="init"
/>
</div>
</template>
<script>
import Editor from '@tinymce/tinymce-vue'
import {uploadImg} from '@/api/uploadImg'
export default {
name: 'app',
components: {
'editor': Editor
},
setup(){
const init = ({
language_url: '/tinymce/langs/zh-Hans.js',
language: 'zh-Hans',
skin: 'tinymce-5',
plugins: 'image table code',
theme:'silver',
branding: false,
images_upload_base_path:import.meta.env.VITE_APP_BASE_API,
images_upload_handler: function (blobInfo, progress) {
//自定义图片上传
return new Promise(resolve => {
let formData = new FormData();
formData.append('file', blobInfo.blob());
uploadImg(formData).then(res => {
resolve(res.data.url.replace('127.0.0.1','192.168.1.227'))
})
})
}
// toolbar: 'code undo redo restoredraft | image | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
// styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
// table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | bdmap indent2em lineheight formatpainter axupimgs',
})
return{
init
}
}
}
</script>
13、svg-sprite-loader
安装
npm install svg-sprite-loader
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
...
chainWebpack(config){
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end();
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
})
.end()
}
}
新建svg-icon组件
<template>
<svg :class="svgClass" aria-hidden="true" :width="size" :height="size">
<use :xlink:href="symbolId" :fill="color"/>
</svg>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
iconName: {
type: String,
required: true
},
color: {
type: String
},
className:{
type: String
},
size:{
type: Number
}
})
const symbolId = computed(() => `#icon-${props.iconName}`)
const svgClass = computed(() => {
if (props.className) {
return `svg-icon ${props.className}`
}
return 'svg-icon'
})
const size = computed(() => {
if (props.size) {
return `${props.size}px`
}
return '1rem'
})
</script>
<style lang="scss" scoped>
.sub-el-icon,
.nav-icon {
display: inline-block;
font-size: 15px;
margin-right: 12px;
position: relative;
}
.svg-icon {
position: relative;
fill: currentColor;
vertical-align: -2px;
overflow: visible;
}
</style>
新建src/icons目录以及icons/index.js文件 icons/svg 目录存放svg文件
import SvgIcon from '@/components/SvgIcon'
const svgRequired = require.context('./svg', false, /\.svg$/)
svgRequired.keys().forEach((item) => svgRequired(item))
export default (app) => {
app.component('svg-icon', SvgIcon)
}
main.js 导入
import SvgIcon from '@/icons'
SvgIcon(app)
使用
<svg-icon :iconName="item.meta" :size="16" />