Vue【定制化】~ 基础知识

1、Vue基础知识

Vue生命周期: 创建 -> 初始化数据 -> 编译模板 -> 挂载Dom渲染 -> 更新渲染 -> 销毁!

1、创建Vue实例

1.1、第一种 - 创建vue实例

//创建vue挂载容器
<div id="root"></div>
<script>
    new Vue({
        el: '#root', 
        data: {}
    })
</script>

1.2、第二种 - 创建vue实例

//创建vue挂载容器
<div id="root"></div>
<script>
   const vm = new Vue({
        data: {}
    })
	vm.$mount('#root'); //作用灵活
</script>

1.3、第一种写法 - data

普通写法

new Vue({
    el: '#app',
    data: {}
})

1.4、第二种写法 - data(推荐使用)

函数写法

new Vue({
    el: '#app',
    data() {
        return {
            
        }
    }
})

2、模板语法

2.1、插值语法

语法:{{属性名}}

<div id="root">
	{{name}}
</div>
<script>
new Vue({
	el: '#root',
    data:{
        name: 'hello'
    }
})
</script>

2.2、指令语法

语法:v-bind:href=“属性名”

简写::href=“属性名”

<div id="root">
    <a v-bind:href="url">去往百度</a>
    <!-- 简写::href="" -->
    <a :href="url">去往百度</a>
</div>
<script>
    new Vue({
		el: '#root',
        data:{
            url: 'http://www.baidu.com'
        }
	})    
</script>

3、数据绑定

3.1、单向数据绑定

语法:v-bind:href =“xxx”

特点:数据只能从 data 流向页面

<div id="root">
    <a v-bind:href="url">去往百度</a>
    <!-- 简写::href="" -->
    <a :href="url">去往百度</a>
</div>
<script>
    new Vue({
		el: '#root',
        data:{
            url: 'http://www.baidu.com'
        }
	})    
</script>

3.2、双向数据绑定

语法:v-mode:value=“xxx” 或简写为 v-model=“xxx”

特点:数据不仅能从 data 流向页面,还能从页面流向 data

<div id="root">
    双向数据绑定:<input v-model="username"/>
</div>
<script>
    new Vue({
		el: '#root',
        data:{
            username: 'admin'
        }
	})    
</script>

4、事件处理

4.1、绑定监听

语法:v-on:click=“函数名” 简写 @click=“函数名”

作用:绑定事件

<!--    v-on: 简写 @click=""-->
<button v-on:click="eventBut01"> - 无参数</button><br>
<button v-on:click="eventBut02('hello')"> - 有参数</button><br>
<button v-on:click="eventBut03($event)"> - 默认参数</button><br>
<button v-on:click="eventBut04($event, '自带参数')"> - 默认参数与自带参数</button><br>
<script>
    new Vue({
        data() {
            return {

            };
        },
    	//可以定义多个函数(vue挂在容器可用)
        methods: {
            eventBut01() {
                alert('无参数')
            },
            eventBut02(name) {
                alert('有参数 - '+ name)
            },
            eventBut03(event) {
                alert('默认参数 - '+ event)
            },
            eventBut04(event, name) {
                alert('有参数 - '+ name)
                console.log(event)
            }
        }
    }).$mount('#root')
</script>

4.2、事件修饰符

(1).stop - 阻止冒泡事件( 通俗讲就是阻止事件向上级DOM元素传递)

<div id="hello">
    <div v-on:click="divFun">
        <button v-on:click.stop="butFun">按钮</button>
    </div>
</div>
new Vue({
    methods: {
        divFun() {
            console.log('外层 div 触发')
        },
        butFun() {
            console.log('but按钮触发')
        }
    }
}).$mount('#hello')

(2) .prevent - 阻止默认事件的发生,默认事件指对DOM的操作会引起自动执行的动作,比如点击超链接 的时候会进行页面的跳转,点击表单 提交按钮时会重新加载页面等,使用".prevent"修饰符可以阻止这 些事件的发生。

<!-- 点击也不会添加到百度这就是阻止a标签默认行为 -->
<a href="http://www.baidu.com" v-on:click.prevent>前往百度</a>

(3).capture - 捕获冒泡,即有冒泡发生时,有该修饰符的dom元素会先执行,如果有多个,从外到内依 次执行,然后再按自然顺序执行触发的事件。

