Vue学习之从入门到入土

el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
data中用于存储数据,数据供el所指定的容器去使用

插值语法:{{xxx}} 适用于标签体内
xxx可以直接接受到data中的所有属性
指令语法:适用于解析标签
v-bind可以给属性动态绑定:v-band:href=“url”其中“url”作为表达式
其中v-bind可以简写成 :

el的两种写法:
(1)el:'#root',
(2)v.$mount('#root')//先有 const v = new Vue({})

data的两种写法:
(1)data:{name:'123'}对象式
(2)data(){return {name:'123'}} 函数式


数据代理:

Object.defineProperty(person,'age',{
value:18,
emumerable:true,//控制属性是否可以枚举
writable:true,//控制属性是否被修改
configurable:true //控制属性是否可以被删除
})
基本原理:通过Object.defineProperty()把data对象中所有属性添加到vm上,为每一个添加到vm上的属性,都指定一个get,set,在get,set内部操作data中对应的属性
get调用时机:
1.初次读取所需数据时
2.所依赖数据发生变化时


计算属性computed:

1.原理:底层借助Object.defineproperty方法提供的get set
2.get调用时机:
(1).初次读取所需数据时
(2).所依赖数据发生变化时
3.计算属性最终会出现在vm上,可以直接调用:vm.computed

{{sum}}

computed:{ sum(){ return 5 } }

可以使用简写形式,但是只能读取数据,当数据修改的时候就要用set


监视属性watch:

1.当被监视属性变化时,回调函数自动打怪调用,惊醒相关操作
2.监视的属性必须存在,才能进行监视
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视


深度监视:

1.Vue的watch默认不监视对象内内部值的改变(一层)
2在watch中配置deep:true可以监视对象内部值的改变(多层)


数据绑定

v-band:单向绑定,可以简写成: :
v-model:双向绑定:只能应用在表单类元素(输入类元素)上,作用于value,收集value值
//v-model:value可以简写成:v-model ,v-model=“计算属性”


事件绑定

v-on 给事件绑定函数:v-on:click ="xxx" 可以简写成:@xxx
事件修饰符:
1.prevent:阻止默认事件
2.stop:阻止事件冒泡
3.once:事件只触发一次
4.capture:使用事件的捕获模式
5.self:只有event.target是当前执行元素时才触发事件
6.passive:事件的默认行为立刻执行,无需等待事件回调执行完毕


键盘事件:

1.回车 enter
2.删除 delete
3.退出 esc
4.空格 space
5.换行 tab
6.上 up
7.下 down
8.左 left
9.右 right
//@keyup.enter = “xx”

所有被Vue管理的函数,最好写成普通函数,这样的this才是vm,或者vm的组件实例对象
所有不被Vue管理的函数(定时器的回调函数,ajax的回调函数,Promise的回调函数),最好写成箭头函数,这样的this才是vm或者vm的组件实例对象


条件渲染:

v-show :做条件渲染 相当于display:none 节点在,只是隐藏
v-if:每次都访问,不会跳过,节点会被删除
v-else-if:满足第一个if就不会继续访问,搭配v-if使用
v-else:不用条件,作为结尾用
例子:

n=1

n=2

n=3

v-show一定能获取到节点,v-if不一定能拿到节点

绑定样式:
1.字符串形式,适用于:样式的类名不确定,需要动态指定
2.数组写法,适用于:样式的类名不确定,个数也不确定
3.数组写法,适用于:样式的类名确定,个数确定

需要包裹,且不破坏原有结构的时候,可以使用template,类似于div但浏览器不显示,只能与v-if配合使用
例子:


列表渲染:

v-for=“item in items” :key=“index” item是形参,items是一个对象
v-for=“(item,index) in items”
(1)遍历数组
v-for="p in persons" :key="p.id"
{{p.name}}-{{p.age}}
persons:[
{id:'001',name:'张三',age:'18'},
{id:'002',name:'李四',age:'19'},
{id:'003',name:'王五',age:'20'}
],
(2)遍历对象
v-for="(value,k) in car" :key="k"
{{k}}-{{value}}
car:{
name:'奥迪',
price:'70w',
color:'黑色'
},
(3)遍历字符串
v-for="(char,index) in str" :key="index"
{{char}}-{{index}}
str:'hello'
(4)遍历指定次数
v-for="(number,index) in 5" :key="index"
{{number}}-{{index}}
{{number}}-{{index}}

