地址
快捷键
c o n t r o l + f − − − − G o o g l e 搜索 control+f ----Google搜索 control+f−−−−Google搜索
c o n t r o l + r − − − − 替换所有指定字符 control+r ----替换所有指定字符 control+r−−−−替换所有指定字符
a l t + 左键 − − − − 对多行进行处理 alt + 左键----对多行进行处理 alt+左键−−−−对多行进行处理
c o n t r o l + a l t + a − − − − Q Q 截屏快键键 control+alt+a----QQ截屏快键键 control+alt+a−−−−QQ截屏快键键
模块开发步骤
1)先静态页面+静态组件拆分
2)发请求(API)
3)vuex(三连环)
- 在api中抛出函数,index.js中
//API统一管理
import request from "./request";
//http://gmall-h5-api.atguigu.cn/api/product/getBaseCategoryList
export const reqCategoryList = () => {return request({url: '/product/getBaseCategoryList',method: 'get' })};
- 在组件中使用
this.$store.dispatch('函数名');
- 在store下引入函数
import { reqCategoryList } from "@/api";
注意:这里的“params={}”指params默认参数是空对象{}
const actions = {
async getSearchList({commit},params={}){
let result=await reqGetSearchInfo(params);
if(result.code===200){
commit('GETSEARCHLIST',result.data)
}else{
console.log('请求失败')
}
}
}
4)组件获取仓库数据,动态展示数据
路由
注册路由
1.引入:
import Vue from 'vue'
import VueRouter from 'vue-router'
2.抛出:
Vue.use(VueRouter) export default new VueRouter({ routes:[]})
路由滚动行为
const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 期望滚动到哪个的位置 return { x: 0, y: 0 } } })
3.重定向
{
path:'/',
redirect: '/home'
}
在APP中要加上
4.在main.js中引入注册
import Vue from 'vue'
import App from './App.vue'
import router from '@/router'
new Vue({
render: h => h(App),
router
}).$mount('#app')
2.route传参
1.编程式导航
this.$router.push({
name: 'sousuo',
params: {
keyword: this.keyword
},
query: {
keyword: this.keyword
}
})
使用下面代码解决点击多下会报错问题,修改VueRouter原型中的push,replace函数
let orginPush = VueRouter.prototype.push
let orginReplace = VueRouter.prototype.replace
VueRouter.prototype.push = function(location, onResolve, onReject) {
if (onResolve || onReject) return orginPush.call(this, location, onResolve, onReject)
return orginPush.call(this, location).catch(err => err)
}
VueRouter.prototype.replace = function(location, onResolve, onReject) {
if (onResolve || onReject) return orginReplace.call(this, location, onResolve, onReject)
return orginReplace.call(this, location).catch(err => err)
}
在router下面的index.js中写上params的参数
props接受参数,一般不定义,在组件中接受
{
name:'sousuo',
path:'/search/:keyword?',
component:Search,
meta:{show:true},
props:($route)=>({keyword:$route.params.keyword,keyword2:$route.query.keyword})
},
注意:path和params不能联合使用,params不能传空字符串,可以加上||unidentified
2.声明式导航
3.query传参
要在ruter下的index.js中配置props,不然接受不到
this.$route.query.参数名
3.meta使用
配置在route下的index.js中
{
path:'/login',
component:Login,
meta:{show:false}
},
使用情形:与v-show并用,决定组件是否渲染
<template>
<div>
<Header/>
<router-view></router-view>
<Footer v-show="$route.meta.show"></Footer>
</div>
</template>
4.路由守卫
-
作用:对路由进行权限控制
-
分类:全局守卫、独享守卫、组件内守卫
-
全局守卫:
在
//全局前置守卫:初始化时执行、每次路由切换前执行 router.beforeEach((to,from,next)=>{ console.log('beforeEach',to,from) if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制 if(localStorage.getItem('school') === 'atguigu'){ //权限控制的具体规则 next() //放行 }else{ alert('暂无权限查看') // next({name:'guanyu'}) } }else{ next() //放行 } }) //全局后置守卫:初始化时执行、每次路由切换后执行 router.afterEach((to,from)=>{ console.log('afterEach',to,from) if(to.meta.title){ document.title = to.meta.title //修改网页的title }else{ document.title = 'vue_test' } })
-
独享守卫:
beforeEnter(to,from,next){ console.log('beforeEnter',to,from) if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制 if(localStorage.getItem('school') === 'atguigu'){ next() }else{ alert('暂无权限查看') // next({name:'guanyu'}) } }else{ next() } }
-
组件内守卫:
//进入守卫:通过路由规则,进入该组件时被调用 beforeRouteEnter (to, from, next) { }, //离开守卫:通过路由规则,离开该组件时被调用 beforeRouteLeave (to, from, next) { }
5.路由跳转注意事项
生命周期:
路由跳转时,旧组件会销毁
若是自己跳自己则不会触发生命周期函数。
注册全局组件
三级联动
指的是多个组件使用这个全局组件。
1.注册全局组件
在main.js中引入
import TypeNav from '@/components/TypeNav'
Vue.component('TypeNav', TypeNav)
注意:其中第一个参数是全局组件的名字,第二个参数是哪一个组件。TypeNav是一个文件夹,下面index.js文件里面有个TypeNav.vue,name:“TypeNav”。
2.使用全局组价
不需要使用components{}来注册,直接使用就可。
接口
api管理接口
主流用axios,安装 npm install --save axios
配置代理
在vue.config.js中配置
//代理跨域
devServer: {
proxy: {
'/api': {
target: 'http://gmall-h5-api.atguigu.cn',
changeOrigin: true,
// pathRewrite: {
// '^/api': ''
// }
}
}
}
}
request.js
import axios from 'axios'
const request = axios.create({
baseURL: "/api",
timeout: 5000,
})
// 请求拦截器
request.interceptors.request.use(config => {
return config});
//响应拦截器
request.interceptors.response.use(response => {
return response.data},(error) => {
return Promise.reject(new Error(error.message));
})
export default request
index.js
抛出函数
//API统一管理
import request from "./request";
//http://gmall-h5-api.atguigu.cn/api/product/getBaseCategoryList
export const reqCategoryList = () => {return request({url: '/product/getBaseCategoryList',method: 'get' })};
在main.js中注册
import {reqCategoryList} from '@/api/index'
reqCategoryList();
进度条
在request.js中引入
其中进度条样式可以修改,在nprogress/nprogress.css中修改
//引入进度条
import nprogress from 'nprogress'
//引入进度条样式
import 'nprogress/nprogress.css'
request.interceptors.request.use(config => {
//显示进度条
nprogress.start();
return config});
request.interceptors.response.use(response => {
//隐藏进度条
nprogress.done();
return response.data},(error) => {
return Promise.reject(new Error(error.message));
})
vuex
vuex是个插件,状态管理库,集中式管理项目中组件公用的数据
vuex仓库储存数据不是持久化储存
使用情形:项目很大,组件很多,数据很多,数据维护很费劲,使用vuex
安装
npm install --save vuex@3
注册
在scr目录下新建store文件夹,在index.js中写入代码
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
//state:仓库中的数据
const state = {}
//mutations:修改仓库中的数据
const mutations = {
//add(state,参数){
// state.数据 = 参数
// }
}
//actions:异步修改仓库中的数据
const actions = {
//这里可以书写业务逻辑但不能修改state中的数据
//ADD(commit,参数){
// commit('ADD',参数)
}
//getters:计算属性
const getters = {}
//对外暴露一个store对象
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
在main.js中注册
import store from '@/store/index'
new Vue({
render: h => h(App),
router,
//注册store
store
}).$mount('#app')
在组件中使用时:
this.$store.dispatch('函数名');
在store的index.js中注册多个vuex
//引入子vuex
import home from './home'
//暴露
export default new Vuex.Store({
modules:{
home,
}
})
在子组件中写时,注意不用创建vuex模块
import { reqCategoryList } from "@/api";
const state={
categoryList:[]
};
const mutations = {
CATEGORYLIST(state,data){
state.categoryList=data
}
};
const actions = {
async categoryList({commit}){
let result=await reqCategoryList()
if (result.code===200){
commit('CATEGORYLIST',result.data)
}
}
};
const getters = {};
export default{
state,
mutations,
actions,
getters
}
使用store中方法:
1.获取数据
首先在全局组件TypeNva中mounted(){}挂载中提交actions,获取接口中的列表等数据
mounted(){
this.$store.dispatch('categoryList')
},
2.mapstate获取store中state中的数据:
两种方式
1.mapState中传入数组
import {mapState} from 'vuex';
computed: {
...mapState(['name', 'age']),//与state中的名字相同,在template中可以直接使用name,age
},
2.mapState中传入对象
注意:当时用modules时,数组方法不可用,用对象方法:
import {mapState} from 'vuex';
computed: {
...mapState({
name1: state => state.name+'123',//与state中的名字不相同,可以进行处理
age: state => state.age
})
},
},
eg:在store中使用modules
import {mapState} from 'vuex';
computed:{
...mapState({
categoryList: state => state.home.categoryList //state是参数,return state.home.categoryList给categoryList
})
},
3.getters获取store中的数据
简化仓库中的数据,可以把将来组件中需要的数据简化一下,获取更方便
const getters = {
goodsList(state){
return state.searchList.goodsList || []
},
trademarkList(state){
return state.searchList.trademarkList || []
},
attrsList(state){
return state.searchList.attrsList || []
}
}
注意:getters可以理解为计算属性,传入的参数是state对象
获取数据时用数组形式即可,不分模块
在想获取数据的组件中
import { mapGetters} from 'vuex'
computed: {
...mapGetters(['goodsList']),
},
函数防抖与节流
定义:防止用户操作过快使页面卡顿,加入lodash函数以后,使在一定时间内用户的操作只进行最后一次的操作。
只引入lodash中的throttle函数
import throttle from 'lodash/throttle';
methods:{
//对changeIndex进行节流
changeIndex: throttle(function(index){
this.currentIndex = index
}, 50),
}
js文件的引入:
如果是默认暴露: import 包名 from ‘路径’
如果是 ? :import {。。。}from ‘路径’
自定义属性
概念
img的标准属性为src、alt等,但若写一个 data-info 则data-info叫自定义属性
作用
一般用来存储额外数据辅助完成某个功能
规范
自定义属性一律以 data- 开头,后面接名字,且名字中若多个单词用-隔开
例:data-info 、data-label、data-login-name等
为什么要加 data- 开头
方便区分什么是【标准属性】,什么是【自定义属性】
JavaScript操作自定义属性:dataset
语法
元素.dataset.自定义属性名
注意事项
不用加data-,后面遵守驼峰命名法
例:某元素的自定义属性叫 data-label,则 元素.dataset.label
通过dataset可以获取自定义属性也可以重新赋值,若赋值的自定义属性不存在时则自动添加
<a :data-categoryName="c1.categoryName" >{{c1.categoryName}}</a>
三级联动的路由跳转
事件委派
将子标签的点击事件全部委托给父标签div
待解决问题
1.事件委派是把全部子节点【h1,dt,dl,em】的事件都委派给父亲节点
2.点击a标签时,才会跳转,怎么保证点击的是a标签
3.若点击的是a标签,如何区分是几级分类的标签
解决
使用自定义属性
<a :data-categoryName="c1.categoryName" :data-category1id="1" >{{c1.categoryName}}</a>
<a :data-categoryName="c2.categoryName" :data-category2id="2">{{c2.categoryName}}</a>
<a :data-categoryName="c3.categoryName" :data-category3id="3">{{c3.categoryName}}</a>
传参时
goSearch(event){
let {categoryname,category1id,category2id,category3id} = event.target.dataset
console.log(event.target.dataset)
if(categoryname){
let location ={name:'sousuo'}
let query ={categoryName:categoryname}
if(category1id){
query.category1Id = category1id
}
else if(category2id){
query.category2Id = category2id
}
else{
query.category3Id = category3id
}
location.query = query
this.$router.push(location)
}
}
过度动画
前提:组件|元素务必要有v-if|v-show指令才能进行过度动画
包裹标签
<transition name="sort">
.....
</trainsition>
<style>
.sort-enter{ //进入动画
opacity: 0;
transform: translateX(-100px);
}
.sort-enter-active{
transition: all 0.5s;
}
.sort-enter-to{
opacity: 1;
transform: translateX(0);
}
</style>
mock(模拟) 数据
需要插件mockjs
生成随机数据,拦截Ajax请求
使用步骤:
1)在项目当中src文件夹中创建mock文件夹
2)准备JSON数据,mock文件夹中创建相应JSON文件—一定要格式化(留有空格跑不起来)
3)把mock数据所需要的图片放置到public文件夹下【public文件夹在打包的时候,会把相应的资源原封不动的打包到dist文件夹中】
注意:默认根目录是public,所以mock中图片路径写“/images/name.png”
4)开始mock虚拟数据了,通过mockjs模块实现,在mock文件夹下创建mockServer.js
5)mockServe在入口文件中引入(至少执行一次,该文件不需要暴露)
代码:
在mockServe.js中
//先引入mockjs模块
import Mock from 'mockjs';
//引入mock数据
//webpack默认对外暴露的:图片,json数据格式
import banner from './banner.json';
import floor from './floor.json';
//mock数据:第一个参数:请求路径,第二个参数:请求方式,第三个参数:请求数据
Mock.mock('/mock/banner',{code:200,data:banner});
Mock.mock('/mock/floor',{code:200,data:floor});
注意:
1)webpack默认对外暴露的:图片,JSON数据格式,不用export暴露
2)请求路径:“/mock/name”,没有“·”
在main.js中
//引入mockServer
import '@/mock/mockServer'
在api中配置接口,写一个mockAjax.js文件,跟之前的request.js一样,但baseURL不一样,使用“/mock”
import axios from 'axios'
//引入进度条
import nprogress from 'nprogress'
//引入进度条样式
import 'nprogress/nprogress.css'
const request = axios.create({
baseURL: "/mock",
timeout: 5000,
})
// 请求拦截器
request.interceptors.request.use(config => {
//显示进度条
nprogress.start();
return config});
request.interceptors.response.use(response => {
//隐藏进度条
nprogress.done();
return response.data},(error) => {
return Promise.reject(new Error(error.message));
})
export default request
在api下index.js中写接口调用函数
import mockRequest from "./mockAjax";
//对外暴露一个函数,只要调用这个函数,就向后台发送Ajax请求,获取数据,切记要返回值
export const reqBannerList = () => {return mockRequest({url: '/banner',method: 'get' })};
在要使用获取数据的组件中挂载:
mounted(){
//派发action,通过vuex发起Ajax请求,将数据存储在仓库store中
this.$store.dispatch('getBannerList')
}
在store中配置相应的action,mutation
1)引入函数
import { reqCategoryList,reqBannerList } from "@/api";
2)在action中配置getBannerList函数
async getBannerList({commit}){
let result=await reqBannerList()
if (result.code===200){
commit('BANNERLIST',result.data)
}
}
3)在mutation中配置BANNERLIST函数,当然state中要有bannerList数组
BANNERLIST(state,data){
state.bannerList=data
},
4)在要使用获取数据的组件中获取数据:
computed: {
...mapState({
bannerList: state => state.home.bannerList
})
},
轮播图swiper
1)引包(相应的js|css
2)页面中结构务必要有
3)new swiper实例(轮播图添加动态效果)
// import Swiper bundle with all modules installed
import Swiper from "swiper/bundle";
// import styles bundle
import "swiper/css/bundle";
使用看官网
注意:最完美解决方案,解决轮播图问题 watch+nextTick: 数据监听 :监听已有数据的变化
watch 监听:可以保证数据一定ok,但不能保证v-for遍历结构是否完事
$nextTick
$nextTick:在下次DOM更新 循环结束之后 执行延迟回调。在 修改数据之后,立即使用这个方法,获取更新后的 DOM。
$nextTick:可以保证页面中的结构一定是有的,经常和很多插件一起使用【都需要DOM存在了】
watch监视bannerList
watch: {
//方式2:watch + nextTick
bannerList: {
handler(newValue, oldValue) {
this.$nextTick(() => {
var swiper = new Swiper(".swiper", {
// Optional parameters
direction: "horizontal",
loop: true,
//分页器可点击
paginationClickable: true,
// If we need pagination
pagination: {
el: ".swiper-pagination",
},
// Navigation arrows
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
// And if we need scrollbar
scrollbar: {
el: ".swiper-scrollbar",
},
});
});
},
},
},
组件间通信方式
六种主要:
1.props:用于父子组件通信
用 :list='floor’传递
在父组件中
<Floor v-for="(floor,index) in floorList" :key="floor.id" :floor="floor"/>
在子组件中
props:['floor']
注意:props中写键,并且打引号
2.全局事件总线:$bus 全能
在main.js中注册$bus
new Vue({
render: h => h(App),
//全局注册事件总线
beforeCreate(){
Vue.prototype.$bus = this
},
router,
//注册store
store
}).$mount('#app')
使用事件总线:
-
接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
methods(){ demo(data){......} } ...... mounted() { this.$bus.$on('xxxx',this.demo) }
-
提供数据:
this.$bus.$emit('xxxx',数据)
-
最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。
3.自定义事件:@on@emit 可以实现子给父通信
-
一种组件间通信的方式,适用于:子组件 ===> 父组件
-
使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
-
绑定自定义事件:
- 第一种方式,在父组件中:
<Demo @atguigu="test"/>
或<Demo v-on:atguigu="test"/>
- 第二种方式,在父组件中:
<Demo ref="demo"/> ...... mounted(){ this.$refs.xxx.$on('atguigu',this.test) }
- 若想让自定义事件只能触发一次,可以使用
once
修饰符,或$once
方法。 - 触发自定义事件:
this.$emit('atguigu',数据)
- 解绑自定义事件
this.$off('atguigu')
- 组件上也可以绑定原生DOM事件,需要使用
native
修饰符。 - 注意:通过
this.$refs.xxx.$on('atguigu',回调)
绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!
- 第一种方式,在父组件中:
- pubsub-js:vue当中几乎不用 全能
- 插槽
- vuex
vue 模块字符串
基础用法${}用``包裹起来
method:{
demo(trademark){
this.searchParams.trademark=`${trademark.tmId}:${trademark.tmName}`
this.getDate()
}
}
动态样式
用 :class={‘样式’:true/false} 形式
<span v-show="isOne" class="iconfont" :class="{'icon-up':isAsc,'icon-down':isDesc}"></span>
分页器
一般使用Element-ui超级简单
分页器展示需要的数据
pageNo:当前第几个
pageSize:代表每一页展示多少条数据
total:代表整个分页一共要展示多少条数据
continus:代表分页连续页码个数
触发事件
分页器点击页数,触发事件,父组件进行展示商品
自定义事件:
分页器中:
methods: {
/*
将当前页码改为指定页码
*/
changeCurrentPage (page) {
// 修改当前页码
this.mcPage = page
// 通知外部父组件
this.$emit('currentChange', page)
}
},
父组件中:
<Pagination :currentPage="searchParams.pageNo" :pageSize="searchParams.pageSize" :total="total" @currentChange="currentChange" />
methods: {
currentChange(page){
this.searchParams.pageNo=page;
this.getDate()
},
放大镜
需要:蒙版,左边一个div放正常照片,右边一个div放放大的照片,右边默认是隐藏的
<template>
<div class="spec-preview" ref="preview">
<img :src="imgObj.imgUrl" />
<div class="event" @mousemove="handler"></div>
<div class="big" >
<img :src="imgObj.imgUrl" ref="big"/>
</div>
<div class="mask" ref="mask"></div>
</div>
</template>
其中,右边放的背景照片移动方向和蒙版反方向,*2是因为放大了两倍
methods:{
handler(){
let mask=this.$refs.mask;
let big=this.$refs.big;
let left=event.offsetX-mask.offsetWidth/2;
let top=event.offsetY-mask.offsetHeight/2;
if(left<0){
left=0;
}else if(left>this.$refs.preview.offsetWidth-mask.offsetWidth){
left=this.$refs.preview.offsetWidth-mask.offsetWidth;
}
if(top<0){
top=0;
}else if(top>this.$refs.preview.offsetHeight-mask.offsetHeight){
top=this.$refs.preview.offsetHeight-mask.offsetHeight;
}
mask.style.left=left+'px';
mask.style.top=top+'px';
big.style.top=-top*2+'px';
big.style.left=-left*2+'px';
}
},
<style lang="less">
.spec-preview {
position: relative;
width: 400px;
height: 400px;
border: 1px solid #ccc;
img {
width: 100%;
height: 100%;
}
.event {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 998;
}
.mask {
width: 50%;
height: 50%;
background-color: rgba(0, 255, 0, 0.3);
position: absolute;
left: 0;
top: 0;
display: none;
}
.big {
width: 100%;
height: 100%;
position: absolute;
top: -1px;
left: 100%;
border: 1px solid #aaa;
overflow: hidden;
z-index: 998;
display: none;
background: white;
img {
width: 200%;
max-width: 200%;
height: 200%;
position: absolute;
left: 0;
top: 0;
}
}
.event:hover~.mask,
.event:hover~.big {
display: block;
}
}
</style>
浏览器存储
本地存储:
持久化存储
localStorage.setItem('uuid_token',uuid)
会话存储:
非持久化存储,关闭浏览器就没了
sessionStorage.setItem('uuid_token',uuid)
游客获取数据
在src文件夹下新建utils文件夹
在uuid_token.js中
import { v4 as uuidv4 } from 'uuid';
export const getUUID = () => {
let uuid=localStorage.getItem('uuid_token')
if(!uuid){
uuid=uuidv4()
localStorage.setItem('uuid_token',uuid)
}
return uuid
}
在商品详情页的store中
import { getUUID } from '@/utils/uuid_token'
const state = {
detailInfo:{}, // 商品详情信息
uuid_token:getUUID(), // 商品sku相关信息对象
}
在api文件夹下的request.js中
在请求拦截器中
//请求头添加一个字段(userTempId): 临时用户标识,事先和后台老师约定好的,不是固定的
if(store.state.detail.uuid_token){
config.headers.userTempId = store.state.detail.uuid_token
}
Token
定义:用户令牌,由服务器派发给用户的唯一标识
储存在vuex中,然后在发送axios请求时,在请求拦截器中,将token赋值给config.headers.token
本地存储token
在utils文件夹下新建token.js文件
export const setToken = (token) => {
localStorage.setItem('token_key', token);
}
export const getToken = () => {
return localStorage.getItem('token_key');
}
export const removeToken = () => {
localStorage.removeItem('token_key');
}
在store中的user文件夹下
const state = {
code: '',
token: getToken(),
userInfo: {},
}
const mutations = {
MUTATE_Token(state, data) {
state.token = data;
setToken(data)
},
}
const actions={
async userLogin({ commit }, userInfo) {
const result = await reqLogin(userInfo);
if (result.code === 200) {
console.log("登录成功",result.data);
commit('MUTATE_Token', result.data.token);
return 'ok';
} else {
console.log("登录失败",result.data);
return Promise.reject(new Error('failed'));
}
}
在 api文件下request.js中
import store from '@/store'
// 请求拦截器
request.interceptors.request.use(config => {
//需要携带token的请求
if(store.state.user.token){
config.headers.token = store.state.user.token
}
//显示进度条
nprogress.start();
return config}
);
登录后在detail中挂载一个函数,获取用户信息
axios同步异步请求
//同步
async init(id) {
await this.initA()
await this.initB(id)
},
initA(){
//先执行A成功,再执行B
}
initB(){
//先执行A成功后,再执行B
}
//异步
init(id){
this.initA()
this.initB()
}
initA(){
//同时执行A和B
}
initB(){
//同时执行A和B
}
组件使用api
在main.js中引入api,将其赋给Vue的原型
注意:vue的原型===vc的原型的原型,vc是vue原型的实例
//引入api
import * as API from '@/api'
new Vue({
render: h => h(App),
//全局注册事件总线
beforeCreate(){
Vue.prototype.$API = API
},
router,
//注册store
store
}).$mount('#app')
element-ui
安装
推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。
npm i element-ui -S
安装 babel-plugin-component:
npm install babel-plugin-component -D
在bable.config.js中
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
使用
在main.js中引入
import { Button, Select } from 'element-ui';
//引入element样式
import 'element-ui/lib/theme-chalk/index.css';
注册组件
三种方式:
1.注册为全局组件
Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
2.直接use
Vue.use(Button)
Vue.use(Select)
3.挂在原型上
使用于特定的一些组件
Vue.prototype.$loading = Loading.service;
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
Vue.prototype.$message = Message;