<div id="hello">
    <div style="background-color: red; width: 300px;height: 300px;" @click.capture="div01">
        <div style="background-color: blue; width: 200px;height: 200px;" v-on:click="div02">
            <div style="background-color: yellow; width: 100px;height: 100px;" v-on:click="div03">
                <div style="background-color: pink; width: 50px;height: 50px;" v-on:click="div04"></div>
            </div>
        </div>
    </div>
</div>
new Vue({
        methods: {
            div01() {console.log('div01')},
            div02() {console.log('div02')},
            div03() {console.log('div03')},
            div04() {console.log('div04')},
        }
    }).$mount('#hello')

(4). self - 将事件绑定到自身,只有自身才能触发,通常用于避免冒泡事件的影响

(5). once - 设置事件只能触发一次,比如按钮的点击等。

​ 作用:按钮事件只触发一次

4.3、键盘事件

<div id="app">
    <input type="text" placeholder="键盘事件测试" @keydown.enter="downFun"> <br>
    <!-- 组合键位的使用 -->
    <input type="text" placeholder="键盘事件测试" @keyup.ctrl.y="upFun"> <br>
</div>
<script>
    new Vue({
        methods: {
            downFun(e) {
                console.log(e)
            },
            upFun(e) {
                console.log(e)
            }
        }
    }).$mount('#app')
</script>

5、计算属性 - 监视

5.1、计算属性 - computed

<div id="root">
    <span>今天天气 -> {{calculate}}</span>
    <br>
    <button @click="condition = !condition">切换天气</button>
</div>
new Vue({
    data() {
        return{
            condition: true
        }
    },
    computed: {
        calculate() {
            return this.condition ? '冷' : '热';
        }
    }
}).$mount("#root")

5.2、监视属性 - watch

作用:监视vue对象中的属性

属性:deep:true : 开启深度监视

immediate: true : 初始化调用一次

handler() {} :监视的属性发生改变调用

​ 简写:函数名() {}

<div id="root">
    <button @click="hello = !hello">切换</button>
    <br>
    <span>{{jisuan}}</span>
</div>
<script>
    const vm = new Vue({
        data() {
            return{
                hello: true,
                arr: {
                    a: 1,
                    b: 2
                }
            }
        },
        //计算属性
        computed: {
            jisuan() {
                return 'Hello Word!'
            }
        },
        //监视属性(方式一)
        watch: {
            hello: {
                /*  初始化调用一次*/
                immediate: true,
                /*  hello属性发生改变调用*/
                handler(newValue,oldValue) {
                    console.log(newValue,oldValue)
                }
            },
            //简写方式
            hello() {
                handler(newValue,oldValue) {
                    console.log(newValue,oldValue)
                }
            }
        }
    }).$mount("#root");

    //监视属性(方式二)
    vm.$watch('hello', {
        /*  初始化调用一次*/
        immediate: true,
        /*  hello属性发生改变调用*/
        handler(newValue,oldValue) {
            console.log(newValue,oldValue)
        }	
    })

	vm.$watch('hello', function(newValue,oldValue) {
        /*  初始化调用一次*/
        immediate: true,
        console.log(newValue,oldValue)
       
    })

	//监视对象属性
	vm.$watch('arr.a', {
        /*  初始化调用一次*/
        immediate: true,
        /*  hello属性发生改变调用*/
        handler(newValue,oldValue) {
            console.log(newValue,oldValue)
        }	
    })

</script>

6、组件访问

6.1、ref属性

<template>
  <div id="app">
    <div ref="appTest">App组件</div>
    <ref ref="testRef"></ref>
    <button ref="but" @click="refClick">ref属性</button>
  </div>
</template>

<script>
  import ref from '@/components/Ref'

export default {
  name: 'App',
  components: {
    ref
  },
  methods: {
    refClick() {
      console.log(this.$refs.testRef) //获取到组件实例对象
      console.log(this.$refs.appTest) //dom元素
        console.log(this.$refs.but) //dom元素
    }
  }
}
</script>

<style>
</style>

6.2、props(接受父组件传递的参数)

注意:props 优先级高于 data

1、父组件传递参数给子组件

<!--  方式一: 直接传递参数-->
<Student name="我是父组件的name参数" :age="20" sex="我是父组件的sex参数"></Student>

<!--  方式二:绑定一个对象-->
<student :data="student"></student>