渲染:过滤数据
indexOf是包含空字符的


后手添加属性及值:

Vue.set()
vm.$set()
添加的属性具有get,set方法


数组变更方法:重新包装数组的方法,以下的方法可以做到页面响应

push()
pop()
shift()
unshift()
splice()
sort()
reverse()


收集表单数据:

若 则v-model收集的是value值,用户输入的就是value值
若单选框 则v-model收集的是value值,要给标签配置value值
若多选框
1.没有配置input的value属性,则收集的是checked(勾选 or未勾选 收集的是bool值)
2.配置了input的value属性:(1)v-model的初始值是数组,即vue.data控制的值是数组,则收集的是由value组成的数组 (2)v-model的初始值是非数组,则收集的是checked(勾选 or未勾选 收集的是bool值)

v-model的三个修饰符

1.lazy:失去焦点的时候再收集数据,而不是时时刻刻收集数据
2.number:输入字符串转为有效数字
3.trim:输入首尾空格过滤


过滤器:对要显示的数据进行特定格式化后再显示

1.注册过滤器 全局Vue.filter(name,callback) 或者 局部new Vue{filters:{}}


内置指令:

v-text :会替换掉节点中的所有内容,不能识别html结构
v-html :会替换掉节点中的所有内容,可以识别html结构,有安全性问题
v-cloak属性
v-once: 所在的节点在初次动态渲染后就是为静态内容了,以后数据的改变不会引起v-once所在节点的更新
v-pre:可以跳过其所在节点的编译过程,直接视为静态内容
v-band:单向绑定,可以简写成: :
v-model:双向绑定:只能应用在表单类元素(输入类元素)上,作用于value,收集value值
v-bind:可以给属性动态绑定:v-band:href=“url”其中“url”作为表达式
其中v-bind可以简写成 :
v-show :做条件渲染 相当于display:none 节点在,只是隐藏
v-if:每次都访问,不会跳过,节点会被删除
v-else-if:满足第一个if就不会继续访问,搭配v-if使用
v-else:不用条件,作为结尾用
v-on 给事件绑定函数:v-on:click =“xxx” 可以简写成:@xxx
v-for=“item in items” :key=“index” item是形参,items是一个对象


自定义指令:

自定义函数形式什么时候被调用?
1.指令成功跟元素绑定时
2.指令所在模板重新解析时
big(element,binding){
element.innerText = binding.value*10
console.log(element,binding)
}
自定义对象形式(directives):
1.bind(){}//指令与元素成功绑定时
2.inserted(){}//指令所在元素被插入页面时
3.update(){}//指令所在模板被重新解析时

fbind:{	

 		 //指令与元素成功绑定时

                bind(element,binding){

                    element.value = binding.value

                },

                //指令所在元素被插入页面时

                inserted(element,binding){

                    element.focus()

                },

                //指令所在模板被重新解析时

                update(element,binding){

                    console.log('update')

                    element.value = binding.value

                }

            }

当出现指令名含多个单词时:v-big-Number
需要在定义指令时用原来的形式:‘big-Number’(element,binding){}
指令函数中的this不再是vm而是window


生命周期函数(钩子)

函数中的this指向vm或组件实例对象

1.beforeCreate 创建 数据监测/数据代理之前,初始化生命周期

2.created 创建完毕,可以通过vm访问data中的数据,methods的方法

3.beforeMount初始化之前,虚拟dom已经解析完毕,未转化为真实dom,页面上仍然是未编译的结构

4.mount 初始化完毕,页面中是真实dom,可以开始定时器,发送网络请求,订阅消息,绑定自定义事件等初始化操作

5.beforeUpdate 更新之前,数据是新的,页面是旧的

6.updated 更新完毕,数据跟页面都是新的

