Vue2学习笔记

第一章(基础)

点击事件

事件修饰符

<!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 接收相同的选项,例如 datacomputedwatchmethods 以及生命周期钩子等。

第二章-组件

组件主要是为了模块化和代码的复用,将一个大的页面划分为不同的模块,每个小模块就是一个组件,而每一个组件都可以复用在不同的页面当中。

新建组件

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缓存的组件,会多出两个生命周期钩子activateddeactivated

<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封装getpost等请求

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"
        }
      ]
    ]
}

接下来,如果你只希望引入部分组件,比如 ButtonSelect,那么需要在 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>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值