2、接收父组件传递的参数

		方式一:普通接收
         props: ['name', 'sex', 'age'],

         方式二:限制类型
         props: {
           name: String,
           age: Number,
           sex: String
         },

        方式三:限制类型、限制必要性、指定默认值
        props: {
            name: {
                type: String,
                require: true,
                default: '默认名称'
            },
            age: {
                type: Number,
                require: true,
                default: 18
            },
            sex: {
                type: String,
                require: true,
                default: '女'
            },
        },

7、混合属性

7.1、mixin

作用:抽取多个组件公共配置 提取到混合配置文件

使用方式:

步骤一:定义混合配置文件

// export 对外暴露 hunhe1
export const hunhe1 ={
    methods: {
        hunheClick() {
            alert(this.name)
        }
    }
}

步骤二:使用混合

局部使用: 组件里配置

<template>
    <div>
        <button @click="hunheClick">{{name}}</button>
    </div>
</template>

<script>
    import {hunhe1} from '@/components/mixin';
    export default {
        name: "Hello",
        data() {return{ name: 'Hello' }},
        mixins: [hunhe1]
    }
</script>

全局使用:main.js 配置

import Vue from 'vue'
import App from './App.vue'
import {hunhe1} from "./components/mixin";

Vue.config.productionTip = false
Vue.mixin(hunhe1)

new Vue({
  render: h => h(App),
}).$mount('#app')

8、插件

//全局注册插件
Vue.use()

9、本地存储

//存数据
localStorage.setItem('key', 'value')

//取数据
localStorage.getItem('key')

10、组件自定义事件

10.1、$emit - 子给父传递参数

方式一:

1、子组件传递一个 hello 函数给父组件接收

this.$emit('hello', {name: 'hello', age: 18})

2、接收hello组件传递过来的函数(子 传 父)

<hello @hello="helloEvent"></hello>

方式二:

1、子组件传递一个 hello 函数给父组件接收

this.$emit('hello', {name: 'hello', age: 18})

2、接收hello组件传递过来的函数(子 传 父)

<!--  ref === hello组件实例对象-->
<hello ref="hello"></hello>

mounted() { //钩子函数(组件挂载完成执行)
    //拿到hello组件实例,然后绑定一个 helloEvent 事件(注意:必须使用箭头函数 this 才执行当前vc实例对象)
    this.$refs.hello.$on('helloEvent', (data) => {
      console.log('@@@',data)
    })
}

10.2、$on - 触发事件

this.$refs.hello.$on('helloEvent', (data) => {
    console.log('@@@',data)
})

10.3、$off - 解绑事件

//解绑一个指定事件
this.$off('hello');

//解绑指定多个事件
this.$off(['hello1', 'hello2']);

//解绑全部事件
this.$off();

11、全局事件总线

使用步骤:

11.1、注册全局事件总线

new Vue({
  render: h => h(App),
  beforeCreate() { //vue创建完成前注册全局事件总线
    Vue.prototype.$bus = this //this是app组件实例
  }
}).$mount('#app')

11.2、使用全局事件总线

methods: {
    deleteOne(titleId) {
        if (confirm('你确定要删除?')) {
            // 发起一个 deleteOneDoto 事件,参数是titleId
            this.$bus.$emit('deleteOneDoto', titleId)
        }
    }
}

11.3、接收事件

mounted() {
    //触发 deleteOneDoto 事件
    this.$bus.$on('deleteOneDoto', this.deleteOneDoto)
}

11.4、vc销毁前解绑事件

//组件实例销毁前执行
beforeDestroy() {
    //按需解绑
    this.$bus.$off('deleteOneDoto')
}

12、消息订阅与发布

12.1、安装消息订阅插件

注意:有多种消息订阅插件 - 安装自己喜欢用的

npm install pubsub-js

12.2、使用步骤

1、在需要使用的组件引入

import pubsub from 'pubsub-js'

2、发布订阅pubsub.publish(name, data)

deleteOne(titleId) {
    if (confirm('你确定要删除?')) {
        //发布订阅
        pubsub.publish('hello', titleId)
    }
}

3、接受订阅 pubsub.subscribe(name, function)

mounted() {
    /*  pusName:发布订阅的name   titleId:传递过来的参数*/
    pubsub.subscribe('hello', (pusName, titleId) => {
        console.log('有人订阅hello事件',pusName, titleId);
    })
    
    // pubsub.subscribe('hello',this.deleteOneDoto)
},