7.beforeDestroy 销毁之前,数据和方法处于可用状态,一般:关闭定时器,取消订阅消息,解绑自定义事件

8.destroyed 销毁完毕

9.activated 路由组件独有的,激活组件

10.deactivated 路由组件独有的,组件失活


使用组件步骤:

1.定义组件(创建组件)
2.注册组件
3.使用组件(写组件标签)
(1)定义组件:使用Vue.extend(options)创建,其中options跟new Vue(options)时传入的options几乎一样,但是也有区别:

  1. el不用写
  2. data必须写成函数形式
  3. 使用template可以配置组件结构

(2)注册组件:

1.全局注册:Vue.component(“组件名”,组件)

2.局部注册:new Vue的时候传入components选项

(3)编写组件标签

可以使用name配置项指定组件在开发者工具中的名字

VueComponent:每次调用Vue.extend,都会返回一个全新的VueComponent
VueComponent.prototype.proto ===Vue.prototype
让VueComponent的实例对象可以访问到Vue原型的属性,方法

Vue.js是完整版的Vue,包含:核心功能+模板解析器
Vue.runtime.xxx.js是精简版的Vue,只包含:核心功能,因为没有模板解析器所以不能使用template配置项,需要使用reader函数接收到的createElement函数去指定具体内容

vue inspect> output.js 可以查看vue脚手架的默认配置

vue.config.js可以对脚手架进行个性化定制


ref属性:

​ 1.被用来给元素或者子组件注册引用信息(id的替代者)

​ 2.应用在html标签上获取的是真实dom元素,应用在组件标签上获取的是组件实例对象

​ 3.使用方式:

获取:this.$refs.xx


配置项:props:

​ 1.传递数据:

​ 2.接受数据:

​ (1)只接收:props=[‘name’]

​ (2)限制类型:props:{name:{String}}

​ (3)限制类型+限制必要性+指定默认值:props:{name:{type:String,required:true}}

//props是只读的,如果对props中的数据做修改,Vue会检测并警告

//如果需要修改props中的数据,可以将props的内容复制到data中,修改data的数据,Vue先读props的数据再读data


mixin(混合):可以把多个组件共用的配置提取成一个混合对象

​ 1.定义混合:{date(){},methods:{}}

​ 2.使用混合:

​ (1)局部混合:mixins:['xxx']

​ (2)全局混合:在mian.js中:Vue.mixin(xxx)

备注:㊙️当数据方法发生冲突时,组件中的数据data,方法methods优先


插件

用于增强Vue,是包含一个install方法的一个对象,install的第一个参数是Vue,第二个参数是插件使用者传递的数据

plugin.js

mixin.js 混合

pubsub-js

animate.css 动画插件,在npm下载

vue-router 路由

axios ajax请求


style 的scoped限制作用域

做条件统计:reduce(()=>{},)


存储机制

webStorage=sessionStorage+localStorage 本地存储机制

xxxx.setItem('key','value')

xxxx.getItem('key')

xxxx.removeItem('key')

xxxx.clear()

sessionStorage一关闭网站就没了,localStorage可以长期保存()


自定义事件,子给父传递数据:

1.通过props传递

2.通过绑定一个自定义事件:第一种写法:使用@或者v-on

ps:父组件: 

	<Teacher @diy="showTeacherName" ></Teacher>

	showTeacherName(name,...parent){

                console.log('app获取到了:',name,parent)

         },

子组件:

	@click="sendName"

	sendName(){

       	 	this.$emit('diy',this.name,70,80,90)

     	 },

3.通过绑定一个自定义事件:第二种写法:使用ref绑定子组件

ps:父组件

 <Teacher ref="teacher"></Teacher>

mounted() {

          this.$refs.teacher.$on('diy',this.showTeacherName)

        },

子组件:

	@click="sendName"

	sendName(){

       	 	this.$emit('diy',this.name,70,80,90)

     	 },

4.全局事件总线:接受数据的组件用this. b u s . bus. bus.on绑定,传递数据的组件用this. b u s . bus. bus.emit传递

