Allin-design

231 阅读4分钟

环境准备

确保系统已安装npm

一、创建

1、cdm 进入项目目录,执行

vue create allin-design

2、选择vue3,回车,等待加载完成

3、根据提示执行

cd allin-design  
yarn serve

4、项目启动后,根据提示进入Vue初始界面

二、安装插件

1、sass

安装

image.png

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

安装

"github.com/antonreshet…"

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>

效果

image.png

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,找到

image.png

在之前的_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

下载

www.tiny.cloud/get-tiny/

image.png

引入

解压到public路径下,将汉化包langs也解压到该文件夹

image.png

修改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" />