4、取消订阅 pubsub.unsubscribe(pusId)

//销毁前执行
beforeDestroy() {
    //取消订阅
    pubsub.unsubscribe(this.pusId)
}

13、配置请求代理(axios)

13.1、第一种配置方式

作用:简单配置只适用于单服务器访问

配置:vue.config.js

module.exports = {
  devServer: {
    proxy: 'http://localhost:4000' //后台api服务器请求地址
  }
}

13.2、第二种配置方式

作用:完整配置适用于多台服务器请求

配置:vue.config.js

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: '<url>', //服务器地址
        ws: true,// 用于支持 websocket(默认true)
        changeOrigin: true //默认true
      },
      '/foo': {
        target: '<other_url>'
      }
    }
  }
}

changeOrigin : 用户给服务器发起请求地址

true :http:localhost:8888(服务器地址)

false: http:localhost:8080(自己的地址)

14、slot 插槽

14.1、默认插槽

理解:子组件定义一个默认插槽 父组件往子组件插入信息(插槽没有使用返回插槽默认值)

1、子组件定义插槽(slot-demo)

<div>
    <slot>I is  defalut slot!</slot>
</div>

2、父组件插入信息

<slot-demo>
    <template>
        插入信息
    </template>
</slot-demo>

14.2、俱名插槽

理解:定义一个有名字的插槽 按插槽名字插入信息

1、子组件定义俱名插槽(slot-demo)

<div>
    <slot name="top">I is top slot!</slot>
    <slot name="main">I is main slot!</slot>
    <slot name="footer">I is footer slot!</slot>
</div>

2、父组件插入信息

注意:v-slot:top 插槽新语法配合template模板使用

<slot-demo>
    <template v-slot:top>
        top
    </template>
    <template v-slot:main>
        main
    </template>
    <template v-slot:footer>
        footer
    </template>
</slot-demo>

旧语法:slot=“name”

<div slot="name">
    param
</div>

14.3、作用域插槽

理解:插槽本身可以传递数据给使用该插槽的组件**(子组件给父组件传递数据,使用 slot-scope="data"接受)

1、子组件定义作用域插槽(slot-demo)

<div>
    <slot :games="games" hello="hello">I is Number</slot>
</div>

2、父组件插入信息**(接收子组件插槽传递的信息)**

<template slot-scope="data">
    <ul>
        <li v-for="(item,index) in data.games" :key="index">{{item}}</li>
    </ul>
    <h3>{{data.hello}}</h3>
</template>

2、Vuex

1.概念

在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

2.何时使用?

多个组件需要共享数据时

3.搭建vuex环境

  1. 创建文件:src/store/index.js

    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //应用Vuex插件
    Vue.use(Vuex)
    
    //准备actions对象——响应组件中用户的动作
    const actions = {}
    //准备mutations对象——修改state中的数据
    const mutations = {}
    //准备state对象——保存具体的数据
    const state = {}
    
    //创建并暴露store
    export default new Vuex.Store({
    	actions,
    	mutations,
    	state
    })
    
  2. main.js中创建vm时传入store配置项

    ......
    //引入store
    import store from './store'
    ......
    
    //创建vm
    new Vue({
    	el:'#app',
    	render: h => h(App),
    	store
    })
    

4.基本使用

  1. 初始化数据、配置actions、配置mutations,操作文件store.js

    //引入Vue核心库
    import Vue from 'vue'
    //引入Vuex
    import Vuex from 'vuex'
    //引用Vuex
    Vue.use(Vuex)
    
    const actions = {
        //响应组件中加的动作
    	jia(context,value){
    		// console.log('actions中的jia被调用了',miniStore,value)
    		context.commit('JIA',value)
    	},
    }
    
    const mutations = {
        //执行加
    	JIA(state,value){
    		// console.log('mutations中的JIA被调用了',state,value)
    		state.sum += value
    	}
    }
    
    //初始化数据
    const state = {
       sum:0
    }
    
    //创建并暴露store
    export default new Vuex.Store({
    	actions,
    	mutations,
    	state,
    })
    
  2. 组件中读取vuex中的数据:$store.state.sum

  3. 组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据)$store.commit('mutations中的方法名',数据)

    备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

5.getters的使用

  1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。

  2. store.js中追加getters配置

    ......
    
    const getters = {
        bigSum(state){
            return state.sum * 10
        }
    }
    
    //创建并暴露store
    export default new Vuex.Store({
        ......
        getters
    })
    
  3. 组件中读取数据:$store.getters.bigSum