(1)在vm中 使用全局事件总线 Vue.prototype.$bus = this

(2)接受数据组件:绑定事件+回调函数

mounted(){

   this.$bus.$on('change',this.change)

  }

beforeDestroy(){

    this.$bus.$off('change')

  }

(3)传递数据组件:

 ItemChange(todo){

	this.$bus.$emit('change',todo)

},

解绑: /* this.$off(‘diy’)//只能解绑一个事件 */

​ this.$off([‘diy’,‘demo’])//解绑多个事件

​ /* this.$off()//解绑所有事件 */

当使用原生事件跟自定义事件定义混乱的时候:@click.native


消息的订阅与发布

(1)安装插件:npm i pubsub-js (2)引入插件:import pubsub from ’pubsub-js‘

接受数据的组件:订阅消息+回调函数

methods: {

            demo(name,parent){

                console.log('有人发布了hello消息',name,parent)

            }

},

mounted() { 

            this.pubId = pubsub.subscribe('hello',this.demo)

},

传递数据的组件:发布消息

send() {

       pubsub.publish('hello',666)

}

取消订阅:pubsub.unsubscribe(pubId)


获取当前事件对象:target

例如:获取input输入内容 @keyup.enter="enter1(todo,$event),可以通过event.target.value获取


nextTick:相当于计时器

动画

style三步:

.v-enter-active{

    animation: guodu 1s ;

  }

  .v-leave-active{

    animation: guodu 1s reverse;

  }

 @keyframes guodu{

    from{

      transform: translateX(-100%);

    }

    to{

      transform:translateX(0px);

    }

  }


开启代理服务器:在config中

ps:不能转发给多个服务器请求

devServe{

proxy

}


创建脚手架

vue create xx


``

:to=“/home/message/Detail?id=${m.id}&title=${m.title}

:to 让=“ xxx”里的xx当作字符串解析

其中xxx加上``,把xxx当作js解析

其中${m.id}是js变量


插槽

让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,使用与父组件===>子组件

分类:默认插槽,具名插槽,作用域插槽

1.默认插槽

父组件:app
<test title="美食">
    <ul>
    	<li v-for="(f,index) in foods" :key="index">{{f}}</li>
    </ul>
</test>
<test title="游戏">
    <img src="xx" alt="">	
</test>

<test title="电影">
    <video controls src="xx"></video>
</test>

data() {
    return {
 	   foods:['火锅','烧烤','小龙虾']	
    }
},
子组件:test
<template>
  <div class="content">
    <h3>{{title}}分类</h3>
    <slot>当没有传递参数的时候,使用默认值</slot>
  </div>
</template>

 props:['title']

2.具名插槽

父组件:app
<div class="app">
    <test title="美食">
        <ul slot="center">
        <li v-for="(f,index) in foods" :key="index">{{f}}</li>
        </ul>
    </test>
    <test title="游戏">
        <img slot="center" src="xx" alt="">
        <template v-slot:footer>
            <h3>0.0</h3>
        </template>
    </test>


    <test title="电影">
        <video slot="center" controls src="xx"></video>
        <div slot="footer">
            <h3>热门</h3>
            <h3>经典</h3>
            <h3>怀旧</h3>
        </div>
    </test>
</div>
data() {
    return {
  	  foods:['火锅','烧烤','小龙虾']
    }
},
子组件:test
<template>
  <div class="content">
    <h3>{{title}}分类</h3>
    <slot name="center">当没有传递参数的时候,使用默认值1</slot>
    <slot name="footer">当没有传递参数的时候,使用默认值2</slot>
  </div>
</template>

props:['title']

3.作用域插槽

数据在组件自身,但根据数据生成的结构需要由插槽的使用者决定(即下面的父组件app生成结构给子组件test使用)

