VUE3
一、项目初始化
npm init vite@latest 项目名 -- --template vue-ts
cd 项目名
npm install
npm run dev
vue3生命周期函数:
-
setup():开始创建组件之前,在 beforeCreate 和 created 之前执行,创建的是 data 和 method -
onBeforeMount() : 组件挂载到节点上之前执行的函数 -
onMounted() : 组件挂载完成后执行的函数 -
onBeforeUpdate(): 组件更新之前执行的函数 -
onUpdated(): 组件更新完成之后执行的函数 -
onBeforeUnmount(): 组件卸载之前执行的函数 -
onUnmounted(): 组件卸载完成后执行的函数 -
onActivated(): 被包含在 中的组件,会多出两个生命周期钩子函数,被激活时执行 -
onDeactivated(): 比如从 A 组件,切换到 B 组件,A 组件消失时执行 -
onErrorCaptured(): 当捕获一个来自子孙组件的异常时激活钩子函数
二、安装相关依赖并配置
vite
npm install @types/node -D
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import * as path from "path"
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.join(__dirname, 'src'),
"@assets": path.join(__dirname, "src/assets"),
"@components": path.join(__dirname, "src/components"),
"@views": path.join(__dirname, "src/views"),
"@utils": path.join(__dirname, "src/utils")
}
},
server: {
host: '127.0.0.1',
port: 3000,
open: true,
proxy: {
'/api': {
target: '你的服务器地址',
changeOrigin: true,
rewrite: (path:string) => path.replace(/^\/api/, '')
}
}
}
});
解决打包错误 添加--skipLibCheck
{
"script": {
"build": "vue-tsc --noEmit --skipLibCheck && vite build"
}
}
typescript
{
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true,
"baseUrl": ".",
"paths": {
"@": [
"./src"
],
"@/*": [
"./src/*"
]
},
"exclude": [
"node_modules"
]
}
eslint
npm install eslint eslint-plugin-vue -D
module.exports = {
root: true,
parserOptions: {
sourceType: "module"
},
parser: "vue-eslint-parser",
extends: [
'plugin:vue/vue3-essential',
'plugin:vue/vue3-strongly-recommended',
'plugin:vue/vue3-recommended'
],
env: {
browser: true,
node: true,
es6: true
},
rules: {
'no-console': 'off',
'comma-dangle': [2, 'never']
}
}
global.scss
- 新建
src\assets\css\global.scss 样式文件
/*全局公共样式表*/
html, body, #app {
margin: 0;
padding: 0;
height: 100%;
a {
text-decoration: none;
color: #333;
}
ul, li {
list-style: none;
}
}
/*设置滚动条样式*/
::-webkit-scrollbar {
width: 5px;
}
/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {
border-radius: 10px;
background-color: rgba(0, 0, 0, 0.1);
}
/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(26, 25, 25, 0.3);
background-color: rgba(0, 0, 0, 0.1);
}
/*设置进度条颜色 不配置时为默认颜色*/
#nprogress .bar {
/*background: rgba(41, 236, 127, 0.5) !important;*/
}
// App.vue
<style>
@import "assets/style/global";
</style>
animate.css
npm install animate.css --save
@import 'animate.css';
通过class使用样式
<h1 class="animate__animated animate__bounce">An animated element</h1>
reset.css
npm install reset.css --save
// App.vue
<style>
@import "reset.css";
</style>
less/sass
less
npm install less less-loader -D
sass
npm install sass sass-loader -D
<style scoped lang="less">
</style>
? 或者
<style scoped lang="sass">
</style>
element plus
官网:Element Plus 组件:组件使用
npm install element-plus --save
完整引用
文件大小占用较大,但是使用时会更加方便
import {App} from 'vue'
import ElementPlus from "element-plus"
import 'element-plus/dist/index.css'
import locale from 'element-plus/es/locale/lang/zh-cn'
import * as Icons from '@element-plus/icons-vue'
export default {
install(app: App) {
app.use(ElementPlus, {
locale,
size: 'small' || 'middle'
})
Object.keys(Icons).forEach((key: string) => {
app.component(key, Icons[key as keyof typeof Icons]);
})
}
}
import {createApp} from 'vue'
import App from './App.vue'
import ElementPlus from "./plugins/element-plus";
const app = createApp(App)
app.use(ElementPlus)
.mount('#app')
按需引用
自动导入(推荐)
首先你需要安装unplugin-vue-components 和 unplugin-auto-import 这两款插件
npm install unplugin-vue-components unplugin-auto-import -D
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default {
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}
手动引入
npm install unplugin-element-plus --save
import ElementPlus from 'unplugin-element-plus/vite'
export default {
plugins: [ElementPlus()],
}
<template>
<el-button type="primary">测试</el-button>
</template>
<script setup lang="ts">
import { ElButton } from 'element-plus'
</script>
图标使用
npm install @element-plus/icons-vue
<template>
<div>
<el-icon :size="size" :color="color">
<edit />
</el-icon>
<!-- Or use it independently without derive attributes from parent -->
<edit />
</div>
</template>
<script setup lang="ts">
import {Edit} from '@element-plus/icons-vue'
</script>
import {createApp} from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as Icons from '@element-plus/icons-vue'
const app = createApp(App);
app.use(ElementPlus)
.mount('#app')
Object.keys(Icons).forEach((key) => {
app.component(key, Icons[key as keyof typeof Icons]);
})
axios
npm install axios vue-axios --save
import axios, {AxiosRequestConfig, AxiosResponse} from "axios";
import VueAxios from "vue-axios"
axios.create({
baseURL: '服务器地址',
timeout: 6 * 1000,
withCredentials: true,
})
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.interceptors.request.use(
(request: AxiosRequestConfig) => {
console.log("请求成功");
return request;
}, ((error: any) => {
console.log(error);
return Promise.reject(error);
}))
axios.interceptors.response.use(
(response: AxiosResponse) => {
console.log("响应成功");
return response;
}, ((error: any) => {
console.log(error);
return Promise.reject(error);
}))
export {axios, VueAxios}
import {createApp} from 'vue'
import App from './App.vue';
import {axios, VueAxios} from './utils/axios'
const app = createApp(App)
app.use(VueAxios, axios)
.mount('#app')
<script setup lang="ts">
import {ref} from "vue";
import axios from "../utils/axios";
const text = ref('')
function test() {
axios.get('/api/test').then(res => {
if (res.data !== null) {
text.value = "连接成功";
}
}).catch(err => {
text.value = "连接失败";
})
}
</script>
<template>
<button @click="test">测试Axios</button>
<p>{{ text }}</p>
</template>
<style scoped lang="less">
p {
color: red;
}
</style>
js-cookie
npm文档:js-cookie
npm install @types/js-cookie --save
import cookie from 'js-cookie'
export const getCookie = (name: string): string => cookie.get(name)
export const getCookieAll = (): string => cookie.get()
export const setCookie = (name: string, value: any) => cookie.set(name, value)
export const setCookieDate = (name: string, value: any, day: number) => cookie.set(name, value, {expires: day})
export const removeCookie = (name: string) => cookie.remove(name)
解决引用报红问题
declare module 'js-cookie'
import cookie from 'js-cookie'
cookie.set('name', 'value')
cookie.set('name', 'value', { expires: 7 })
cookies.set('name', 'value', { expires: 7, path: '' })
cookies.get()
cookies.get('name')
cookies.remove('name')
cookies.remove('name', { path: '' })
js-base64
详细使用:js-base64
npm install @types/js-base64 --save
import { Base64 } from 'js-base64'
vue-router
npm install vue-router@4
import {createRouter, createWebHistory, RouteRecordRaw} from 'vue-router'
const routes: Array<RouteRecordRaw> = []
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
import {createApp} from 'vue'
import App from './App.vue'
import router from './router'
createApp(App)
.use(router)
.mount('#app')
nProgress
npm install nprogress --save
由于需要使用到router ,所以我这里直接配置在router.ts 中,也可以单独写配置文件
import {createRouter, createWebHistory} from 'vue-router'
import nProgress from 'nprogress'
import 'nprogress/nprogress.css'
router.beforeEach((to, from, next) => {
nProgress.start()
next()
})
router.afterEach(() => {
nProgress.done()
})
nProgress.configure({
ease: 'linear',
speed: 500,
showSpinner: true
})
export default router;
// App.vue
<style>
/*设置进度条颜色 不配置时为默认颜色*/
#nprogress .bar {
background: red !important;
}
</style>
解决引用错误问题:
declare module 'nprogress'
pinia
npm install pinia
import {defineStore} from "pinia";
interface storeTypes {
}
export const useMainStore = defineStore('main', {
state: (): storeTypes => {
return {}
},
getters: {},
actions: {}
});
import {createApp} from 'vue'
import App from './App.vue';
import {createPinia} from "pinia"
createApp(App)
.use(createPinia())
.mount('#app');
markdown
v-md-editor(推荐)
官方文档:v-md-editor
npm install @kangc/v-md-editor@next --save
npm install prismjs --save
npm install vite-plugin-prismjs -D
- 解决在 vue3 + typescript 中使用报错?
declare module 'nprogress';
declare module '@kangc/v-md-editor';
declare module '@kangc/v-md-editor/*';
declare module 'prismjs';
import { defineConfig } from 'vite';
import prismjs from 'vite-plugin-prismjs';
export default defineConfig({
plugins: [
prismjs({
languages: 'all',
plugins: ["line-numbers"],
theme: "twilight",
css: true
}
],
});
import VueMarkdownEditor from '@kangc/v-md-editor';
import '@kangc/v-md-editor/lib/style/base-editor.css';
import vuepressTheme from '@kangc/v-md-editor/lib/theme/vuepress.js';
import '@kangc/v-md-editor/lib/theme/style/vuepress.css';
import createMermaidPlugin from '@kangc/v-md-editor/lib/plugins/mermaid/cdn';
import '@kangc/v-md-editor/lib/plugins/mermaid/mermaid.css';
import createLineNumbertPlugin from '@kangc/v-md-editor/lib/plugins/line-number/index';
import createKatexPlugin from '@kangc/v-md-editor/lib/plugins/katex/cdn';
import createEmojiPlugin from '@kangc/v-md-editor/lib/plugins/emoji/index';
import '@kangc/v-md-editor/lib/plugins/emoji/emoji.css';
import createTipPlugin from '@kangc/v-md-editor/lib/plugins/tip/index';
import '@kangc/v-md-editor/lib/plugins/tip/tip.css';
import createTodoListPlugin from '@kangc/v-md-editor/lib/plugins/todo-list/index';
import '@kangc/v-md-editor/lib/plugins/todo-list/todo-list.css';
import createCopyCodePlugin from '@kangc/v-md-editor/lib/plugins/copy-code/index';
import '@kangc/v-md-editor/lib/plugins/copy-code/copy-code.css';
import createHighlightLinesPlugin from '@kangc/v-md-editor/lib/plugins/highlight-lines/index';
import '@kangc/v-md-editor/lib/plugins/highlight-lines/highlight-lines.css';
import Prism from 'prismjs';
import 'prismjs/components/prism-json';
VueMarkdownEditor
.use(createHighlightLinesPlugin())
.use(createCopyCodePlugin())
.use(createLineNumbertPlugin())
.use(createTipPlugin())
.use(createTodoListPlugin())
.use(createKatexPlugin())
.use(createEmojiPlugin())
.use(vuepressTheme, {
Prism
})
export default VueMarkdownEditor
import {createApp} from 'vue'
import App from './App.vue'
import VueMarkdownEditor from './utils/v-md-editor'
createApp(App)
.use(VueMarkdownEditor)
.mount('#app')
<script setup lang="ts">
import {reactive} from "vue";
const Options = reactive({
// 双向绑定数据
content: '# 你好世界',
// 编辑器模式 默认editable
mode: [
{name: '仅编辑模式', value: 'edit'},
{name: '仅预览模式', value: 'preview'},
{name: '编辑与预览模式', value: 'editable'}
],
// 正常模式下编辑器的高度
height: '400px',
// 编辑和预览时制表符的长度 默认2
tabSize: 2,
// 目录导航是否在右侧 默认false
tocNavPositionRight: false,
// 是否默认显示目录导航 默认false
defaultShowToc: false,
// 提示文本
placeholder: '记录下你的想法吧!',
// 编辑器加载完是否自动聚焦 默认false
autofocus: true,
// 是否默认开启全屏
defaultFullscreen: false,
// 目录导航生成时包含的标题。默认[2,3]
includeLevel: [1, 2, 3, 4, 5],
// 左侧工具栏 默认 undo redo clear | h bold italic strikethrough quote | ul ol table hr | link image code | save
leftToolbar: 'h bold italic strikethrough quote | ul ol table hr | link image code |undo redo clear | save',
// 哟测工具栏 默认 preview toc sync-scroll fullscreen
rightToolbar: 'preview toc sync-scroll fullscreen',
// 自定义工具栏
toolbar: {},
// toolbar内置配置
toolbarConfig: {
'image-link': {
// 是否在插入图片链接的时候默认带上width height 属性,默认值:false
insertWithSize: false
}
}
})
</script>
<template>
<v-md-editor
v-model="Options.content"
:mode="Options.mode[2].value"
:height="Options.height"
:tab-size="Options.tabSize"
:toc-nav-position-right="Options.tocNavPositionRight"
:default-show-toc="Options.defaultShowToc"
:placeholder="Options.placeholder"
:autofocus="Options.autofocus"
:default-fullscreen="Options.defaultFullscreen"
:include-level="Options.includeLevel"
:left-toolbar="Options.leftToolbar"
:right-toolbar="Options.rightToolbar"
:toolbar="Options.toolbar"
:toolbar-config="Options.toolbarConfig"
/>
</template>
<style scoped lang="less">
</style>
<script setup lang="ts">
import {reactive} from "vue";
const Documentation = reactive({
// 文档标题
title: '',
// 双向绑定数据
content: ''
})
const Options = reactive({
// 编辑器模式 默认editable
mode: [
{name: '仅编辑模式', value: 'edit'},
{name: '仅预览模式', value: 'preview'},
{name: '编辑与预览模式', value: 'editable'}
]
})
// 点击图片时触发的事件
const clickImage = (images: string, currentIndex: number) => {
console.log("点击图片...")
console.log(images)
console.log(currentIndex)
}
</script>
<template>
<v-md-editor
v-model="Documentation.content"
:mode="Options.mode[1].value"
/>
</template>
<style scoped lang="less">
</style>
Editor.md
官方网站:Editor.md
npm install editor.md
mavon-edito(Vue3.x暂不支持)
github源码:github
使用文档:mavon-editor
npm install mavon-editor --save
全局注册
import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
md-editor-vue3
官方文档:MdEditorV3 文档
npm install md-editor-v3
<script lang="ts" setup>
// 文档:https://imzbf.github.io/md-editor-v3/docs/index
import MdEditor from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import {ref} from "vue";
const blogContent = ref('')
</script>
<template>
<MdEditor v-model="blogContent" />
</template>
<style lang="less" scoped>
/*编辑器样式设置*/
#md-editor-v3 {
height: 750px;
}
</style
|