Vue2.0+Vue3.0(复习笔记)

Vue是一套用于 构建用户界面 的 渐进式 JavaScript框架。
渐进式:vue可以自底向上逐层的应用(简单应用:只需一个轻量小巧的核心库;复杂应用:可以引入各种Vue插件库)

一、Vue基础

1.1. v-bind与v-model

v-bind:单项数据绑定,model => view view !=> medel
v-model:双向数据绑定,model <=> view (仅用于表单元素的value)

image.png

简写:
image.png

1.2.回顾Object.defineProperty

Object.defineProperty:对对象的属性进行操作(vue2.0中的数据劫持、数据代理...底层都有用到)


image.png

1.3. vue中的数据代理

数据代理:通过一个对象(vm)对另一个对象(data)的属性进行操作(Object.defineProperty)


image.png

image.png

1.4. Vue中的事件

a.事件传参问题

@click="fn" 与@click="fn($event,x)" 都可调用事件,后者可直接传递参数

b.事件修饰符(6种)

image.png

c.键盘事件

image.png

注:tab及系统修饰键(ctrl、alt、shift、meta)建议搭配@keydown.键名 使用

1.5. 计算属性computed 与 监视/侦听属性watch

计算属性:通过已有属性计算得来的新属性(getter/setter——defineProperty)
优点:计算属性computed有缓存,当创建时/所依赖的属性发生变化时才会刷新
监视属性:当监视的属性发生变换时被调用(handler(newVal,oldVal){})


深度监视:监视引用类型数据时

计算属性与监视属性的区别:


image.png

当计算属性和监视属性都能实现效果时优先选择计算属性,但涉及到一些异步(比如:定时器setTimeout...)操作的就选监视属性。因为,computed依靠函数的返回值,不能开启异步任务,而watch依靠自身计算不依靠返回结果,可以开启异步任务。

1.6. 样式绑定

image.png

a.绑定class样式
字符串写法:适用于样式的类名不确定,需要动态绑定
:class="variable"
数组写法:适用于要绑定的样式个数不确定,名字也不确定
:class="classArr"
对象写法:适用于要绑定的样式个数确定,名字也确定,但要动态决定是否使用
:class="classObject"
b.绑定style样式
对象写法:
:style="styleObj"
注意:styleObj里要使用小驼峰命名
对象写法(不常用):
:style="[styleObj1,styleObj2]" :style="styleArr"

1.7. 条件渲染(v-if v-else v-show)

image.png

v-show="true/false" ======底层实现就是控制display
v-if="true/false" =======为false时直接对元素进行删除操作
注:切换频率高,使用v-show,频率低,使用v-if
v-if、v-else-if、v-else配合使用,当某条语句的判断条件成立时,紧接在该语句后的其他判断语句就不执行。
这几个条件配合使用时,这几条语句中间不可以加入其他语句,否则该判断结构会被打断,会失效。
注:template标签不会破坏DOM结构,但template只能配合v-if使用

1.8. 列表渲染(v-for)