父组件:app
<div class="app">
        <test title="美食">
            <template scope="data">
                <ul>
                    <li>其中scope中的data指的是:{{data}}</li>
                    <!-- scope访问的是组件里slot中传递的数据 -->
                    <br>
                    <li>data中的数据foods指的是:{{data.foods}}</li>
                    <br>
                    <li v-for="(f,index) in data.foods" :key="index">{{f}}</li>
                </ul>
            </template>
        </test>
        <test title="游戏">
            <template scope={x}>
                <ol>
                    <li v-for="(f,index) in x" :key="index">{{f}}</li>
                </ol>
            </template>
        </test>

  
        <test title="电影">
            <template scope="data">
                <h4>
                    <li v-for="(f,index) in data.foods" :key="index">{{f}}</li>
                </h4>
            </template>
        </test>
    </div>
子组件:test
<template>
  <div class="content">
    <h3>{{title}}分类</h3>
    <slot :foods="foods" :demo="demo" x="x">当没有传递参数的时候,使用默认值1</slot>
  </div>
    
</template>

data() {
    return {
       foods:['火锅','烧烤','小龙虾'],
       demo:1
    }
},

3…呈现结果:


Vuex

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ThTam2X3-1664379083828)(D:\myDesktop\FE\Vue\新建文件夹\1662555523024.png)]

1.引入vues

import Vuex from 'vuex'

2.应用vuex插件

Vue.use(Vues)

3.准备actions,用于响应组件中的动作

const actions={}

4.准备mutations,用于操作数据(state)

const mutations={}

5.准备state,用于存储数据

const state={}

6.创建Store,并暴露store

export default new Vuex.Store({
    actions,
    mutations,
    state,
    getters

})

在main.js中创建vm时传入store配置项

1.引入store

import store from './store'

2.创建vm

new Vue({
  render: h => h(App),
  store,
  beforeCreate(){
    Vue.prototype.$bus = this//安装全局事件总线
  }
}).$mount('#app')

基本使用

在组件中:
methods:{
    add(){
         this.$store.dispatch('add',{x:this.x,y:this.y})
         //做分发,将'add'发给actions处理业务逻辑,最终在mutations处理数据  
    },
    sub(){
    	this.$store.commit('SUB',{x:this.x,y:this.y})
    	//直接将'SUB'发给mutations,省略了发给actions的过程,用于简单逻辑
    },
}

在store中:
const actions={
    add:function(context,values){
        // context为上下文中可能用到的方法,其中含有dispatch,comit,state
        // console.log('@',context,values)
        context.dispatch('add2',values)
    },
    add2:function(context,values){
        console.log('执行大量代码1')
        context.dispatch('add3',values)
    },
    add3:function(context,values){
        console.log('执行大量代码2')
        context.commit('ADD',values)
    },
}

const mutations={
    ADD(state,values){    
        state.sum = values.x + values.y
    },
}
const state={sum:0}

const getters={
    BigSum(state){
        return state.sum*10
    }
}

最终在组件中读取数据:$store.state.sum

四个map方法的使用

1.mapState

computed:{
    sum(){
        return this.$store.state.sum
    },
    school(){
        return this.$store.state.school
    },
    dept(){
        return this.$store.state.dept
    },
	
    //借助mapState生成计算属性,从state中读取数据。(对象写法)
    // ...mapState({he:'sum',school:'school',dept:'dept'}),

    //借助mapState生成计算属性,从state中读取数据。(数据写法)
    //...mapState(['sum','school','dept']),
}

2.mapGetters

computed:{
     bigSum(){
        return this.$store.getters.bigSum
    },

    //借助mapGetters生成计算属性,从getters中读取数据。(对象写法)
    //意思就是:在组件中调用的方法名是bigSum,$store.getters中的名字也是bigSum
    // ...mapGetters({bigSum:'bigSum'}),

    //借助mapGetters生成计算属性,从getters中读取数据。(数据写法)
    //意思就是:在组件中调用的方法名是bigSum,$store.getters中的名字也是bigSum,名字相同才可以这么用
    //...mapGetters(['bigSum']),
}

3.mapMutations,需要传入参数

<button @click="add({x,y})">+</button>
//

methods:{
    add(){
        // this.$store.commit('ADD',{x:this.x,y:this.y})
	}, 
	//借助mapMutations生成相应的方法,方法中回调用commit去联系mutations,需要在调用方法的时候传入参数
	//...mapMutations({add:'ADD'}),
}

