构建用户界面的渐进式框架
vue CLI 是 vue.js开发的标准工具
cnpm install -g @vue/cli
vue --version
vue create vue-demo // 名字不能大写
- 插件高亮 vue2 vetur,vue3 volar
# 模板语法
<template>
<div class="hello">
<h3>学习模板语法</h3>
<p>{{msg}}</p>
<div v-html="rawHtml"></div>
<div v-bind:id="dynamicId"></div>
<p>{{ num + 10}}</p>
<p>{{ flag ? "浩浩":"婷婷"}}</p>
<p>{{message.split('').reverse().join("")}}</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data(){
return {
msg: "测",
rawHtml: "<a href='http://www.baidu.com'>百度</a>",
dynamicId: 10001,
num: 10,
flag: true,
message: "123"
}
}
}
</script>
- {{}}文本
- v-html 绑定标签
- v-bind 绑定属性 可以简写成 :
- vue支持JS表达式 不支持语句和流程控制
# 条件渲染
<template>
<div v-if="flag">haha</div>
<div v-else>hhh</div>
</template>
<script>
export default {
name: 'HelloWorld',
data(){
return {
flag: true
}
}
}
</script>
- 一个 v-else 元素必须跟在一个 v-if 或者 v-else-if 元素后面,否则它将不会被识别。
v-if 是“真实的”按条件渲染,因为它确保了在切换时,条件区块内的事件监听器和子组件都会被销毁与重建。
v-if 也是惰性的:如果在初次渲染时条件值为 false,则不会做任何事。条件区块只有当条件首次变为 true 时才被渲染。
相比之下,v-show 简单许多,元素无论初始条件如何,始终会被渲染,只有 CSS display 属性会被切换。
总的来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要频繁切换,则使用 v-show 较好;如果在运行时绑定条件很少改变,则 v-if 会更合适。
# 列表渲染
<template>
<ul>
<li v-for="item in newLists" :key="item.id">
{{item.title}}
</li>
</ul>
</template>
<script>
export default {
data(){
return {
newLists:[
{
id:1001,
title: "今日新闻1"
},
{
id:1002,
title: "今日新闻2"
},
{
id:1003,
title: "今日新闻3"
}
]
}
}
}
</script>
Vue 默认按照“就地更新”的策略来更新通过v-for渲染的元素列表。当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。
默认模式是高效的,但只适用于列表渲染输出的结果不依赖子组件状态或者临时 DOM 状态 (例如表单输入值) 的情况。
为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的keyattribute:
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
# 事件处理
<template>
<div>
<button @click="counter += 1">点击counter = {{ counter }}</button>
<button @click="clickHandle">按钮</button>
<p>{{ message }}</p>
<button @click="say('hi')">say hi</button>
<button @click="say('what')">say what</button>
<ul>
<li @click="clickItemhandle(item)" v-for="(item,index) in names" :key="index">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
counter: 1,
message: "消息通知",
name:[
"iwen",
"ime",
"frank"
]
}
},
methods: {
clickHandle(event) {
//this.message = "消息被撤回了";
// event 是原生dom event
console.log(event);
console.log(event.target);
if (event) {
event.target.innerHTML = "点击之后";
}
},
say(data){
console.log(data);
},
clickItemhandle(item){
console.log(item);
}
}
}
</script>
# 表单输入绑定
v-model 指令在表单元素上进行双向绑定input,textarea,select
.lazy ,默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步。,会转成change事件之后进行同步。
.trim 去掉首尾空格
<template>
<div>
<input type="text" v-model.lazy="username">
<input type="text" v-model.trim="password">
<p>{{username}},{{password}}</p>
<button @click="clickGetUserName">获取用户名</button>
</div>
</template>
<script>
export default {
data() {
return {
username:"",
password:""
}
},
methods: {
clickGetUserName(){
console.log(this.username);
}
}
}
</script>
# 组件基础
<template>
<h3>单文件主键</h3>
</template>
<script>
export default{
name: "mycomponents"
}
</script>
<style>
h3{
color: red;
}
</style>
<template>
<img alt="Vue logo" src="./assets/logo.png">
<MyComponents></MyComponents>
<my-components></my-components>
</template>
<script>
import MyComponents from './components/MyComponents.vue';
export default {
name: 'App',
components: {
MyComponents
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
- 组件名不能使用单字母,驼峰命名可以使用-来使用组件。
- 通常一个应用会以一颗嵌套的组件树的形式来组织。
- 组件之前会相互隔离的,一定程度上防止问题的发生
# 组件交互
<template>
<h3>prop传递数据</h3>
<p>{{title}}</p>
<ul>
<li v-for="(item,index) in names" :key="index">{{item}}</li>
</ul>
</template>
<script>
export default{
name: "Mycomponent",
props:{
title:{
type:String,
default: ""
},
names:{
type:Array,
// 数组和对象必须使用函数进行返回
default:function(){
return []
}
}
}
}
</script>
<style>
h3{
color: red;
}
</style>
<template>
<img alt="Vue logo" src="./assets/logo.png">
<MyComponents :title="title" :names="names"></MyComponents>
</template>
<script>
import MyComponents from './components/MyComponents.vue';
export default {
name: 'App',
data(){
return{
title: "我是一个标题",
names:["iwen","ime","frank"]
}
},
components: {
MyComponents
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
- String
- Number
- Boolean
- Array
- Object
- Function
- 对象或者数组要用工厂模式。
# 自定义事件的组件交互
<template>
<h3>自定义事件传递关系</h3>
<button @click="sendClickhandle">点击传递</button>
</template>
<script>
export default {
name: "Mycomponent",
data() {
return {
message: "我是MyComponent数据"
}
},
methods:{
sendClickhandle()
{
// 参数1:字符串: 理论上是随便的,但是需要具有意义
// 参数2:传递的数据
this.$emit("onEvent", this.message)
}
}
}
</script>
<style>
h3 {
color: red;
}
</style>
<template>
<img alt="Vue logo" src="./assets/logo.png">
<MyComponents @onEvent="getDataHandle"></MyComponents>
<p>{{message}}</p>
</template>
<script>
import MyComponents from './components/MyComponents.vue';
export default {
name: 'App',
components: {
MyComponents
},
data(){
return {
message: ""
}
},
methods:{
getDataHandle(data){
console.log(data);
this.message = data;
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
# 组件的生命周期(8个)
创建 beforeCreate 、 created
渲染 beforeMount 、 mounted
更新 beforeUpdate、updated
卸载 beforeUnmount、unmounted
<template>
<h3>生命周期函数</h3>
<p>{{message}}</p>
<button @click="message='数据'">点击</button>
</template>
<script>
export default {
name: "Mycomponent",
data() {
return {
message: ""
}
},
beforeCreate(){
console.log("beforeCreate: 组件创建之前");
},
created(){
console.log("created: 组件创建之前");
},
beforeMount(){
console.log("beforeMount:渲染之前");
},
mounted(){
console.log("mounted:组件渲染完成");
// 把网络请求放到这里
},
beforeUpdate(){
console.log("beforeUpdate: 组件更新之前");
},
updated(){
console.log("beforeUpdate: 组件更新之后");
},
beforeUnmount(){
console.log("beforeUnmount: 组件卸载之前");
// 卸载之前,把消耗性能的处理都干掉
// 定时器
},
unmounted(){
console.log("unmounted: 组件卸载之后");
}
}
</script>
<style>
h3 {
color: red;
}
</style>
# vue引入第三方
npm i swiper@版本号
Swiper 轮播图
github寻找
vue2的好的第三方资源
<template>
<swiper :modules="modules" :pagination="{ clickable: true }">
<swiper-slide>
<img src="../assets/1.jpg">
</swiper-slide>
<swiper-slide><img src="../assets/1.jpg"></swiper-slide>
<swiper-slide><img src="../assets/1.jpg"></swiper-slide>
</swiper>
</template>
<script>
import { Swiper, SwiperSlide } from 'swiper/vue';
import {Pagination} from 'swiper';
import 'swiper/css';
import 'swiper/css/pagination';
export default {
components: {
Swiper,
SwiperSlide,
},
data() {
return {
modules: [Pagination],
};
},
};
</script>
<style>
img {
width: 80%;
height: 600px;
}
</style>
# Axios网络请求
基于promise的网络请求库
npm install axios 安装
npm install -save querystring 转换格式
https://www.kancloud.cn/yunye/axios/234845/ (opens new window)
<template>
<div>
<p>{{ chengpin.title }}</p>
</div>
</template>
<script>
// import axios from "axios"
// import querystring from "querystring"
export default {
data() {
return {
chengpin: {}
}
},
mounted() {
// axios(
// {
// method: "get",
// url: "http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php"
// }
// ).then(
// res =>{
// this.chengpin = res.data.chengpinDetails[0];
// }
// )
// axios(
// {
// method: "post",
// url: "http://iwenwiki.com/api/blueberrypai/login.php",
// data: querystring.stringify({
// user_id: "iwen@qq.com",
// password: "iwen123",
// verification_code: "crfvw"
// })
// }
// ).then(
// res =>{
// console.log(res.data);
// }
// )
// 快捷方案
this.$axios.get("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php").then(res => {
console.log(res.data);
});
this.$axios.post("http://iwenwiki.com/api/blueberrypai/login.php", this.$querystring.stringify(
{
user_id: "iwen@qq.com",
password: "iwen123",
verification_code: "crfvw"
}
)).then(res => {
console.log(res.data);
})
}
};
</script>
<style>
img {
width: 80%;
height: 600px;
}
</style>
import { createApp } from 'vue'
import App from './App.vue'
import axios from "axios"
import querystring from "querystring"
import './registerServiceWorker'
const app = createApp(App)
app.config.globalProperties.$axios = axios
app.config.globalProperties.$querystring = querystring
app.mount('#app')
# 网络请求封装
const base = {
baseUrl: "http://iwenwiki.com",
chengpin: "/api/blueberrypai/getChengpinDetails.php"
}
export default base;
import axios from "../utils/request"
import path from './path'
const api = {
// 诚品详情地址
getChengpin(){
return axios.get(path.baseUrl+path.chengpin)
}
}
export default api
import axios from 'axios'
import querystring from "querystring"
const errorHandle = (status,info)=>{
switch(status){
case 400:
console.log("语音有误");
break;
case 401:
console.log("服务器认证失败");
break;
case 403:
console.log("服务器拒绝访问");
break;
case 404:
console.log("地址错误");
break;
case 500:
console.log("服务器遇到意外");
break;
case 502:
console.log("服务器无响应");
break;
default:
console.log(info);
break;
}
}
const instance = axios.create(
{
// 网络请求的公共配置
timeout: 5000
}
)
// 拦截器使用
// 发送数据
instance.interceptors.request.use(
config =>{
if(config.method === "post"){
config.data = querystring.stringfy(config.data)
}
// config 包含网络请求的所有信息
return config;
},
error =>{
return Promise.reject(error)
}
)
// 获取数据之前
instance.interceptors.response.use(
response =>{
return response.status === 200 ? Promise.resolve(response) : Promise.reject(error)
},
error =>{
const {response} = error;
// 错误的处理才是重点
errorHandle(response.status,response.info)
}
)
// 发送数据之前
export default instance;
# 网络请求跨域解决方案
js 同源策略
同源策略就是浏览器的一项安全策略,浏览器只允许js代码请求和当前所在服务器域名,端口,协议相同的数据接口上
协议,域名,端口任意一个不相同,就跨域。
后台解决:cors
前台解决:proxy
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer:{
proxy:{
'/api':{
target: 'http://iwenwiki.com',
changeOrigin: true
}
}
}
})
# vue引入路由配置
在vue中,我们可以通过vue-router路由管理页面之间的关系
vue Router 构建单页面应用轻而易举
cnpm install --save vue-router
import {createRouter,createWebHashHistory,createWebHistory} from "vue-router"
import HomeView from "../views/HomeView"
import AboutView from "../views/AboutView"
// 配置信息中需要页面的相关配置
const routes =[
{
path:"/",
component: HomeView
},
{
path:"/about",
component: AboutView
}
]
const router = createRouter(
{
// createWebHashHistory 原理: a标签的锚点链接
// createWebHistory 此种方式需要后台做重定向,否则会出现404问题 h5 的 pushState()
history: createWebHashHistory(),
routes
}
)
export default router;
import { createApp } from 'vue'
import App from './App.vue'
import axios from "axios"
import querystring from "querystring"
import './registerServiceWorker'
import router from "./router"
const app = createApp(App)
app.config.globalProperties.$axios = axios
app.config.globalProperties.$querystring = querystring
app.use(router)
app.mount('#app')
<template>
<router-link to="/">首页</router-link> |
<router-link to="/about">关于</router-link>
<router-view></router-view>
</template>
<script>
export default {
name: 'App',
components: {
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
location / {
try_files $uri $uri/ /index.html;
}
# 路由传递参数
import {createRouter,createWebHashHistory,createWebHistory} from "vue-router"
import HomeView from "../views/HomeView"
import AboutView from "../views/AboutView"
// 配置信息中需要页面的相关配置
const routes =[
{
path:"/",
name: 'home',
component: HomeView
},
{
path:"/about",
name: 'about',
component: AboutView
},
{
path:"/news",
name: 'news',
// 异步加载方式 页面多容易造成卡顿
component: () => import("../views/NewsView.vue")
},
{
path:"/newsdetails/:name",
name: 'newsdetails',
// 异步加载方式 页面多容易造成卡顿
component: () => import("../views/NewsDetailsView.vue")
}
]
const router = createRouter(
{
// createWebHashHistory 原理: a标签的锚点链接
// createWebHistory 此种方式需要后台做重定向,否则会出现404问题 h5 的 pushState()
history: createWebHashHistory(),
routes
}
)
export default router;
!<template>
<div class="">
<h3>新闻</h3>
<ul>
<li><router-link to="/newsdetails/中国">中国新闻</router-link></li>
<li><router-link to="/newsdetails/百度">百度新闻</router-link></li>
<li><router-link to="/newsdetails/头条">头条新闻</router-link></li>
</ul>
</div>
</template>
<script>
export default {
name: '',
props: {},
data () {
return {}
},
components: {
},
computed: {
},
mounted: {
},
watch: {
},
methods: {
},
created () {
},
mounted () {
},
}
</script>
<style scoped>
</style>
!<template>
<div class="">
<h3>新闻详情</h3>
<p>{{$route.params.name}}</p>
</div>
</template>
<script>
export default {
name: '',
props: {},
data () {
return {}
},
components: {
},
computed: {
},
mounted: {
},
watch: {
},
methods: {
},
created () {
},
mounted () {
},
}
</script>
<style scoped>
</style>
# 嵌套路由配置
import {createRouter,createWebHashHistory,createWebHistory} from "vue-router"
import HomeView from "../views/HomeView"
import AboutView from "../views/AboutView"
// 配置信息中需要页面的相关配置
const routes =[
{
path:"/",
name: 'home',
component: HomeView
},
{
path:"/about",
name: 'about',
redirect: "/about/us",
component: AboutView,
children:[
{
path: "us",
component: () => import("../views/AboutSub/AboutUS.vue")
},
{
path: "info",
component: () => import("../views/AboutSub/AboutInfo.vue")
}
]
},
{
path:"/news",
name: 'news',
// 异步加载方式 页面多容易造成卡顿
component: () => import("../views/NewsView.vue")
},
{
path:"/newsdetails/:name",
name: 'newsdetails',
// 异步加载方式 页面多容易造成卡顿
component: () => import("../views/NewsDetailsView.vue")
}
]
const router = createRouter(
{
// createWebHashHistory 原理: a标签的锚点链接
// createWebHistory 此种方式需要后台做重定向,否则会出现404问题 h5 的 pushState()
history: createWebHashHistory(),
routes
}
)
export default router;
<template>
<div>
<router-link to="/about/us">关于我们</router-link> |
<router-link to="/about/info">关于信息</router-link>
<router-view></router-view>
</div>
</template>
# Vuex 状态管理
更方便的管理组件之间的数据交互,提供了一个集中式的管理方案,任何组件都有可以指定的方式进行读取和改变数据。解决组件嵌套传递数据问题。
cnpm install --save vuex
import { createApp } from 'vue'
import App from './App.vue'
import axios from "axios"
import querystring from "querystring"
import './registerServiceWorker'
import router from "./router"
import store from './store'
const app = createApp(App)
app.config.globalProperties.$axios = axios
app.config.globalProperties.$querystring = querystring
app.use(router)
app.use(store)
app.mount('#app')
<template>
<router-link to="/">首页</router-link> |
<router-link to="/about">关于</router-link> |
<router-link to="/news">新闻</router-link>
<router-view></router-view>
<p>counter = {{$store.state.counter}}</p>
<p>{{counter}}</p>
</template>
<script>
// vuex提供的快捷读取方式
import {mapState} from "vuex"
export default {
name: 'App',
components: {
},
computed:{
...mapState(["counter"])
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
import{createStore} from 'vuex'
export default createStore({
state:{
counter: 0
}
})
# Vuex 常用核心概念
state,getter,Mutation,Action
Getter 过滤数据
Mutation 修改数据
Action 类似不过可以是异步操作,类似于网络请求
<template>
<router-link to="/">首页</router-link> |
<router-link to="/about">关于</router-link> |
<router-link to="/news">新闻</router-link>
<router-view></router-view>
<p>counter = {{$store.state.counter}}</p>
<p>{{counter}}</p>
<p>count = {{$store.getters.getCounter}}</p>
<button @click="addClickHandle">点击</button>
<button @click="addAsyncClickHandle">点击</button>
</template>
<script>
// vuex提供的快捷读取方式
import {mapActions, mapMutations, mapState} from "vuex"
import {mapGetters} from "vuex"
export default {
name: 'App',
components: {
},
computed:{
...mapState(["counter"]),
...mapGetters(["getCounter"])
},
methods:{
...mapMutations(["addCounter"]),
...mapActions(["asyncAddCounter"]),
addClickHandle(){
// this.$store.commit("addCounter",15)
this.addCounter(20)
},
addAsyncClickHandle(){
//this.$store.dispatch("asyncAddCounter")
this.asyncAddCounter()
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
import{createStore} from 'vuex'
import axios from "axios"
export default createStore({
state:{
counter: 10
},
getters:{
getCounter(state){
return state.counter > 0 ? state.counter : "counter数据异常"
}
},
mutations:{
addCounter(state,num){
state.counter += num;
}
},
actions:{
asyncAddCounter({commit}){
axios.get("http://iwenwiki.com/api/generator/list.php").then(
res =>{
commit("addCounter",res.data[0])
}
)
}
}
})
# Vue3新特性
- 性能比2强
- 打包体积更小,可以删除无用模块
- 组合API
- 碎片
- TS支持
- 暴露了自定义渲染API
!<template>
<div class="">
<p>{{message}}</p>
<ul>
<li v-for="(item,index) in names.lists" :key="index">{{item}}</li>
</ul>
<p>{{message}}</p>
<button @click="clickHandle">点击</button>
<p>{{msg}}</p>
</div>
</template>
<script>
import {ref,reactive} from "vue"
export default {
name: '',
props:{
msg: String
},
setup(props,ctx){
// setup 没有this 关键字
console.log(props.msg);
console.log(ctx);
const message = ref("我是消息");
const names = reactive(
{
lists:["iwen","ime","frank"]
}
)
function clickHandle(){
console.log("我是新的消息");
message.value = "我是新的消息";
}
const msg = props.msg;
return{
message,
names,
clickHandle,
msg
}
}
}
</script>
<style scoped>
</style>
生命周期函数 都加上 on,去掉了组件创建的两个。
生命周期函数可以有多个按照生命周期函数
Provide 和 Inject 必须是父和子,不限层级
Fragment 以前只是单个根节点,现在允许多个
!<template>
<div class="">
<p>{{message}}</p>
<ul>
<li v-for="(item,index) in names.lists" :key="index">{{item}}</li>
</ul>
<p>{{message}}</p>
<button @click="clickHandle">点击</button>
<p>{{msg}}</p>
<p>{{mess}}</p>
</div>
</template>
<script>
import {ref,reactive, onMounted, inject} from "vue"
export default {
name: '',
props:{
msg:String
},
setup(props,ctx){
// setup 没有this 关键字
console.log(props.msg);
console.log(ctx);
const message = ref("我是消息");
const names = reactive(
{
lists:["iwen","ime","frank"]
}
)
onMounted(()=>{
console.log("挂载了");
})
onMounted(()=>{
console.log("挂载了1");
})
function clickHandle(){
console.log("我是新的消息");
message.value = "我是新的消息";
}
const msg = props.msg;
const mess = inject("message");
return{
message,
names,
mess,
clickHandle,
msg
}
}
}
</script>
<style scoped>
</style>
<template>
<router-link to="/">首页</router-link> |
<router-link to="/about">关于</router-link> |
<router-link to="/news">新闻</router-link>
<router-view></router-view>
<p>counter = {{$store.state.counter}}</p>
<p>{{counter}}</p>
<p>count = {{$store.getters.getCounter}}</p>
<button @click="addClickHandle">点击</button>
<button @click="addAsyncClickHandle">点击</button>
<div>
<HelloWorldVue msg="hhhh"></HelloWorldVue>
</div>
</template>
<script>
import HelloWorldVue from "./components/HelloWorld.vue"
// vuex提供的快捷读取方式
import {mapActions, mapMutations, mapState} from "vuex"
import {mapGetters} from "vuex"
import {provide} from "vue"
export default {
name: 'App',
components: {
HelloWorldVue
},
setup(){
provide("message","我是消息消息")
},
computed:{
...mapState(["counter"]),
...mapGetters(["getCounter"])
},
methods:{
...mapMutations(["addCounter"]),
...mapActions(["asyncAddCounter"]),
addClickHandle(){
// this.$store.commit("addCounter",15)
this.addCounter(20)
},
addAsyncClickHandle(){
//this.$store.dispatch("asyncAddCounter")
this.asyncAddCounter()
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
# Vue3 加载Element-plus
cnpm install element-plus --save
# 完整引入
import { createApp } from 'vue'
import App from './App.vue'
import axios from "axios"
import querystring from "querystring"
import './registerServiceWorker'
import router from "./router"
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.config.globalProperties.$axios = axios
app.config.globalProperties.$querystring = querystring
app.use(router)
app.use(store)
app.use(ElementPlus)
app.mount('#app')
# 按需引入
cnpm install -D unplugin-vue-components unplugin-auto-import
const { defineConfig } = require('@vue/cli-service')
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
]
}
})
# Element-plus字体图标
cnpm install @element-plus/icons-vue
在项目根目录下,创建plugins文件夹,在文件夹下创建文件icons.js文件
import * as components from "@element-plus/icons-vue";
export default {
install: (app) => {
for (const key in components) {
const componentConfig = components[key];
app.component(componentConfig.name, componentConfig);
}
},
};
# 引入文件
在main.js中引入icons.js文件
import elementIcon from "./plugins/icons";
app.use(elementIcon)