image.png
//person=[
  {id:'001',name:'张三'},
  {id:'002',name:'李四'},
  {id:'003',name:'王五'}
]
  • {{p.name}}
  • 补充内容

    v-for中key的原理与作用:
    真实dom没有key,虚拟dom上有,用户操作是在真实dom上发生,用户操作真实dom后,虚拟dom也随之发生改变,在进行页面渲染之前,新旧虚拟dom会进行对比(diff算法),根据key进行对比,key相同的元素,数据也相同的话就直接复用,否则就重新生成。使用index作为key的值,当打乱遍历的数据顺序时(如:unshift添加数据),数据会发生错乱,所以,开发中最好使用数据的唯一标识作为key的值。
    key是每个节点的唯一标识,在vue中不写不会报错,但在react中会报错。
    扩展:for-in与for-of的区别:
    for-in主要用于遍历对象(val,key,inedx),也可以遍历数组(val,index)
    for-of(es6新特性)主要用于遍历数组,也可以遍历字符串、伪数组,一般不用于遍历对象(需内建Object.keys())
    使用总结:对象遍历使用for-in,数组遍历使用for-of
    列表过滤:
    方法一:在watch中使用filter(需要新建一个data属性作为遍历的对象,原数据对象不能直接修改)

    image.png

    方法二:在computed中使用filter
    image.png

    注意:data中的原数据尽量不要直接修改
    列表排序:
    在computed中利用filter+sort实现:
    image.png

    1.9. Vue监测数据改变的原理:

    Vue监测数据改变的原理

    当data中的数据发生改变时,Observer方法(观察者)会收集数据,触发该数据对应的set方法(setter),setter会重新解析模板(界面),形成新的虚拟dom树,新旧虚拟dom树进行对比,相同的的元素直接复用,不一样的元素进行生成创建,达到监听数据改变形成响应式的功能。
    Vue.set的使用:
    ①.在向data中的 对象 追加数据时,不可以直接添加(无法实现响应式),需要使用Vue.set()。
    Vue.set(需要添加数据的对象,key,value)
    或者 this.$set(需要添加数据的对象,key,value)
    缺陷:不能直接给data追加数据,只能给data中的对象添加
    ②.在Vue中,没有为数组提供getter和setter,根据索引值直接赋值修改data中的数组数据,页面数据不会响应,Vue对数组的常用方法进行了封装,所以只有调用数组方法修改数组时,响应才会生效。
    image.png

    1.10. 收集表单数据(form)

    总结

    表单type属性:
    text:文本(v-model.trim收集数据时去除空格)
    password:密码
    number:数值(input默认输入的是字符串,所以,可以v-model.numder)
    radio:单选(多选一时,固定name属性)===>配置value值,被选中时读取value
    checkbox:多选 (多选v-model要绑定数组)===>配置value值,被选中时读取value
    select>option:下拉选项
    textarea:多行文本输入(有时不需要打一个字就收集,可以v-model.lazy,改标签失去焦点时才收集)
    单个checkbox:勾选框(直接指定v-model,无需配置value值)
    image.png

    image.png

    1.11. 过滤器

    数据 | 过滤器的名称
    过滤器的本质就是一个函数,将数据作为参数传入过滤器,然后将返回结果替换整个过滤器。多个过滤器可以串联使用。过滤器不改变原数据。
    过滤器一般用于插值语法{{}}和v-bind,不能用于v-model
    局部过滤器:和methods、methods一样,直接在Vm下filters:{}

    //局部过滤器
    filters:{
      过滤器名(数据,参数='设置参数默认值'){
            代码片段;
        return 返回结果
        }       
    }           
    

    全局过滤器:Vue.filter('过滤器名称',function(){})

    //全局过滤器
    Vue.filter('mySlice',function(value){
        return value.slice(0,4)
    })
    

    总结:


    总结

    1.12. 内置指令(Vue提供的但不常用的指令)

    复习:
    v-bind: 单向绑定解析表达式, 可简写为 :xxx
    v-model : 双向数据绑定
    v-for : 遍历数组/对象/字符串
    v-on : 绑定事件监听, 可简写为@
    v-if : 条件渲染(动态控制节点是否存存在)
    v-else : 条件渲染(动态控制节点是否存存在)
    v-show : 条件渲染 (动态控制节点是否展示)
    v-text指令:
    1.作用:向其所在的标签中插入文本内容。
    2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
    v-html指令:
    1.作用:向指定节点中渲染包含html结构的内容。
    2.与插值语法的区别:
    (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
    (2).v-html可以识别html结构。
    3.严重注意:v-html有安全性问题!!!!
    (1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
    (XSS攻击:冒充用户攻击,盗用cookie)
    (2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
    扩展:cookie的工作原理:

    image.png

    v-cloak指令(没有值):
    1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
    2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
    扩展:JS阻塞:JS具有阻塞特性,当浏览器在执行js代码时,不能同时做其它事情,即

    单文件组件的结构组成

    文件暴露/导出的三种方式:
    1、分别暴露:export const 组件名 = Vue.extend({})
    2、统一暴露:export {组件名} ---------引入时:import {***} from ****
    3、默认暴露:export default 组件名---------引入时:import *** from ****
    统一暴露与默认暴露的区别
    App.vue 汇总所有的组件
    main.js 入口文件(new Vue({}))====引入App.vue
    index.html 入口文件的容器====引入main.js

    关系

    三、Vue脚手架 Vue CLI(command line interface 命令行接口工具)

    Vue脚手架是Vue官方提供的标准化开发工具/开发平台。

    3.1.Vue脚手架

    使用步骤:
    ①全局安装@vue/cli(仅一次使用时,记得配置淘宝镜像)

        npm config set registry https://registry.npm.taobao.org
    

    切换到要创建项目的目录,然后使用命令行创建项目 vue create ***
    ③启动项目 npm run serve
    注:Vue脚手架隐藏了所有webpack相关的配置,若想查看相关配置:vue inspect > output.js
    可参考文章使用Vue-CLI搭建项目
    项目结构解析:

    Vue cli项目结构解析

    总结:执行npm run serve=>main.js=>App.js=>执行其下的组价=>汇总到App.js=>找到容器所在文件index.html,将执行的内容放入容器,浏览器进行渲染。
    针对main.js中的render方法进行分析:
    完整版的vue:vue核心+模板解析器,其中模板解析器占1/3左右,如果使用完整版的vue,使用webpack打包后模板解析器占了很大内存且无用。为了使打包完成的项目体积小一些,脚手架中引入的vue是残缺的,没有模板解析器(无法解析template标签),就需要使用render函数来进行渲染。
    render其实是一个函数:

    render(createElement){
        return createElement('h1','你好啊!')
    }
    //vue调用,且该函数中没有用到this,可以简写:
    render:createElement=>createElement('h1','你好啊!')
    

    image.png

    脚手架默认配置:public、favicon.icn、index.html、src、main.js
    默认配置一般是不可更改的,若要自定义个性化配置,可在项目的package.json的同级目录下创建vue.config.js文件(若修改该文件,一定要有重启项目)。
    关闭语法检查的方法:在vue.config.js文件下添加 lintOnSave:false(与pages平级)
    关闭语法检查

    Vue脚手架总结:
    项目结构

    Vue版本说明

    vue.config.js

    3.2. ref属性

    普通标签:在原生javascript中,我们获取一个html元素通常使用id属性(getElementById),但在vue中,我们使用ref属性给元素做标识,然后this.$refs.获取相应元素。
    组件标签:当ref使用到组件标签上时,this.$refs.
    获取到得就是该组件的实例对象VueComponent。(可用于组件间通信)

    ref属性

    3.3. props配置

    <组件标签 key1="value1" key2="value2" ...>
    组件:props:["key1","key2",...]

    但这样接收到的是字符串,所以,可以使用v-bind解决,②即:<组件标签 :key1="value1" :key2="value2" ...>,为了避免上述情况,接收时也可进行类型限制,即:props:{key1:String,key2:Number,...}。③也可设置默认值指定和必要性限制:props:{key1:{type:String,required:true},key2:{type:Number,default:77},...}
    注意:接收到的props是不可以更改的,若想修改,可以赋值给其他变量,然后修改。扫描优先级:props>data
    e.g.

    注意事项

    props总结:
    props总结

    3.4. mixin混入(混合)

    mixin:多个组件使用相同的配置时使用。

    混合mixin的使用

    mixin总结:
    mixin总结

    3.5. 插件plugin

    在src文件夹下创建文件plugins.js文件,创建一个对象(插件的本质是一个对象),在该对象的install方法(一定要有install方法)中进行插件编写,记得暴露/导出,然后在main.js中引入,然后使用(Vue.use(插件名,参数列表))。

    image.png

    插件

    3.6. scoped样式

    在Vue中,各个组件的样式最终是会汇总到一起的,在各个组件中可能会出现类名相同的情况,造成类名冲突。为了解决上述问题,可以给各个组件的样式标签style加一个作用域限制(scoped)。
    注意:App组件不适用scoped

    总结:让样式在局部生效,防止冲突
    组件间通信:
    原始方法:
    父子间传参
    兄弟间传参:借助父组件
    1、自定义事件
    2、全局事件总线
    3、消息订阅与发布
    4、Vuex
    5、路由传参

    3.7. 本地存储(控制台=>Application)

    1、localStorage:借助浏览器的本地存储,将数据存在硬盘上。关闭浏览器,数据不会消失。
    (主动删除或者删除浏览器缓存时就会被清除)
    注:localStorage解决页面更新,数据丢失问题

    解决页面更新,数据丢失问题

    localStorage.setItem("key":"value");//存储,key和value都要使用字符串
    localStorage.getItem("key");//读取
    localStorage.removeItem("key");//移除
    localStorage.clear();//清空
    
    JSON.stringify();//数组对象转JSON字符串
    JSON.parse();//
    

    2、sessionStorage:关闭浏览器,数据消失

    webStorage

    3.8. 组件自定义事件

    子组件给父组件传递数据的方式(3种):
    1、通过父组件给子组件传递函数类型的props实现:子组件通过props接收,然后通过函数使用触发将数据传递给父组件。

    2、通过父组件给子组件绑定一个自定义事件实现:给谁绑的自定义事件找谁触发,使用this.$emit("事件名",参数)触发(第一种写法,使用@或v-on

    3、通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref)

    image.png

    解绑自定义事件(给谁绑的自定义事件找谁解绑):
    1、this.$off('自定义事件名'):解绑一个
    2、this.$off(['自定义事件名','自定义事件名']):解绑多个
    3、this.$off():解绑所有自定义事件
    注意:销毁当前组件的VueComponent实例,销毁后该组件上的所有自定义事件都失效。
    自定义事件总结

    3.9. 全局事件总线:任意组件间通信

    全局事件总线:在A组件中给x绑定自定义事件demo,回调函数留在A中,B组件触发x中的事件demo,并传递参数p,A组件就可接收到B组件传递的参数p。
    x应满足的条件:所有组件都可访问;可调用到$on/$off/$emit...

    全局事件总线图解

    条件①:所有组件都可访问
    一个重要的内置关系:VueComponent.prototype.prop===Vue.prototype(让组件实例对象vc可以访问到Vue原型上的属性和方法),所以,可以把X放到Vue的原型对象Vue.prototype上(在main.js文件中)。
    条件②:可调用到$on/$off/$emit...
    在数据监测、数据代理之前(beforeCreate)直接安装(main.js)

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

    使用:
    this.$bus.$on('自定义事件名',(data)=>{data:接收到的数据})
    this.$bus.$emit(('事件名',传递的数据)
    this.$off('事件名');解绑
    注:
    1、收数据的组件:在mounted中绑定事件总线中自定义事件:this.$bus.on('绑定的自定义事件',绑定时触发的函数);
    传数据的组件:触发this.$bus.$emit('绑定的自定义事件',参数);
    2、在组件销毁前,可以关闭该组件使用到的自定义事件;
    e.s. beforDestroy(){this.$bus.$off('hello')}

    3.10. 消息订阅与发布:任意组件间通信

    消息订阅与发布(mounted中):
    (推荐库pubsub-js)安装:npm i pubsub-js
    引入:import pubsub- from ' pubsub-js'
    1.订阅消息:消息名(接收数据的组件:需要/买):

        this.pubId=pubsub.subscribe('消息名',(消息名msgName,数据data)=>{}) 
        //第二个参数使用箭头函数,this才能指向VC(组件实例对象)
    

    2.发布消息:消息内容(传递数据的组件:提供/卖)pubsub.publish('消息名',function(){ return ...})
    注:组件销毁前(beforeDeatory)需要把订阅消息取消pubsub.unsubscribe(this.pubId);
    消息订阅与发布原生不可实现,需要借助第三方库pubsub-js(其他库也可以)

    消息订阅与发布

    $nextTick

    语法:this.$nextTick(function(){})
    作用:在下一次DOM更新结束后执行其指定的回调函数。
    什么时候用:当改变数据后,要基于更新后的DOM进行某些操作,要在nextTick所指定的回调函数中执行。

    3.11. 过渡与动画

    1、单个元素:将产生动画效果的这个元素使用标签包裹起来,然后编写进入/离开的动画,进入.v-enter-active 离开:v-leave-active
    要使元素一开始就有进入动画,给transition标签加appear属性。
    当有多个transition时,可以给transition标签加name属性(name="x1")进行区分,但在写选择器时,选择器名得与之对应,进入.x1-enter-active 离开:x1-leave-active
    2、多个元素使用相同的动画效果:使用包裹元素,注意,其中的元素要使用key属性进行区分。

    
    
    

    使用动画:

    
    

    使用过渡:

    
    

    推荐:动画库animate
    多个元素使用同一个动画效果(这里使用了动画库):

             
                

    你好啊!

    尚硅谷!

    总结

    3.12. 配置代理

    axios:promis风格,支持请求拦截和响应拦截,体积小
    fetch:会把返回的数据包装两层promise,兼容性差
    1、axios的使用:(使用广泛,推荐)
    下载:npm i axios
    引入:import axios from 'axios'(App.vue)
    使用:axios.get('url').then(response=>{},err=>{})


    跨域报错

    解决跨域(协议名+主机名+端口号):
    1、cors:后端配置特殊的响应头
    2、jsonp:借助script的src属性在引入外部资源时不受同源策略限制(只能解决get产生的跨域问题)
    3、代理服务器(开发中常用)


    image.png

    使用脚手架中的代理服务器:
    方式一:
    image.png

    在vue.config.js配置devServer:{ proxy:'http://localhonst:5000}
    缺点:只能配置一台服务器代理;无法灵活控制请求是否走代理
    方式二:

    image.png

    devServer:{ 
      proxy:{
        '/请求前缀':{
            target:'url',//要发送到的服务器
            pathRewirite:{'^/请求前缀',''},//重写路径(一定要写!!)
            ws:true,//用于支持websocket
            changeOrigin:false//用于控制请求头中的host值
        }
      }
    }
    

    axios.get('http://host:端口号/前缀/路径')
    注意:
    1、所谓“前缀”在请求时是放在端口号之后
    2、引入第三方文件时,①src-assets-...-在App.vue中引入 import '文件' ②在public中添加,然后在index.html文件中使用link引入
    3、Vue的插件库vue-resource(维护频率低)
    安装:npm i vue-resource
    引入(main.js):import vueResource from 'vue-resource'
    使用:Vue.use(vueResource)
    e.g. this.\$http.get('url').then()

    3.13. 插槽slot

    插槽:让父组件可以向子组件指定的位置插入html结构,也是一种组件间通信的方式,适用于父子组件。[子组件挖坑等父组件来填(父组件不填时使用默认值)]
    插槽/匿名插槽/具名插槽/作用域插槽/v-slot指令

    四、Vuex

    4.1. Vuex简介

    Vuex:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
    Vuex
    使用场景:[共享数据]①多个组件依赖同一状态/数据 ②来自不同组件的行为需要变更同一状态

    4.2. Vuex工作原理

    Vuex=Actions+Mutations+State
    Actions:动作、行为 Mutations:修改、加工、维护 State:状态、数据


    Vuex工作原理图解

    所有的组件实例对象VueCompontent都要能使用store(import+use)
    注意:vue2只能使用vuex的3版本,vue3只能使用vuex的4版本

    4.3. 搭建Vuex环境

    1、安装:npm i vuex@指定版本号
    2、引入(main.js):import Vuex from 'vuex'
    Vue.use(Vuex)
    3、store
    4、VueComponent都能使用store
    创建文件:src=>store=>index.js

    //该文件用于创建Vuex中最为核心的stroe
    //引入Vuex
    import Vuex from 'vuex'
    //准备actions——用于响应组件中的动作(服务员)
    const actions = {}
    //准备mutations——用于操作数据(state)
    const mutations = {}
    //准备state——用于存储数据
    const state = {}
    //创建store
    //const store = new Vuex.Store({
    export default  new Vuex.Store({
      acrions,
      mutations,
      state
    })
    //导出/暴露文件
    //export default store
    

    然后在main.js中引入 import store from './store/index.js',在vm中使用
    注意:因为store是基于Vuex的,所以store必须得Vuex生效后才能使用,但import的执行顺序总是大于Vue.use(),所以,在./store/index.js中引入Vuex,然后将Vue.use(Vuex)放到store的创建之前,记得删除main.js中Vuex的引入和使用。

    搭建Vuex环境

    总结:
    1获取state中的数据:this.$store.state.数据名
    2修改state中的共享数据: 1
    ①将共享数据放到state中;
    ②在组件中调用this.$store.dispatch("数据名",变量)
    ③在actions中编写对应的数据 数据名:function(context,value){context.commit('数据名',value)},(actions可以进行业务逻辑的操作,尤其是对各组件共同使用到的操作,需要的数据去content中找);
    ④在mutations中** 数据名:function(state,value){}**,mutations尽量不要进行业务逻辑的操作,也不要发送请求。
    无业务逻辑处理时,可忽略③步骤,①步骤中直接调用④步骤,即this.$store.commit("数据名",变量)
    image.png

    4.4. getters配置项

    getters配置项:用于将state中的数据进行加工


    getters的使用

    4.5. 4种map方法的使用(读取Vuex中的数据的方法)

    1、this.$store.state.数据名
    2、借助mapState生成计算属性,从state中读取数据(对象写法)
    ...mapState({计算属性名:需获取的state中的变量,...})
    3、借助mapState生成计算属性,从state中读取数据(数组写法):计算属性名与需获取的state中的变量同名时
    ...mapState(['需获取的state中的变量',...])
    同理:还有mapGetters方法、mapActions方法、mapMutations方法(加上mapState方法,总的4个,mapActions和mapMutations在调用时,记得把变化量作为参数传入的)

    mapActions和mapMutations

    map**方法的使用总结

    多组件共享数据:

    4.5. Vuex模块化namespace

    Vuex模块化:按功能分类集中处理
    配置项处理:

    Vuex模块化配置

    注意:每一个模块一定要开启命名空间'namespace:true'
    组件获取数据时:
    自己写:this.$store.state.模块名.数据名 this.$store.commit('模块名/mutation名',变化量名)
    this.$store.state.getters[模块名/数据名] this.$store.state.dispatch('模块名/mutation名',变化量名)
    image.png

    借助map**方法:...mapState('模块名',{'方法名':数据,...})/...mapState('模块名',['数据列表']),同理,mapGetters方法、mapActions方法、mapMutations方法也一样
    image.png

    总结:
    image.png

    image.png

    五、路由

    路由:一个路由(route)就是一组映射关系【key-value(路径-组件)】,将路径与组件配对使用,多个路由需要路由器(router)进行管理。

    5.1. 路由的基本使用

    1、安装vue-router:npm i vue-router(2022.7月之后,默认版本为4,且4版本只能在vue3中使用,若是vue2项目,使用路由安装时需要指定版本3:npm i vue-router@3)
    2、在mian.js中引入使用:import VueRouter from 'vue-router' Vue.use(VueRouter)
    3、创建路由器:在src下创建router文件夹>index.js

    // 创建整个项目的路由器
    // 引入vue-router
    import VueRouter from 'vue-router'
    // 引入组件
    import Login from '../components/Login'
    import Index from '../components/Index'
    // 创建路由器并导出
    export default new VueRouter({
        routes:[
            {
                path:'/login',
                component:Login
            },
            {
                path:'/index',
                component:Index
            }
        ]
    })
    

    4、在main.js中引入路由器:

    import router from './router/index'
    new Vue({
      el:'#app',
      render:h=>{app},
      router:router
    })
    

    5、跳转:跳转 出口/视图:
    注:
    ①标签属性active-calss:该路由被激活时的样式
    ②一般组件与路由组件的区别:开发中为了一般组件与路由组件,会将它们发到不同的文件夹之下进行管理,pages:路由组件
    ③不用的路由组件会被销毁,待使用时再挂载
    components:一般组件
    动态路由

    5.2. 嵌套路由

    路由嵌套

    注:子级路由在配置对应组件时,不需要以'/'开头;子级路由在进行路由跳转时,需要把父级带上。()

    5.3. 路由传参

    1、跳转路由并携带query参数:
    ①to的字符串写法:
    在进行路由跳转时:
    接收参数的组件使用$route(路由信息):this.$route.query.key1

    ②to的对象写法:

    
        
    

    路由的query参数

    2、跳转路由并携带params参数:
    在进行路由跳转时:
    在路由配置时,在path属性中设置占位符(指明对应数据对应的对象):{path:"/路由/:key1/:key2",component:组件}
    接收参数的组件使用$route(路由信息):this.\$route.params.key1

    5.4. 命名路由

    命名路由:在配置路由时增加name属性。
    在路由跳转时就不用使用path属性编写多级路由,直接使用name属性即可。
    注意:路由使用to的对象写法时,路由命名和params参数不可共存。

    
        
    

    5.5. 路由的props配置

    路由的props配置:在配置路由时添加props属性
    第一种写法:props值为对象。该对象中的所有key-value都会以props的形式传给使用该路由的组件,然后在对应组件中接收props。(用的非常少,死数据)
    第二种写法:值为布尔值。若为true,就会把改路由组件收到的所有params参数,以props的形式传给使用该路由的组件,然后在对应组件中接收props。
    第三种写法:值为函数。依靠函数的返回值,返回值(对象)以props的形式传给使用该路由的组件。

    路由的props配置

    5.6. router-link的replace属性

    作用:控制路由跳转时操作浏览器历史记录模式。
    浏览器的历史记录(栈)有两种写入方式:push和replace,push是追加历史记录,replace是替换当前记录,默认是push.
    replace模式:取代栈顶的第一条数据(路由跳转时,当前路由会替换掉上一条路由,最终结果就是页面不能千金不能后退)
    使用:

    5.7. 编程式路由导航

    有些时候我们无法使用(标签)来进行路由或者需要实现跳转延迟,这时就需要使用编程式路由导航(不借助的路由导航)

    //e.g.
    
    
    methods:{
      goRouter(){
        //this.$router.push({name:'rputeName',query:{}});
        //this.$router.push({name:'rputeName',query:{}});
        //this.$router.go(number);
          this.back();
      }
    }
    

    5.8. 缓存路由keep-alive

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

    //
    
      
    
    

    5.9. 两(3)个新的生命钩子函数(activated,deactivated)

    由路由缓存引出的,路由组件独有的两个生命钩子函数。
    作用:路由组件独有,用于捕获路由组件的激活/失活状态。
    activated:路由组件被激活时触发
    deactivated:路由组件失活时被触发
    nextTick:在下一次DOM更新结束后执行其指定的回调函数。当改变数据后,要基于更新后的DOM进行某些操作,要在nextTick所指定的回调函数中执行。

    5.10. 路由守卫(很重要!!!)

    分类:全局守卫、独享守卫、组件内守卫(可搭配使用)
    路由守卫:对路由进行权限控制,保护路由的安全。进入某个路由时,进行需求判断,条件为真才可进入该路由,否则跳回指定的其他路由。(防止在不登录的情况下在地址栏输入路径查看页面详情的情况发生)
    1、全局前置路由守卫
    使用:在路由器中给每个路由添加name属性,先使用变量接收路由器,再默认导出(不可简写),在导出之前进行路由守卫的编写beforeEach函数
    beforeEach函数:初始化路由时被调用+每次路由切换之前被调用
    to:目标路由(去哪里)
    from:来自哪里
    next:放行(接着往下走)

    router.beforeEach((to,from,next)=>{
        //前提条件,当前去的目标路由是否是我们需要进行守卫的路由,是:进入判断,否:放行
        if(to.path==='/route1' || to.name==='/route1'...){
            //是需要守卫的路由,那么就进行条件判断,满足就往下走,否则就修改目标路由
             //例如,判断token是否有效,无效就跳到登录页面,有效就继续
             if(!token){
                  next('/login')
              }else{
                  next()
              }
        }else{
            next()
        }
    })
    export default router
    

    !!!!!!如果需要守卫的路由很多的话,这种判断很繁琐,可以在路由配置时加路由源信息meta来控制是否需要守卫:

    // 引入vue-router
    import VueRouter from 'vue-router'
    const router = new VueRputer({
        routes:[
          {
            name:'**',
            path:'/**',
            meta:{isAuth:true},//需要守卫的路由为true
            compontent:()=>import('/**')//按需引入路由组件,有效防止首屏加载慢或白屏问题
          }
        ]
    })
    router.beforeEach((to,from,next)=>{
        //前提条件:使用配置项进行判断是否路由守卫
        if(to.meta.isAuth){
            //是需要守卫的路由,那么就进行条件判断,满足就往下走,否则就修改目标路由
             //例如,判断token是否有效,无效就跳到登录页面,有效就继续
             if(!token){
                  next('/login')
              }else{
                  next()
              }
        }else{
            next()
        }
    })
    export default router
    

    2、全局后置路由守卫
    后置路由守卫没有next参数,一般用于路由跳转后修改页面的标题title。
    用法:在路由源信息meta中增加title属性,在路由跳转是进行修改:

    // 引入vue-router
    import VueRouter from 'vue-router'
    const router = new VueRputer({
        routes:[
          {
            name:'**',
            path:'/**',
            meta:{isAuth:true,title:'****'},
            compontent:()=>import('/**')
          }
        ]
    })
    router.beforeEach((to,fromt)=>{
        if(to.meta.isAuth){
             if(!token){
                  next('/login')
              }else{
                  next()
              }
        }else{
            next()
        }
    })
    //使用后置路由守卫修改页面标题
    router.afterEach((to,from)=>{
        ducument.title = to.meta.title || '默认值'
    })
    export default router
    
    全局守卫

    3、独享路由守卫
    独享路由守卫:只给某一个路由设置的守卫。只有前置没有后置!

    {
            name:'**',
            path:'/**',
            meta:{
                isAuth:true,
                title:'****',
                beforeEnter:(to,from,next)=>{
                      if(to.meta.isAuth){
                           if(!token){
                                next('/login')
                           }else{
                                next()
                            }
                     }else{
                        next()
                    }
                }
              },
            compontent:()=>import('/**')
          }
    

    4、组件内路由守卫
    组件内路由守卫:直接在组件内编写beforeRouterEnter和afterRouterLeave(和钩子函数同级)

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

    5.11. history模式和hash模式(仅从前端角度分析)

    路由器的两种工作模式:history模式和hash模式
    hash模式下,路径中的值称为哈希值,它不会随着http请求发给服务器。
    hash模式(默认模式):地址栏带#号。兼容性好。
    history模式:无#号。兼容性略差。
    项目打包(npm run bind)前可将工作模式改为hash模式(哈希模式在部署发送网络请求时不会因地址栏参数产生404错误):更改工作模式:在路由配置项中 mode:'history或者hash'

    路由器的两种工作模式

    若使用history模式,404报错的解决方法(使用node的中间件):
    npm i connect-history-api-fallback=>在server.js中引入:const history = require('connect-history-api-fallback')=>使用(在使用静态资源之前):app.use(history)

    扩展:使用node express搭建一个微型服务器
    新建文件夹demo=>vscod打开=>安装express: 【npm init=>取名:test-server,一路回车=>npm i express】=>创建server.js文件:=>服务器下一般有static(public)文件夹用来存放前端的文件(服务器要识别这些文件就需要借助中间件app.use来指定静态资源(express.static(__dirname+'static')))=>停掉重启即可在浏览器查看前端文件
    将前端文件放入服务器静态资源文件夹下的过程就称之为部署。

    //server.js
    //引入express
    const express = require('express')
    //引入connect-history-api-fallback解决跨域
    const history = require('connect-history-api-fallback')
    app.use(history)
    //创建服务对象
    const app = express()
    //借助中间件app.use来指定静态资源
    express.static(__dirname+'static'))
    //配置路由
    app.get('/person',(request,response)=>{
          //该路由给前端返回的信息
          request.send({name:'jaja',age:18})
    })
    //监听端口
    app.listen(50005,(err)=>{
          if(!err) {
                //服务器启动成功
          }
    })
    

    5.12. Vue UI组件库

    移动端常用:
    vant:https://youzan.github.io/vant
    Cube UI:https://didi.github.io/cube-ui
    Mint UI:https://mint-ui.github.io
    PC端常用:
    Element UI:https://element.eleme.cn
    IView UI:https://www.iviewui.com
    使用(以Element UI为例):
    打开官网=>组件(按着官网来就好了)
    npm i element-ui=>在main.js中引入使用(import和use)=>引入样式(最好按需引入)=>使用:
    按需引入:借助库babel-plugin-component:
    安装:npm i babel-plugin-component -D(-D开发依赖)=>在babel.config.js下追加配置=>在main.js下引入需要的组件

    六、Vue3

    嗷嗷嗷,终于到vue3了!!!!!
    Vue3快速上手

    注:绝大部分截图来自尚硅谷张天禹老师教学视频

    你可能感兴趣的:(Vue2.0+Vue3.0(复习笔记))