4.mapActions,需要传入参数

<button @click="waitAdd">等1s再相加</button>
//

methods:{
    waitAdd(){
         this.$store.dispatch('addWait',{x:this.x,y:this.y})
	}, 
	//借助mapActions生成相应的方法,方法中回调用dispatch去联系Actions,需要在调用方法的时候传入参数
	//...mapAction({waitAdd:'addWait'}),
}

模块化+命名空间

 在组件中:
 import {mapGetters, mapState,mapMutations,mapActions} from 'vuex'
 computed:{
 			//其中的h c是指在index.js中模块化的hobbyOptions,countOptions,需要通过
 			hc指定是哪个模块(通过map生成)
            ...mapState('h',{hobbys:'hobbys'}),
            ...mapState('c',['sum','school','dept']),
            ...mapGetters('c',['bigSum']),
			
			//(自己写),只有自己读取state的时候不用通过'h/firstName',其他都要
            firstName(){
                return this.$store.getters['h/firstName']
            },

        },
        methods: {
            ...mapMutations('c',{add:'ADD'}),
            ...mapActions('c',{waitAdd:'addWait'}),
            ...mapMutations('c',{sub:'SUB'}),
        },
        
 在index.js中:
 //计算相关的配置
import countOptions from './count'

//爱好相关的配置
import hobbyOptions from './hobby'

//创建Store,并暴露store
export default new Vuex.Store({
    modules:{
        h:hobbyOptions,
        c:countOptions
    }
})

在命名空间中:count.js
export default{
    namespaced:true,
    actions:{
        add:function(context,values){
            // context为上下文中可能用到的方法,其中含有dispatch,comit,state
            console.log('@',context,values)
            context.dispatch('add2',values)
        },
        add2:function(context,values){
            console.log('执行大量代码1')
            context.dispatch('add3',values)
        },
        add3:function(context,values){
            console.log('执行大量代码2')
            context.commit('ADD',values)
        },
        addWait(context,values){
            setTimeout(()=>{
                context.commit('ADD',values) 
            },1000)
        },
    },
    mutations:{
        ADD(state,values){
            console.log(state,values)
            state.sum = values.x + values.y
            console.log(state.sum)
        },
        SUB(state,values){
            state.sum = values.x - values.y
        },
    },
    state:{
        sum:0,
        school:'北大',
        dept:'计算机',
    },
    getters:{
        bigSum(state){
            return state.sum*10
        }
    }
}
 

基本路由

npm i vue-router

router-link 路由切换

router-view指定组件的呈现位置

在router/index.js中:

import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'

export default new VueRouter({
    routes:[
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home
        }
    ]
})

在路由组件文件夹pages中:About.vue
<template>
  <div>
    <h2>我是about的内容</h2>
  </div>
</template>

<script>
    export default {
        name:'About'
    }
</script>

在app.vue中:
<!-- 借助router-link标签实现路由的切换 -->
    <router-link to="/about" active-class="active">About</router-link>
    <br>
    <router-link to="/home" active-class="active">Home</router-link>
    <!-- 指定组件的呈现位置 -->
    <div>
        <router-view></router-view>
    </div>

路由组件一般放在pages文件夹,一般组件放在components文件夹

通过切换,“隐藏”了的路由组件,默认是被销毁的,需要的时候再去挂载

每个组件都有自己的$route属性,里面存储着自己的路由信息

整个应用就只有一个router,可以通过组件的$router属性获取到


多级路由

{
    path:'/home',
    component:Home,
    //children二级路由,且二级路由的path不能带有/,
    children:[
    {
        path:'news',
        component:News
    },
    {
        path:'message',
        component:Message
    }
    ]
}

且,to的目标路径要写完整
<li>
	<router-link  active-class="active" to="/home/message">message</router-link>
</li>

路由传参

1.query参数:

//跳转路由并携带query参数,to的字符串写法
<li v-for="(m,id) in messageList" :key="id">{{m.title}}

<router-link active-class="active" :to="`/home/message/Detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link> 

</li>

