第一章(基础)
点击事件
事件修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1 style="text-align: center">{{ message }}</h1>
<p>1.阻止默认事件</p>
<a href="http://www.baidu.com" @click.prevent="showInfo">查看当前时间</a>
<p>2.阻止冒泡事件</p>
<div style="background: red;width: 200px;height: 200px" @click="showInfo">
<button @click.stop="showInfo">查看当前时间</button>
</div>
<p>3.事件只触发一次</p>
<button @click.once="showInfo">查看当前时间</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data: {
message: "常用的事件修饰符"
},
methods: {
showInfo() {
alert("当前时间:"+new Date())
}
}
});
</script>
</html>
组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div id="root">
<button-counter></button-counter>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 定义一个名为 button-counter 的新组件
const buttonCounter = Vue.extend({
template:`<button v-on:click="addCount">You clicked me {{ count }} times.</button>`,
data() {
return {
count:0
}
},
methods: {
addCount() {
this.count++
}
}
})
var app = new Vue({
el:"#app",
data:{
},
// 局部注册
components:{
buttonCounter
},
methods: {
},
});
</script>
</html>
因为组件是可复用的 Vue
实例,所以它们与 new Vue
接收相同的选项,例如 data
、computed
、watch
、methods
以及生命周期钩子等。
第二章-组件
组件主要是为了模块化和代码的复用,将一个大的页面划分为不同的模块,每个小模块就是一个组件,而每一个组件都可以复用在不同的页面当中。
新建组件
在components
目录下新建Student.vue
<template>
<div>
<h2>{{title}}</h2>
</div>
</template>
<script>
export default {
name: "Student",
// 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
data() {
return {
title:"学生信息"
}
}
}
</script>
组件注册
全局注册
在main.js
下进行全局注册
import Student from "./components/Student"
Vue.component('Student',Student)
在App.vue
中使用
<template>
<div id="app">
<h1 style="text-align: center">首页</h1>
<Student />
</div>
</template>
局部注册
在App.vue
中进行局部注册
<template>
<div id="app">
<h1 style="text-align: center">首页</h1>
<Student />
</div>
</template>
<script>
import Student from "./components/Student";
export default {
name: 'App',
components: {
"Student":Student,
//Student, // 当key与value的值一样时,也可以简写成写成Student
}
}
</script>
数据传递
通过Prop向子组件传递数据
Prop 是我们可以在组件上注册的一些自定义属性。当一个值传递给一个 prop 属性的时候,它就变成了那个组件实例的一个属性。
向Student
组件传递学生列表信息
<template>
<div id="app">
<h1 style="text-align: center">首页</h1>
<!-- 通过属性将数据传递给子组件 -->
<Student :studentList="studentList" />
</div>
</template>
<script>
import Student from "./components/Student";
export default {
name: 'App',
data(){
return {
studentList:[
{id:"001",name:"李华"},
{id:"002",name:"李四"},
]
}
},
components: {
"Student":Student
}
}
</script>
Student
组件接收数据
<template>
<div>
<h2>{{title}}</h2>
<ul>
<li v-for="student in studentList" :key="student.id">{{student.name}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Student",
// 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
data() {
return {
title:"学生信息"
}
},
// 一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
// 我们能够在组件实例中访问这个值,就像访问 data 中的值一样。
props:["studentList"]
}
</script>
**注意:**v-model绑定的值不能是props传过来的值,因为props是不可以修改的。
子组件向父组件传递数据
父组件需要先定义一个方法,通过props传递给子组件,然后子组件就可以直接调用这个传递过来的方法。通过该方法可以实现子组件向父组件传递传递数据。
以Student
组件为例,在Student
组件新增一个添加学生信息的功能并将学生信息传递给父组件的studentList
父组件传递方法给子组件
<template>
<div id="app">
<h1 style="text-align: center">首页</h1>
<!-- 通过属性将方法传递给子组件 -->
<Student :studentList="studentList" :addStudent="addStudent"/>
</div>
</template>
<script>
import Student from "./components/Student";
export default {
name: 'App',
data(){
return {
studentList:[
{id:"001",name:"李华"},
{id:"002",name:"李四"},
]
}
},
methods:{
addStudent(student) {
this.studentList.unshift(student)
}
},
components: {
"Student":Student
}
}
</script>
子组件调用父组件的方法
<template>
<div>
<h2>{{title}}</h2>
<input v-model="name"> <button @click="add">添加学生</button>
<ul>
<li v-for="student in studentList" :key="student.id">{{student.name}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "Student",
// 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
data() {
return {
title:"学生信息",
name:""
}
},
// 一个组件默认可以拥有任意数量的 prop,任何数据或者方法都可以传递给任何 prop。
// 我们能够在组件实例中访问这个数据或者方法,就像访问 data/methods 一样。
props:["studentList","addStudent"],
methods: {
add() {
const student = {
id: Date.now(),
name: this.name
}
this.addStudent(student)
}
}
}
</script>
组件自定义事件
使用场景
A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)
使用方式
父组件
第一种方式
<Student @addStudent="addStudent" />
或者
<Student v-on:addStudent="addStudent" />
若想让自定义事件只能触发一次,可以使用once
修饰符
<Student @addStudent.once="addStudent" />
或者
<Student v-on:addStudent.once="addStudent" />
第二种方式
<Student ref="studentDemo" />
export default {
......
methods:{
addStudent(student) {
this.studentList.unshift(student)
}
},
mounted() {
this.$refs.studentDemo.$on("addStudent",this.addStudent)
},
......
}
若想让自定义事件只能触发一次,可以使用$once
方法
this.$refs.studentDemo.$once("addStudent",this.addStudent)
子组件触发事件
子组件触发自定义事件
this.$emit("addStudent",数据)
子组件解除自定义事件
// 解除一个
this.$off("addStudent")
// 解除多个
this.$off(["addStudent"])
// 解除所有的自定义事件
this.$off()
全局事件总线
一种组件间通信的方式,适用于任意组件间通信。
安装
在main.js
中安装
new Vue({
render: h => h(App),
beforeCreate() {
// 安装总线
Vue.prototype.$bus = this
}
}).$mount('#app')
绑定事件
在需要接收数据的组件中绑定事件,当有组件触发事件时就会回调到这里
......
,
methods:{
addStudent(student) {
this.studentList.unshift(student)
}
},
mounted() {
// 绑定事件
this.$bus.$on("addStudent", this.addStudent)
},
beforeDestroy() {
// 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件
this.$bus.$off("addStudent")
}
......
触发事件
// 触发绑定的事件
this.$bus.$emit("addStudent",student)
第三章-Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。主要适用于多个组件需要共享数据的场景。
安装
默认会安装最新的vuex,而vue2只能用vuex的3版本,所以安装时指定对应的版本号
# 指定版本号
cnpm i vuex@3 --save
# 不指定版本号
cnpm i vuex --save
在src/store
目录里面新建index.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备state对象:保存具体的数据
const state = {
}
// 准备mutations对象:修改state中的数据
const mutations = {
}
// 准备actions对象:响应组件中用户的动作
const actions = {
}
// 创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state
})
在main.js
中引入
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store
}).$mount('#app')
基本使用
// 引入Vue核心库
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 应用Vuex插件
Vue.use(Vuex)
// 准备state对象——保存具体的数据
const state = {
count:0
}
// 准备mutations对象——修改state中的数据
// 一条重要的原则就是要记住 mutation 必须是同步函数。
// https://vuex.vuejs.org/zh/guide/mutations.html
const mutations = {
// 对state中的count字段进行加法操作
addCount(state,value) {
console.log('mutations中的addCount被调用了', state, value)
state.count += value
}
}
// 准备actions对象——响应组件中用户的动作
const actions = {
// 对state中的count字段进行加法操作
actionAddCount(context,value) {
console.log('actions中的actionAddCount被调用了', context, value)
// actions 中的方法最终也是调用的mutations里面的方法
// 在调用mutations中的方法前可以做一些其它操作
context.commit('addCount',value)
}
}
// 创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state
})
读取数据
this.$store.state.count
修改数据
this.$store.dispatch('action中的方法名',参数)
或者 this.$store.commit('mutations中的方法名',参数)
getters的使用
当state中的数据需要经过加工后再使用时,可以使用getters加工。在store.js
中追加getters
配置
......
const getters = {
bigCount(state){
// 将count放大十倍
return state.count * 10
}
}
// 创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
getters
})
组件中读取$store.getters.bigCount
四个辅助函数
mapState
用于帮助我们映射state
中的数据为计算属性。使得我们访问state
中的数据就跟访问data
中的数据一样
import {mapState} from 'vuex'
export default {
name: 'App',
data(){
return {
}
},
computed: {
// 借助mapState生成计算属性:count(对象写法)
// ...mapState({count:'count'}),
// 借助mapState生成计算属性:count(数组写法)
...mapState(['count']),
},
}
mapGetters
用于帮助我们映射getters
中的数据为计算属性。使得我们访问getters
中的数据就跟访问data
中的数据一样。
import {mapGetters} from 'vuex'
export default {
name: 'App',
data(){
return {
}
},
computed: {
// 借助 mapGetters生成计算属性:bigCount(对象写法)
// ...mapGetters({bigCount:'bigCount'})
// 借助 mapGetters生成计算属性:bigCount(数组写法)
...mapGetters(['bigCount'])
}
}
mapActions
用于帮助我们生成与actions
对应的方法,使得我们访问actions
中的方法就跟访问methods
中的数据一样。
若需要传递参数,在模板中绑定事件时传递好参数,否则参数是事件对象,如actionAddCount(2)
import {mapActions} from 'vuex'
export default {
methods:{
// ...mapActions({actionAddCount:'actionAddCount'})
...mapActions(['actionAddCount'])
}
}
mapMutations
用于帮助我们生成与mapMutations
对应的方法,使得我们访问mapMutations
中的方法就跟访问methods
中的数据一样。
若需要传递参数,在模板中绑定事件时传递好参数,否则参数是事件对象,如addCount(2)
import {mapMutations} from 'vuex'
export default {
methods:{
// 靠mapMutations生成:addCount(对象形式)
// ...mapMutations({addCount:'addCount'}),
// 靠mapMutations生成:addCount(数组形式)
...mapMutations(['addCount']),
}
}
模块化
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
修改src/store/index.js
// 引入Vue核心库
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 应用Vuex插件
Vue.use(Vuex)
const moduleA = {
namespaced:true,// 开启命名空间
state:{},
mutations: {},
actions: {},
getters: {}
}
const moduleB = {
namespaced:true, // 开启命名空间
state:{},
mutations: {},
actions: {},
getters: {}
}
// 创建并暴露store
export default new Vuex.Store({
modules:{
moduleA:moduleA,
moduleB:moduleB
}
})
读取state数据
// 方式一:自己直接读取
$store.state.moduleA.count
// 方式二:借助mapState读取:
...mapState('moduleA',['count']),
读取getters数据
// 方式一:自己直接读取
this.$store.getters['moduleA/bigCount']
// 方式二:借助mapGetters读取
...mapGetters('moduleA',['bigCount'])
调用Mutation
//方式一:自己直接commit
this.$store.commit('moduleA/addCount',2)
//方式二:借助mapMutations:
...mapMutations('moduleA',['addCount']),
调用Action
//方式一:自己直接dispatch
this.$store.dispatch('moduleA/actionAddCount',2)
//方式二:借助mapActions:
...mapActions('moduleA',['actionAddCount'])
第四章-路由
安装
# vue2只能安装vue-router的版本3
cnpm install vue-router@3 --save-dev
# 安装最新版本 vue-router
cnpm install vue-router --save-dev
基本使用
在src/router
下新建index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
import Vue from 'vue'
// 引入组件
import Home from '../components/Home'
import UserCenter from '../components/UserCenter'
Vue.use(VueRouter)
//创建并暴露一个路由器
export default new VueRouter({
routes:[
{
path:'/userCenter',
component:UserCenter
},
{
path:'/home',
component:Home
},
{
path: '/', // 这样就会重定向到/home
redirect: "/home"
},
]
})
在main.js
中注册
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
router
}).$mount('#app')
在组件中使用
<template>
<div id="app">
<h1 style="text-align: center">首页</h1>
<div>
<span style="padding: 15px;">
<router-link active-class="active" to="/home">home</router-link>
</span>
<span style="padding: 15px;">
<router-link active-class="active" to="/userCenter">userCenter</router-link>
</span>
</div>
<div>
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view/>
</div>
</div>
</template>
多级路由
通过children配置子级路由
export default new VueRouter({
routes:[
{
path:'/home',
component:Home,
children:[ // 通过children配置子级路由
{
path:'news',
component:News
},
{
path:'message',
component:Message,
}
]
},
]
})
跳转要写完整路径
<template>
<div>
<h1 style="text-align: center">Home</h1>
<div>
<span style="padding: 15px;">
<router-link active-class="active" to="/home/news">news</router-link>
</span>
<span style="padding: 15px;">
<router-link active-class="active" to="/home/message">message</router-link>
</span>
</div>
<div>
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
</div>
</template>
路由的query参数
参数传递
<!-- 跳转并携带query参数,to的字符串写法 -->
<router-link to="/home/message/detail?id=666&title=你好">跳转</router-link>
<!-- 跳转并携带query参数,to的对象写法 -->
<router-link :to="{
path:'/home/message/detail',
query:{
id:'001',
title:'标题001'
}
}">
跳转
</router-link>
接收参数
$route.query.id
$route.query.title
路由的params参数
配置路由,声明接收params参数
export default new VueRouter({
routes:[
{
path:'/home',
component:Home,
children:[ // 通过children配置子级路由
{
path:'news',
component:News
},
{
path:'message',
component:Message,
children:[
{
// 使用占位符声明接收params参数
path:'detail/:id/:title',
// 给地址取名 可以直接通过这个名字跳转页面 不需要写全地址
name:'xiangqing',
component: MessageDetail
}
]
}
]
}
]
})
参数传递
<!-- 跳转并携带params参数,to的字符串写法 -->
<router-link to="/home/message/detail/666/你好">跳转</router-link>
<!-- 跳转并携带params参数,to的对象写法 必须使用name配置 -->
<router-link :to="{name:'xiangqing',params:{id:888,title:'哈哈哈'}}">
跳转
</router-link>
参数接收
$route.params.id
$route.params.title
路由的props配置
让路由组件更方便的收到参数
export default new VueRouter({
routes:[
{
path:'/home',
component:Home,
children:[ // 通过children配置子级路由
{
path:'message',
component:Message,
children:[
{
path:'detail',
// 给地址取名 可以直接通过这个名字跳转页面 不需要写全地址
name:'xiangqing',
component: MessageDetail,
props($route){
return {
// 这里是query方式 params方式:id:$route.params.id,
id:$route.query.id,
title:$route.query.title
}
}
}
]
}
]
}
]
})
接收数据
<template>
<div>
<h1 style="text-align: center">MessageDetail</h1>
<ul>
<li>消息编号:{{id}}</li>
<li>消息标题:{{title}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "MessageDetail",
props:['id','title']
}
</script>
编程式路由导航
不借助<router-link>
实现路由跳转,让路由跳转更加灵活
// query方式
this.$router.push({
path:'/home/message/detail',
query:{
id:'123',
title:'哈哈哈'
}
})
// params 方式
this.$router.push({
name:'xiangqing',
params:{
id:'123',
title:'哈哈哈'
}
})
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退
缓存路由组件
路由跳转不同组件时保持挂载,不被销毁。
<keep-alive include="News,Message">
<router-view></router-view>
</keep-alive>
keep-alive
是 vue 中的内置组件,能够在组件切换过程中将状态保留在内存中,防止重复的渲染 DOM;
keep-alive
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们;
keep-alive
可以设置一下 props 属性:
include
字符串或者是正则表达式。只有名称匹配的组件才能被缓存
exclude
字符串或者是正则表达式。
max
数字。最多可以缓存多少组件实例。
匹配首先是检查自身的 name 选项,如果 name 属性不可用,则匹配它的局部注册名称,也就是父组件中 components 选项的键值,匿名组件不能被匹配。
设置了keep-alive
缓存的组件,会多出两个生命周期钩子activated
和deactivated
<script>
export default {
name: "News",
activated() {
console.log('xxx组件被激活了')
},
deactivated() {
console.log('xxx组件失活了')
},
}
</script>
路由守卫
对路由进行权限控制,主要有三类:全局守卫、独享守卫、组件内守卫
全局守卫
const router = new VueRouter({
routes:[
{
path:'/userCenter',
component:UserCenter,
meta:{
isAuth:true
}
},
{
path:'/home',
component:Home,
},
{
path: '/', // 这样就会重定向到/home
redirect: "/home"
},
]
})
// 全局前置路由守卫————初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to,from,next)=>{
console.log('前置路由守卫', to, from)
if(to.meta.isAuth){ // 判断是否需要鉴权
if(localStorage.getItem('user')==='lzc'){
// 继续往下走
next()
}else{
alert('未登录,无权限查看')
}
}else{
next()
}
})
// 全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to,from)=>{
console.log('后置路由守卫', to, from)
})
export default router
独享守卫
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
import Vue from 'vue'
// 引入组件
import Home from '../components/Home'
import UserCenter from '../components/UserCenter'
Vue.use(VueRouter)
const router = new VueRouter({
routes:[
{
path:'/home',
meta:{
isAuth:true
},
component:Home,
beforeEnter(to,from,next){
console.log('beforeEnter', to, from)
if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
if(localStorage.getItem('user') === 'lzc'){
next()
}else{
alert('暂无权限查看')
}
}else{
next()
}
},
}
]
})
export default router
组件内守卫
<script>
export default {
name: "Home",
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
console.log('beforeRouteEnter', to, from)
next()
},
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {
console.log('beforeRouteLeave', to, from)
next()
}
}
</script>
第五章-axios
新建http.js
封装get
、post
等请求
import axios from 'axios'
import {Message} from 'element-ui'
/**
*
* 后端设置 Access-Control-Max-Age, 用来指定本次预检请求的有效期
* 单位为秒, 在此期间不用发出另一条预检请求
* httpResponse.addHeader("Access-Control-Max-Age", "86400");
*
* 使用自定义配置新建一个 axios 实例
* 文档地址:http://www.axios-js.com/zh-cn/docs/#axios-create-config
*
*/
const instance = axios.create({
baseURL: getBaseUrl(),
// 超时时间
timeout: 3000,
/**
* 为true时允许携带cookie
* 如果设置true: 后端设置 Access-Control-Allow-Origin不能为"*" 必须是源地址
* 如: httpResponse.setHeader("Access-Control-Allow-Origin", httpRequest.getHeader("origin"));
*/
withCredentials:true,
headers: {'token':'xxxxxx'}
});
function getBaseUrl() {
// 根据环境返回不同的地址
console.log('getBaseUrl', process.env.NODE_ENV)
if (process.env.NODE_ENV === 'development') {
return 'http://localhost:8088'
} else if (process.env.NODE_ENV === 'production') {
return '生产地址'
}
}
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
console.log("interceptors.request",config)
// 在发送请求之前做些什么
return config;
}, function (error) {
console.log("interceptors.request.error",error)
return Promise.reject(error);
});
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
console.log("interceptors.response",response)
// 对响应数据做点什么
return response;
}, function (error) {
console.log('interceptors.response.error',error)
Message.error(error.message)
// 对响应错误做点什么
return Promise.reject(error);
});
/**
* @param {Object} url 接口地址
* @param {Object} params 请求参数
* @param {Object} config 配置, 用来覆盖默认配置
*/
export function get(url, params, config){
return new Promise((resolve, reject) =>{
instance.get(url,{
params:params,
// baseURL: 'http://xxxxxx' 这里也可以指定来覆盖默认的
...config
})
.then(function (response) {
resolve(response.data)
})
.catch(function (error) {
reject(error.message)
});
})
}
/**
* @param {Object} url 接口地址
* @param {Object} params 请求参数
* @param {Object} config 配置, 用来覆盖默认配置
*/
export function post(url, params, config){
return new Promise((resolve, reject) =>{
instance.request({
url:url,
method:'post',
data:params,
...config
})
.then(function (response) {
resolve(response.data)
})
.catch(function (error) {
reject(error.message)
});
})
}
新建api.js
用来管理接口
import {get,post} from './http.js'
export const apiTest1 = (params,config) => get("/test1",params,config);
export const apiTest2 = (params,config) => post("/test2",params,config);
使用
// 引入
import {apiTest1,apiTest2} from './utils/api.js'
// 调用 apiTest1
apiTest1({
q:"923226145"
}).then(data=>{
console.log("get data success:",data)
},error=>{
console.log("get data error:",error)
})
// 调用apiTest2
apiTest2({
username:"923226145",
age:20
}).then(data=>{
console.log("get data success:",data)
},error=>{
console.log("get data error:",error)
})
安装less
# vue2中less-loader安装7版本的
npm install less less-loader@7.0.0 --save
在style
中加入lang="less"
才会生效
<style scoped lang="less">
</style>
引入 Element
npm i element-ui -S
按需引入
借助 babel-plugin-component
,可以只引入需要的组件,以达到减小项目体积的目的。
首先,安装 babel-plugin-component
npm install babel-plugin-component -D
然后,将 babel.config.js修改为:
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
["@babel/preset-env", { "modules": false }]
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
接下来,如果你只希望引入部分组件,比如 Button
和 Select
,那么需要在 main.js
中写入以下内容:
import Vue from 'vue';
import { Button, Select } from 'element-ui';
import App from './App.vue';
Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
new Vue({
el: '#app',
render: h => h(App)
});
实现一个消息通知工具类
import {Message} from 'element-ui';
/**
* 定义消息提示工具类:这里使用的是 element-ui
*/
export function successMsg(msg, duration = 3000, showClose = false) {
Message({
message: msg,
type: 'success',
duration: duration,
showClose: showClose
});
}
export function warningMsg(msg, duration = 3000, showClose = false) {
Message({
message: msg,
type: 'warning',
duration: duration,
showClose: showClose
});
}
export function errorMsg(msg, duration = 3000, showClose = false) {
Message({
message: msg,
type: 'error',
duration: duration,
showClose: showClose
});
}
使用
import {warningMsg} from '@/common/MessageUtils.js';
warningMsg("警告信息");
多级菜单实现
新建MenuNode.vue
<template>
<el-submenu v-if="menuInfo.childrenList" :index="menuInfo.id">
<template slot="title">
<i class="el-icon-location"></i>
<span>{{menuInfo.title}}</span>
</template>
<MenuNode v-for="node in menuInfo.childrenList" :menuInfo = node :key="node.id" />
</el-submenu>
<!-- 没有子组件 -->
<el-menu-item v-else-if="!menuInfo.childrenList" :index="menuInfo.id">
<i class="el-icon-menu"></i>
<span slot="title">{{menuInfo.title}}</span>
</el-menu-item>
</template>
<script>
export default {
name:'MenuNode',
props:["menuInfo"]
}
</script>
<style>
</style>
新建MenuComponent.vue
<template>
<el-menu
default-active="2"
@select="handleSelect"
@open="handleOpen"
@close="handleClose">
<MenuNode v-for="menu in menuList" :menuInfo=menu :key="menu.id" />
</el-menu>
</template>
<script>
import MenuNode from './MenuNode.vue'
export default {
name:'MenuComponent',
components:{MenuNode},
props:["menuList"],
data(){
return {
}
},
methods: {
handleOpen(key, keyPath) {
console.log("handleOpen",key, keyPath);
},
handleClose(key, keyPath) {
console.log("handleClose",key, keyPath);
},
handleSelect(key, keyPath) {
console.log("handleSelect",key, keyPath);
}
},
}
</script>