6.四个map方法的使用

  1. mapState方法:用于帮助我们映射state中的数据为计算属性

    computed: {
        //借助mapState生成计算属性:sum、school、subject(对象写法)
         ...mapState({sum:'sum',school:'school',subject:'subject'}),
             
        //借助mapState生成计算属性:sum、school、subject(数组写法)
        ...mapState(['sum','school','subject']),
    },
    
  2. mapGetters方法:用于帮助我们映射getters中的数据为计算属性

    computed: {
        //借助mapGetters生成计算属性:bigSum(对象写法)
        ...mapGetters({bigSum:'bigSum'}),
    
        //借助mapGetters生成计算属性:bigSum(数组写法)注意:名字必须对应getters对象里面的函数名
        ...mapGetters(['bigSum'])
    },
    
  3. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

    methods:{
        //靠mapActions生成:increment、decrement(对象形式)
        ...mapMutations({increment:'JIA',decrement:'JIAN'}),
        
        //靠mapMutations生成:JIA、JIAN(对象形式)
        ...mapMutations(['JIA','JIAN']),
    }
    

备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

7.模块化+命名空间

  1. 目的:让代码更好维护,让多种数据分类更加明确。

  2. 修改store.js

    const countAbout = {
      namespaced:true,//开启命名空间
      state:{x:1},
      mutations: { ... },
      actions: { ... },
      getters: {
        bigSum(state){
           return state.sum * 10
        }
      }
    }
    
    const personAbout = {
      namespaced:true,//开启命名空间
      state:{ ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        countAbout,
        personAbout
      }
    })
    
  3. 开启命名空间后,组件中读取state数据:

    //方式一:自己直接读取
    this.$store.state.personAbout.list
    //方式二:借助mapState读取:
    ...mapState('countAbout',['sum','school','subject']),
    
  4. 开启命名空间后,组件中读取getters数据:

    //方式一:自己直接读取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:借助mapGetters读取:
    ...mapGetters('countAbout',['bigSum'])
    
  5. 开启命名空间后,组件中调用dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:借助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  6. 开启命名空间后,组件中调用commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:借助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    

3、router

  1. 理解: 一个路由(route)就是一组映射关系(key - value),多个路由需要路由器(router)进行管理。
  2. 前端路由:key是路径,value是组件。

1.基本使用

  1. 安装vue-router,命令:npm i vue-router

  2. 应用插件:Vue.use(VueRouter)

  3. 编写router配置项:

    //引入VueRouter
    import VueRouter from 'vue-router'
    //引入Luyou 组件
    import About from '../components/About'
    import Home from '../components/Home'
    
    //创建router实例对象,去管理一组一组的路由规则
    const router = new VueRouter({
    	routes:[
    		{
    			path:'/about',
    			component:About
    		},
    		{
    			path:'/home',
    			component:Home
    		}
    	]
    })
    
    //暴露router
    export default router
    
  4. 实现切换(active-class可配置高亮样式)

    <router-link active-class="active" to="/about">About</router-link>
    
  5. 指定展示位置

    <router-view></router-view>
    
  6. 路由懒加载

    component: () => import('@/views/redirect')
    

2.几个注意点

  1. 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹。
  2. 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
  3. 每个组件都有自己的$route属性,里面存储着自己的路由信息。
  4. 整个应用只有一个router,可以通过组件的$router属性获取到。

3.多级路由(多级路由)

  1. 配置路由规则,使用children配置项:

    routes:[
    	{
    		path:'/about',
    		component:About,
    	},
    	{
    		path:'/home',
    		component:Home,
    		children:[ //通过children配置子级路由
    			{
    				path:'news', //此处一定不要写:/news
    				component:News
    			},
    			{
    				path:'message',//此处一定不要写:/message
    				component:Message
    			}
    		]
    	}
    ]
    
  2. 跳转(要写完整路径):

    <router-link to="/home/news">News</router-link>
    

4.路由的query参数

  1. 传递参数

    <!-- 跳转并携带query参数,to的字符串写法 -->
    <router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link>
    				
    <!-- 跳转并携带query参数,to的对象写法 -->
    <router-link 
    	:to="{
    		path:'/home/message/detail',
    		query:{
    		   id:666,
                title:'你好'
    		}
    	}"
    >跳转</router-link>
    
  2. 接收参数:

    $route.query.id
    $route.query.title
    