//对象写法
<router-link active-class="active" :to="{
    path:'/home/message/Detail',
    query:{
        id:m.id,
        title:m.title
    } 
}">{{m.title}}</router-link>

//接受参数:
$route.query.id
$route.query.title

命名路由

简化路由跳转

在index中:
children:[
    {   
        name:'xiaoxi',
        path:'Detail',
        component:Detail
    }
]
在路由组件中:
<router-link active-class="active" :to="{
    name:'xiaoxi',
    query:{
        id:m.id,
        title:m.title
    } 
}">{{m.title}}</router-link>

2.params传参

在index中:需要提前声明变量
children:[
    {   
        name:'xiaoxi',
        path:'Detail/:id/:title',
        component:Detail
    }
]
在路由组件中:
//跳转路由并携带params参数,to的字符串写法
<router-link active-class="active" :to="`/home/message/Detail/666/消息6`">{{m.title}}</router-link>

//对象写法,当使用params写法的时候,不能使用path,只能用 name配置项
<router-link active-class="active" :to="{
    name:'xiaoxi',
    params:{
    id:m.id,
    title:m.title
    } 
}">{{m.title}}</router-link>

路由的props配置

1.第一种写法:props对象写法,给谁传数据就写在谁身上

props:{a:1, b:'hello' }

2.第二种写法:值为bool,若bool为真,就会把该路由组件收到的所有params参数,以props形式传给Detail组件

index中:
props:true

组件中:
接收数据:props:['id','title'],

3.第三种写法:值为函数

{
    path:'message',
    component:Message,
    children:[
    {   
        name:'xiaoxi',
        path:'Detail/:id/:title',
        component:Detail,
        //props的第三种写法,值为函数
        //ps:下面写的是params传参方法,所以组件中要用params,也可以用query,组件中也要对应
        props($route){
        	return {id:$route.params.id,title:$route.params.title}
    	}
    }
    ]
}

编程式路由

router-link 的replace属性

push是追加,replace是替换:

this.$router.push({
    name:'xiaoxi',
    params:{
    id:m.id,
    title:m.title
    } 
})

页面记录的跳转:back,forward

<button @click="back">点击后退</button>
back(){
    this.$router.back()
}

缓存路由组件:

//include中的是组件名
<keep-alive include="News">
      <router-view></router-view>
</keep-alive>

全局守卫

index中:给每个配置项添加meta属性
{   
    name:'zhuyeAbout',
    path:'/about',
    component:About,
    meta:{title:'主页About'}
},


//全局前置路由守卫,初始化调用,切换之前调用
router.beforeEach((to,from,next)=>{
    // 进行权限控制
    if(to.meta.isAuth){
        if(localStorage.getItem('local') ==='wang'){
            next()
        }else{
            console.log('无权查看')
        }
    }else{
        next()
    }
})

//后置路由守卫,初始化调用,切换后调用
router.afterEach((to,from)=>{
    document.title = to.meta.title || '纯主页'
    console.log(to,'@',from)
})

独享路由守卫

在idnex中的某个单独的配置项中:
beforeEnter:(to,from,next)=>{
    if(to.meta.isAuth){
        if(localStorage.getItem('local') ==='wang'){
            next()
        }else{
            console.log('无权查看')
        }
    }else{
		next()
    }
}

组件内守卫

在路由组件内单独为这个组件设置守卫:
export default {
        name:'Home',
        mounted() {
          console.log(this)
        },
        //通过路由规则,进入组件前被调用
        beforeRouteEnter(to,from,next){
          if(to.meta.isAuth){
                  if(localStorage.getItem('local') ==='wang'){
                      next()
                  }else{
                      console.log('无权查看')
                  }
              }else{
                  next()
              }
        },
        //通过路由规则,进入组件后被调用
        beforeRouteLeave(to,from,next){
          
        }
    }

路由器的两种工作模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XZn4Xx9Y-1664379083829)(D:\myDesktop\FE\Vue\新建文件夹\1662776321262.png)]Vue学习之从入门到入土_第1张图片

你可能感兴趣的:(vue.js,学习,前端)