• Vue2学习笔记


    第一章(基础)

    点击事件

    事件修饰符

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    组件

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
    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:``,
            data() {
                return {
                    count:0
                }
            },
            methods: {
                addCount() {
                    this.count++
                }
            }
        })
        var app = new Vue({
            el:"#app",
            data:{
    
            },
            // 局部注册
            components:{
                buttonCounter
            },
            methods: {
    
            },
        });
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 datacomputedwatchmethods 以及生命周期钩子等。

    第二章-组件

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

    新建组件

    components目录下新建Student.vue

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    组件注册

    全局注册

    main.js下进行全局注册

    import Student from "./components/Student"
    Vue.component('Student',Student)
    
    • 1
    • 2

    App.vue中使用

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    局部注册

    App.vue中进行局部注册

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    数据传递

    通过Prop向子组件传递数据

    Prop 是我们可以在组件上注册的一些自定义属性。当一个值传递给一个 prop 属性的时候,它就变成了那个组件实例的一个属性。

    Student组件传递学生列表信息

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    Student组件接收数据

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    **注意:**v-model绑定的值不能是props传过来的值,因为props是不可以修改的。

    子组件向父组件传递数据

    父组件需要先定义一个方法,通过props传递给子组件,然后子组件就可以直接调用这个传递过来的方法。通过该方法可以实现子组件向父组件传递传递数据。

    Student组件为例,在Student组件新增一个添加学生信息的功能并将学生信息传递给父组件的studentList

    父组件传递方法给子组件

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    子组件调用父组件的方法

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    组件自定义事件

    使用场景

    A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)

    使用方式
    父组件

    第一种方式

    
    或者
    
    
    • 1
    • 2
    • 3

    若想让自定义事件只能触发一次,可以使用once修饰符

    
    或者
    
    
    • 1
    • 2
    • 3

    第二种方式

    <Student ref="studentDemo" />
    
    export default {
      ......
      methods:{
        addStudent(student) {
          this.studentList.unshift(student)
        }
      },
      mounted() {
        this.$refs.studentDemo.$on("addStudent",this.addStudent)
      },
      ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    若想让自定义事件只能触发一次,可以使用$once方法

    this.$refs.studentDemo.$once("addStudent",this.addStudent)
    
    • 1
    子组件触发事件

    子组件触发自定义事件

    this.$emit("addStudent",数据)
    
    • 1
    子组件解除自定义事件
    // 解除一个
    this.$off("addStudent")
    // 解除多个
    this.$off(["addStudent"])
    // 解除所有的自定义事件
    this.$off()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    全局事件总线

    一种组件间通信的方式,适用于任意组件间通信。

    安装

    main.js中安装

    new Vue({
      render: h => h(App),
      beforeCreate() {
        // 安装总线
        Vue.prototype.$bus = this
      }
    }).$mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    绑定事件

    在需要接收数据的组件中绑定事件,当有组件触发事件时就会回调到这里

    ......
    ,
    methods:{
    	addStudent(student) {
    	  this.studentList.unshift(student)
    	}
    },
    mounted() {
      // 绑定事件
    	this.$bus.$on("addStudent", this.addStudent)
    },
    beforeDestroy() {
        // 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件
        this.$bus.$off("addStudent")
    }
    ......
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    触发事件

    // 触发绑定的事件
    this.$bus.$emit("addStudent",student)
    
    • 1
    • 2

    第三章-Vuex

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。主要适用于多个组件需要共享数据的场景。

    安装

    默认会安装最新的vuex,而vue2只能用vuex的3版本,所以安装时指定对应的版本号

    # 指定版本号
    cnpm i vuex@3 --save
    # 不指定版本号
    cnpm i vuex --save
    
    • 1
    • 2
    • 3
    • 4

    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
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    基本使用

    // 引入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
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    读取数据

    this.$store.state.count
    
    • 1

    修改数据

    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
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    组件中读取$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']),
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    mapGetters

    用于帮助我们映射getters中的数据为计算属性。使得我们访问getters中的数据就跟访问data中的数据一样。

    import {mapGetters} from 'vuex'
    export default {
      name: 'App',
      data(){
        return {
    
        }
      },
      computed: {
        // 借助 mapGetters生成计算属性:bigCount(对象写法)
        // ...mapGetters({bigCount:'bigCount'})
        // 借助 mapGetters生成计算属性:bigCount(数组写法)
        ...mapGetters(['bigCount'])
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    mapActions

    用于帮助我们生成与actions对应的方法,使得我们访问actions中的方法就跟访问methods中的数据一样。

    若需要传递参数,在模板中绑定事件时传递好参数,否则参数是事件对象,如actionAddCount(2)

    import {mapActions} from 'vuex'
    export default {
      methods:{
        
        // ...mapActions({actionAddCount:'actionAddCount'})
        ...mapActions(['actionAddCount'])
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    mapMutations

    用于帮助我们生成与mapMutations对应的方法,使得我们访问mapMutations中的方法就跟访问methods中的数据一样。

    若需要传递参数,在模板中绑定事件时传递好参数,否则参数是事件对象,如addCount(2)

    import {mapMutations} from 'vuex'
    export default {
      methods:{
        // 靠mapMutations生成:addCount(对象形式)
        // ...mapMutations({addCount:'addCount'}),
        // 靠mapMutations生成:addCount(数组形式)
        ...mapMutations(['addCount']),
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    模块化

    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,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
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    读取state数据

    // 方式一:自己直接读取
    $store.state.moduleA.count
    // 方式二:借助mapState读取:
    ...mapState('moduleA',['count']),
    
    • 1
    • 2
    • 3
    • 4

    读取getters数据

    // 方式一:自己直接读取
    this.$store.getters['moduleA/bigCount']
    // 方式二:借助mapGetters读取
    ...mapGetters('moduleA',['bigCount'])
    
    • 1
    • 2
    • 3
    • 4

    调用Mutation

    //方式一:自己直接commit
    this.$store.commit('moduleA/addCount',2)
    //方式二:借助mapMutations:
    ...mapMutations('moduleA',['addCount']),
    
    • 1
    • 2
    • 3
    • 4

    调用Action

    //方式一:自己直接dispatch
    this.$store.dispatch('moduleA/actionAddCount',2)
    //方式二:借助mapActions:
    ...mapActions('moduleA',['actionAddCount'])
    
    • 1
    • 2
    • 3
    • 4

    第四章-路由

    安装

    # vue2只能安装vue-router的版本3
     cnpm install vue-router@3 --save-dev
    
    
    # 安装最新版本 vue-router
    cnpm install vue-router --save-dev
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    基本使用

    在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"
            },
        ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在组件中使用

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    多级路由

    通过children配置子级路由

    export default new VueRouter({
        routes:[
            {
                path:'/home',
                component:Home,
                children:[ // 通过children配置子级路由
                    {
                        path:'news',
                        component:News
                    },
                    {
                        path:'message',
                        component:Message,
                    }
                ]
            },
         
        ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    跳转要写完整路径

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    路由的query参数

    参数传递

    
    跳转
    
    
    	跳转
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    接收参数

    $route.query.id
    $route.query.title
    
    • 1
    • 2

    路由的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
                            }
                        ]
                    }
                ]
            }
        ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    参数传递

    
    跳转
    
    
    
      跳转
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    参数接收

    $route.params.id
    $route.params.title
    
    • 1
    • 2

    路由的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 
                                    }
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    接收数据

    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    编程式路由导航

    不借助实现路由跳转,让路由跳转更加灵活

    // 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() //可前进也可后退
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    缓存路由组件

    路由跳转不同组件时保持挂载,不被销毁。

    
    	
    
    
    • 1
    • 2
    • 3

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    路由守卫

    对路由进行权限控制,主要有三类:全局守卫、独享守卫、组件内守卫

    全局守卫

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    独享守卫

    // 该文件专门用于创建整个应用的路由器
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    组件内守卫

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    第五章-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)
    		});
    	})
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    新建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);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用

    // 引入
    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)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    安装less

    # vue2中less-loader安装7版本的
    npm install less less-loader@7.0.0 --save
    
    • 1
    • 2

    style中加入lang="less"才会生效

    
    
    • 1
    • 2
    • 3

    引入 Element

    npm i element-ui -S
    
    • 1

    按需引入
    借助 babel-plugin-component,可以只引入需要的组件,以达到减小项目体积的目的。
    首先,安装 babel-plugin-component

    npm install babel-plugin-component -D
    
    • 1

    然后,将 babel.config.js修改为:

    module.exports = {
      presets: [
        '@vue/cli-plugin-babel/preset',
    	["@babel/preset-env", { "modules": false }]
      ],
        "plugins": [
          [
            "component",
            {
              "libraryName": "element-ui",
              "styleLibraryName": "theme-chalk"
            }
          ]
        ]
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    接下来,如果你只希望引入部分组件,比如 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)
    });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    实现一个消息通知工具类

    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
    	});
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    使用

    import {warningMsg} from '@/common/MessageUtils.js';
    
    warningMsg("警告信息");
    
    • 1
    • 2
    • 3

    多级菜单实现

    新建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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    新建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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    Linux系统编程--IO
    如何对待工作中的失误
    PEG/蛋白Protein/抗体antibody 功能化修饰硫化锌量子点 ZnS QDs
    单分散Eu3+-PS荧光微球/吸附荧光素生物素化聚苯乙烯微球/包覆TiO2粉体的制备方式
    Linux CentOS7 用户组管理
    最佳实践-使用Github Actions来构建跨平台容器镜像
    Java 实现统计文件字符
    springboot系列(二十六):如何实现word模板单页导出?这你得会|超级详细,建议收藏
    Python爬虫--xpath
    多目标优化算法:基于非支配排序的麻雀搜索算法(Non-Dominated Sorting Sparrow Search Algorithm,NSSSA)
  • 原文地址:https://blog.csdn.net/lizc_lizc/article/details/126696315