5.命名路由

  1. 作用:可以简化路由的跳转。

  2. 如何使用

    1. 给路由命名:

      {
      	path:'/demo',
      	component:Demo,
      	children:[
      		{
      			path:'test',
      			component:Test,
      			children:[
      				{
                            name:'hello' //给路由命名
      					path:'welcome',
      					component:Hello,
      				}
      			]
      		}
      	]
      }
      
    2. 简化跳转:

      <!--简化前,需要写完整的路径 -->
      <router-link to="/demo/test/welcome">跳转</router-link>
      
      <!--简化后,直接通过名字跳转 -->
      <router-link :to="{name:'hello'}">跳转</router-link>
      
      <!--简化写法配合传递参数 -->
      <router-link 
      	:to="{
      		name:'hello',
      		query:{
      		   id:666,
                  title:'你好'
      		}
      	}"
      >跳转</router-link>
      

6.路由的params参数

  1. 配置路由,声明接收params参数

    {
    	path:'/home',
    	component:Home,
    	children:[
    		{
    			path:'news',
    			component:News
    		},
    		{
    			component:Message,
    			children:[
    				{
    					name:'xiangqing',
    					path:'detail/:id/:title', //使用占位符声明接收params参数
    					component:Detail
    				}
    			]
    		}
    	]
    }
    
  2. 传递参数

    <!-- 跳转并携带params参数,to的字符串写法 -->
    <router-link :to="/home/message/detail/666/你好">跳转</router-link>
    				
    <!-- 跳转并携带params参数,to的对象写法 -->
    <router-link 
    	:to="{
    		name:'xiangqing',
    		params:{
    		   id:666,
           	   title:'你好'
    		}
    	}"
    >跳转</router-link>
    

    特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!

  3. 接收参数:

    $route.params.id
    $route.params.title
    

7.路由的props配置

作用:让路由组件更方便的收到参数

{
	name:'xiangqing',
	path:'detail/:id',
	component:Detail,

	//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
	// props:{a:900}

	//第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
	// props:true
	
	//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
	props(route){
		return {
			id:route.query.id,
			title:route.query.title
		}
	}
}

8.<router-link>的replace属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式
  2. 浏览器的历史记录有两种写入方式:分别为pushreplacepush是追加历史记录,replace是替换当前记录。路由跳转时候默认为push
  3. 如何开启replace模式:<router-link replace .......>News</router-link>

9.编程式路由导航

  1. 作用:不借助<router-link> 实现路由跳转,让路由跳转更加灵活

  2. 具体编码:

    //$router的两个API
    this.$router.push({
    	name:'xiangqing',
    		params:{
    			id:xxx,
    			title:xxx
    		}
    })
    
    this.$router.replace({
    	name:'xiangqing',
    		params:{
    			id:xxx,
    			title:xxx
    		}
    })
    this.$router.forward() //前进
    this.$router.back() //后退
    this.$router.go() //可前进也可后退 参数是number类型(正数为前进的步数,负数为后退的部署)
    

10.缓存路由组件

  1. 作用:让不展示的路由组件保持挂载,不被销毁。

  2. 具体编码:

    <keep-alive include="News"> 
        <router-view></router-view>
    </keep-alive>
    

11.两个新的生命周期钩子

  1. 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
  2. 具体名字:
    1. activated路由组件被激活时触发。
    2. deactivated路由组件失活时触发。

12.路由守卫

  1. 作用:对路由进行权限控制

  2. 分类:全局守卫、独享守卫、组件内守卫

  3. 全局守卫:

    //全局前置守卫:初始化时执行、每次路由切换前执行
    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'
    	}
    })
    
  4. 独享守卫:

    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()
    	}
    }
    
  5. 组件内守卫:

    //进入守卫:通过路由规则,进入该组件时被调用
    beforeRouteEnter (to, from, next) {
    },
    //离开守卫:通过路由规则,离开该组件时被调用
    beforeRouteLeave (to, from, next) {
    }
    

13.路由器的两种工作模式

  1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。
  2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。
  3. hash模式:
    1. 地址中永远带着#号,不美观 。
    2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
    3. 兼容性较好。
  4. history模式:
    1. 地址干净,美观 。
    2. 兼容性和hash模式相比略差。
    3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值