尚硅谷Vue笔记

1、Vue基础 
2、vue-cli
3、vue-router
4、Vuex
5、element-ui
6、Vue3

1、Vue基础

1.1、Vue介绍

Vue是一套用于构建用户界面的渐进式JavaScript框架

Vue可以自底向上逐层的应用:从引入一个轻量小巧的核心库到可以引入各式各样的Vue插件

1.1.1、Vue特点

尚硅谷Vue笔记_第1张图片

 1.1.2、学习Vue前的基础

ES6语法规范、ES6模块化、包管理器、原型、原型链、数组常用方法、axios、promise...

1.1.3、Vue官网

Vue官网

1.1.4、搭建Vue开发环境

找到教程--安装--直接用

1.3Vue模板语法

Vue模板语法有两大类:

1、插值语法:

        功能:用来解析标签体内容。

        写法:{{xxx}},xxx是js表达式,可以直接读取data里面的属性。

2、指令语法:

        功能:用来解析标签(包括:标签属性、标签体内容、绑定事件......)

        写法:v-bind:href='xxx' 或者简写成 :href = 'xxx',里面的xxx同样也是js表达式,也可以读取data里面的属性。

        备注:Vue里面指令很多,形式都是v-???,并不是所有简写都和v-bind一样。


    
    

hello,{{name}}
baidu,{{address.name}}

1.4数据绑定

Vue里面有两种数据绑定:

1、单向绑定(v-bind):数据只能从data流向页面。

2、双向绑定(v-model):数据不仅可以从data流向页面,还可以从页面流向data。

        备注:

                1、双向绑定一般用于表单类元素(如:input、select...)

                2、v-model:value 可以简写为 v-model(因为v-model默认收集就是value值)

1.5data和el两种写法

data和el两种写法:

1、el的两种写法:

        (1)new Vue时候配置el属性

        (2)先创建Vue实例,然后通过vm.$mount('.root')指向el的值。

2、data的两种写法:

        (1)对象式(就是之前写的那样)

        (2)函数式(注意:data用函数式,return后面必须是对象)

        如何选择:现在两种写法都可以,但是用到组件时,必须用函数式,否则报错。

data: function () {//data用来存储数据
                return {
                    name: '阿胜', 
                    url: 'https://www.baidu.com',
                    address: {
                        name: 'China'
                    }
                }



            }

3、原则:

        由Vue管理的函数,一定不能写箭头函数,箭头函数this指向window,如果写了,this就不再是Vue实例了。

1.6 MVVM模型

1、M:模型(model):data中的数据;

2、V:视图(view):模板代码;

3、VM:视图模型(viewmodel):Vue实例

观察发现:

        1、data中的属性,最后都会出现在VM身上

        2、VM身上的属性以及Vue实例中的属性,在Vue模板(代码)中都可以直接使用

1.7Object.defineProperty(定义属性)

object.defineproperty(对象名,对象属性,值)

Object.defineProperty(v,'age',{
            // value:18;
            // enumerable:true,//控制属性是否可以枚举,也就是遍历,默认false
            // writable:true,//控制属性是否可以修改,默认false
            // configurable:true,//控制属性是否可以被删除,默认false
            get(){//当读取时,get函数就被调佣
                console.log('有人读取age属性');
                return number;
            },
            set(value){//当修改时,set函数就被调用
                console.log('修改属性');
                number = value
            }
        })

object.keys(对象名):可以将对象转换成数组 

1.8数据代理

Vue中的数据代理尚硅谷Vue笔记_第2张图片

 1、Vue中数据代理:

        通过VM对象来代理data对象中属性的操作(读/写)

2、Vue中数据代理的好处:

        更加方便操作data中数据

3、基本原理:

        通过object.defineproperty()把data对象中所有属性添加到VM中,并且给每一个属性添加getter和setter方法,在getter/setter内部去操作(读/写)data中对应的属性。

1.9事件处理



    

{{name}}

事件的基本使用:

        1、使用v-on:xxx 或@xxx绑定事件。其中xxx是事件名;

        2、事件的回调写在methods对象中,最终会在vm中;

        3、methods中配置的函数,不要用箭头函数!!!否者this就不是vm了;

        4、methods中的函数,都是Vue所管理的函数,this指向vm 或组件实例对象;

        5、@click=“demo” 和@click=“demo($event)”效果一致,但是后者传参。

        6、@xxx="yyy",yyy可以写简单的语句

1.10事件修饰符

Vue中的事件修饰符:

        1、prevent:阻止默认事件(常用);

        2、stop:阻止事件冒泡(常用);

        3、once:事件只触发一次(常用);

        4、capture:使用事件的捕获模式;

        5、self:只有event.target是当前操作的元素时才触发事件;

        6、passive:事件的默认行为立即执行,无需等待事件回调执行完毕;(一般用来优化,移动端用的较多)

        7、修饰符可以连着写!!!例如:@click.prevent.stop(阻止默认行为而且阻止冒泡)

    


    

hello,{{name}}

点我提示信息
  • 1
  • 2
  • 3
  • 4
  • 5

1.11键盘事件

1、Vue中常用的键盘别名:

        回车 => enter

        删除 => delete(捕获“删除”和‘退格’键)

        退出 => esc

        空格 => space

        换行 => tab(特殊,必须配合keydown去使用)

        上 => up

       下=> down

        左 => left

        右 => right

2、Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意转为kebab-case(短横线命名)

3、系统修饰键(用法特殊):Ctrl、Alt、shift、meta(win键)

        (1)配合keyup使用:按下修饰键的同时,还得按下其他键,随后释放其他键,事件才触发。

        (2)配合keydown使用:正常触发

        (3)如果想ctrl + y 触发,可以写@keyup.ctrl.y

4、可以使用keycode去指定具体按键(不推荐,以后弃用)

5、Vue.config.keyCodes.自定义键名 = 建码。可以定制按键别名


    

hello,{{name}}

1.12计算属性

计算属性:

        1、定义:要用的属性不存在,通过已有的属性计算得来。

        2、原理:底层借助了object.defineproperty方法提供的getter和setter。

        3、get函数什么时候执行?

                (1)初次读取时执行一次

                (2)当依赖的数据发生变化时会被再次调用

        4、优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便

        5、备注:

                1、计算属性最终出现在vm上,直接读取使用即可

                2、如果计算属性要被修改,那必须的写set函数去响应修改,且set中要引起计算时依赖的数据发生变化。


    
姓:

名:

全名:{{firstname + '-'+ lastname}}

全名:{{fullname}}

       当不需要进行修改,只读取时,可以省略set,如下

computed:{
                // 详细
                // fullname:{
                //     get(){
                //         return this.firstname + this.lastname
                //     },
                //     set(value){
                //         const arr = value.split('-')
                //         this.firstname = arr[0];
                //         this.lastname = arr[1];
                //     }
                // }
                // 简写
                fullname(){
                    return this.firstname + this.lastname

                }

            }

1.13监视属性

监视属性watch:

        1、当被监视的属性变化时,回调函数自动调用,进行相关操作。

        2、监视的属性必须存在,才能进行监视!!

        3、监视的两种写法:

                (1)new Vue时传入watch配置

                (2)通过vm.$watch监视


    

今天天气很{{info}}



本节讲了watch属性里面的这两个属性和方法,immediate和handler

1.14深度监视

深度监视:

        (1)Vue中的watch默认不监视对象内部值得改变(一层)。

        (2)配置deep:true可以监视对象内部值得改变(多层)。

备注:

        (1)Vue自身可以监视对象内部值的改变,但是Vue提供的watch默认不可以!

        (2)使用watch时根据数据的具体结构,决定是否深度监视。

简写:

watch: {
                // 正常写法
                // isHot: {
                //     immediate: true,//初始化时让handle调用一下
                //     handler(newValue, oldValue) {
                //         console.log('isHot被修改', newValue, oldValue);
                //     }
                // }
                // 简写
                isHot(newValue, oldValue){
                    console.log('isHot被修改', newValue, oldValue);
                }
            },


            

        })
        // 正常写法
        // vm.$watch('isHot',{
        //         immediate: true,//初始化时让handle调用一下
        //             handler(newValue, oldValue) {
        //                 console.log('isHot被修改', newValue, oldValue);
        //             }
        //     })

        // 简写
        vm.$watch('isHot',function (newValue, oldValue) {
            console.log('isHot被修改', newValue, oldValue);
        })

1.15computed和watch之间的区别

computed和watch之间的区别:

        1、computed能完成的功能,watch都可以完成

        2、watch能完成的,computed不一定可以完成,例如:watch可以进行异步操作(函数的回调)

两个重要的小原则:

        1、被Vue管理的函数,最好写成普通函数function(){},这样this就指向Vue或组件实例对象

        2、所有不被Vue管理的函数(定时器回调函数,ajax的回调函数、promise的回调函数等),最好写成箭头函数()=>{},这样this的指向才是vm 或者组件实例对象。

1.16绑定样式

绑定样式:

                    1. class样式

                                写法:class="xxx" xxx可以是字符串、对象、数组。

                                        字符串写法适用于:类名不确定,要动态获取。

                                        对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。

                                        数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。

                    2. style样式

                                :style="{fontSize: xxx}"其中xxx是动态值。

                                :style="[a,b]"其中a、b是样式对象。



	
		
		绑定样式
		
		
	
	
		
		
		
{{name}}


{{name}}


{{name}}


{{name}}


{{name}}

1.17条件渲染

条件渲染:

                            1.v-if

                                        写法:

                                                (1).v-if="表达式"

                                                (2).v-else-if="表达式"

                                                (3).v-else="表达式"

                                        适用于:切换频率较低的场景。

                                        特点:不展示的DOM元素直接被移除!!!(DOM中看不到)

                                        注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”!!!还可以和标签template使用,template标签不会出现在DOM中

                            2.v-show

                                        写法:v-show="表达式"

                                        适用于:切换频率较高的场景。

                                        特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

                               

                            3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。

		

当前的n值是:{{n}}

1.18列表渲染

1.18.1v-for遍历

v-for指令:

                        1.用于展示列表数据

                        2.语法:v-for="(item, index) in xxx" :key="yyy"

                        3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)

		
		

人员列表(遍历数组)

  • {{p.name}}-{{p.age}}

汽车信息(遍历对象)

  • {{k}}-{{value}}

测试遍历字符串(用得少)

  • {{char}}-{{index}}

测试遍历指定次数(用得少)

  • {{index}}-{{number}}

1.18.2key作用与原理

面试题:react、vue中的key有什么作用?(key的内部原理)

                        1. 虚拟DOM中key的作用:

                                        key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,  随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:

                        2.对比规则:

                                    (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:

                                                ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!

                                                ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。

                                 (2).旧虚拟DOM中未找到与新虚拟DOM相同的key:

                                                创建新的真实DOM,随后渲染到到页面。       

                        3. 用index作为key可能会引发的问题:

                                            1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:

                                                            会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。

                                            2. 如果结构中还包含输入类的DOM:

                                                            会产生错误DOM更新 ==> 界面有问题。

                        4. 开发中如何选择key?:

                                            1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。

                                            2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示, 使用index作为key是没有问题的。

尚硅谷Vue笔记_第3张图片

尚硅谷Vue笔记_第4张图片

 1.18.3列表过滤

用到了filter(element)方法


    

One Piece

  • {{p.name}}-{{p.age}}

 1.18.4列表排序

用到了数组sort(p1,p2)方法


    

One Piece

  • {{p.name}}-{{p.age}}

1.19Vue数据监视

        1.19.1模拟数据监视原理(对象)

        简单模拟了vue的数据监视,不过vue监视的更加完善,多层都可以监视


    

        1.19.2Vue.set()方法

        Vue.set(target,key,val)或者vm.$set(target,key,val)可以向响应式对象里面添加(修改        )一个属性。

        注意:

                对象不能是Vue实例,或是Vue实例的根数据对象!!!(记住不能给vue或者vm添加就行)


    

性别:{{school.sex}}

        1.19.3模拟数据监视原理(数组)

给数组添加或者删除可以用:

        (1)vm.$set(vm.person.hobby,0,'gan')

        (2)数组的操作方法:vm.person.hobby.push('做梦'),vm.person.hobby.splice(0,1,'chi')


    

我的爱好

  • {{item}}

        1.19.4数据监视总结

尚硅谷Vue笔记_第5张图片

1.20收集表单数据

收集表单数据:

                    若:,则v-model收集的是value值,用户输入的就是value值。

                    若:,则v-model收集的是value值,且要给标签配置value值。

                    若:

                            1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)

                            2.配置input的value属性:

                                    (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)

                                    (2)v-model的初始值是数组,那么收集的的就是value组成的数组

                    备注:v-model的三个修饰符:

                                    lazy:失去焦点再收集数据

                                    number:输入字符串转为有效的数字

                                    trim:输入首尾空格过滤


    
账号:

密码:

年龄:

性别:

爱好: 睡觉 动漫 打游戏

所属地区:

其他信息:

你敢点我?给你好看的看看

1.21过滤器

过滤器:

                定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。

                语法:

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

                        2.使用过滤器:{{ xxx | 过滤器名}}  或  v-bind:属性 = "xxx | 过滤器名"

                备注:

                        1.过滤器也可以接收额外参数、多个过滤器也可以串联

                        2.并没有改变原本的数据, 是产生新的对应的数据


    

显示格式化后的时间

现在是{{fmtime}}

现在是{{gettime()}}

现在是{{nowtime | getFormate}}

现在是{{nowtime | getFormate('YYYY年MM月DD日')}}

现在是{{nowtime | getFormate('YYYY年MM月DD日') | myslice}}

现在是{{fmtime}}

1.22内置指令

我们学过的指令:

                        v-bind  : 单向绑定解析表达式, 可简写为 :xxx

                        v-model : 双向数据绑定

                        v-for   : 遍历数组/对象/字符串

                        v-on    : 绑定事件监听, 可简写为@

                        v-if        : 条件渲染(动态控制节点是否存存在)

                        v-else  : 条件渲染(动态控制节点是否存存在)

                        v-show  : 条件渲染 (动态控制节点是否展示)

                v-text指令:

                        1.作用:向其所在的节点中渲染文本内容。

                        2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会,并且不识别html标签。

                v-html指令:

                        1.作用:向指定节点中渲染包含html结构的内容。

                        2.与插值语法的区别:

                                    (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。

                                    (2).v-html可以识别html结构。

                        3.严重注意:v-html有安全性问题!!!!

                                    (1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。

                                    (2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!(可能会带走你的cookie哦!!!)

		
hello,{{name}}

                v-cloak指令(没有值):

                        1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。

                        2.使用css配合v-cloak(css里面用属性原则器【v-cloak】)可以解决网速慢时页面展示出{{xxx}}的问题。

尚硅谷Vue笔记_第6张图片

                v-once指令(没有值):

                        1.v-once所在节点在初次动态渲染后,就视为静态内容了。

                        2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。

初始化的n值是:{{n}}

                v-pre指令:

                    1.跳过其所在节点的编译过程。

                    2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。

1.23自定义指令

       1.23.1 函数式和对象式


        

当前的n值是

扩大10倍后的值


自定义指令总结:

                        一、定义语法:

                                    (1).局部指令:

                                                new Vue({ directives:{指令名:配置对象}) 或者     

                                                new Vue({ directives{指令名:回调函数})                             

                                    (2).全局指令:

                                                    Vue.directive(指令名,配置对象) 或   Vue.directive(指令名,回调函数)

                        二、配置对象中常用的3个回调:

                                    (1).bind:指令与元素成功绑定时调用。

                                    (2).inserted:指令所在元素被插入页面时调用。

                                    (3).update:指令所在模板结构被重新解析时调用。

                        三、备注:

                                    1.指令定义时不加v-,但使用时要加v-;

                                    2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。

                                     3.注意!!!里面的this不是vue,是window!

1.24生命周期

        1.24.1引出生命周期

生命周期:

                        1.又名:生命周期回调函数、生命周期函数、生命周期钩子。

                        2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。

                        3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。

                        4.生命周期函数中的this指向是vm 或 组件实例对象。


    

史蒂芬·胜

        1.24.2生命周期总结

常用的生命周期钩子:

                        1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。

                        2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

                关于销毁Vue实例

                        1.销毁后借助Vue开发者工具看不到任何信息。

                        2.销毁后自定义事件会失效,但原生DOM事件依然有效。

                        3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。

需要注意是:

前面的创建是数据代理和数据监视,一定不要以为是vm哦!!!

 尚硅谷Vue笔记_第7张图片


    

史蒂芬·胜

2.Vue组件化编程

        2.1组件化理解

        模块

                1. 理解: 向外提供特定功能的 js 程序, 一般就是一个 js 文件

                2. 为什么: js 文件很多很复杂

                3. 作用: 复用 js, 简化 js 的编写, 提高 js 运行效率
        组件
        1. 理解: 用来实现局部(特定)功能效果的代码集合(html/css/js/image…..)
        2.为什么: 一个界面的功能很复杂
        3. 作用: 复用编码, 简化项目编码, 提高运行效率
模块化
当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用。(就是把一个js文件拆成多个)
组件化
当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用,。

        2.2非单文件组件

        非单文件组件:一个文件里有多个组件

        单文件组件:一个文件里有1个组件

Vue中使用组件的三大步骤:

                    一、定义组件(创建组件)

                    二、注册组件

                    三、使用组件(写组件标签)

            一、如何定义一个组件?

                        使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;

                        区别如下:

                                1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。

                                2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。

                        备注:使用template可以配置组件结构。

            二、如何注册组件?

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

                            2.全局注册:靠Vue.component('组件名',组件)

            三、编写组件标签:

                           


    

        2.3组件注意事项

几个注意点:

                    1.关于组件名:

                                一个单词组成:

                                            第一种写法(首字母小写):school

                                            第二种写法(首字母大写):School

                                多个单词组成:

                                            第一种写法(kebab-case命名):my-school

                                            第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)

                                备注:

                                        (1).组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。

                                        (2).可以使用name配置项指定组件在开发者工具中呈现的名字。

                    2.关于组件标签:

                                第一种写法:

                                第二种写法:

                                备注:不用使用脚手架时,会导致后续组件不能渲染。

                    3.一个简写方式:

                                const school = Vue.extend(options) 可简写为:const school = options

        2.4组件嵌套


    

2.5 Vuecomponent

关于VueComponent:

                        1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

                        2.我们只需要写,Vue解析时会帮我们创建school组件的实例对象, 即Vue帮我们执行的:new VueComponent(options)。

                        3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!

                        4.关于this指向:

                                (1).组件配置中:

                                            data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。

                                (2).new Vue(options)配置中:

                                            data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。

                        5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。

                            Vue的实例对象,以后简称vm。

2.6一个重要的内置关系

                1.一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype

                2.为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。

尚硅谷Vue笔记_第8张图片


    

2.7单文件组件

Student.vue





School.vue





App.vue





main.js

import App from './App.vue'

new Vue({
    el:'.root',
    components:{
        App
    }
})

index.html


    

注意:

         使用默认暴露,引入的时候用  import ... from ...

         使用统一暴露或者分别暴露,引入的时候用  import {...} from ...

使用情况在school.vue代码里面有

 3.Vue.cli脚手架(command line interface)

3.1初始化脚手架

最重要!!!        安装脚手架之前首先需要安装node.js

3.1.1说明

        1. Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台)。
        2. 最新的版本是 4.x。
        3. 文档: vue.cli

3.1.2 具体步骤

第一步(仅第一次执行):全局安装@vue/cli。
                npm install -g @vue/cli
第二步: 切换到你要创建项目的目录 ,然后使用命令创建项目
                vue create xxxx
第三步:启动项目
                npm run serve
当需要暂停项目时:Ctrl+C
注意:
1. 如出现下载缓慢请配置 npm 淘宝镜像:
        npm config set registry https://registry.npm.taobao.org
2. Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpakc 配置,
请执行:
         vue inspect > output.js

3.1.3分析脚手架结构

├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ │── main.js: 入口文件
├── .gitignore: git 版本管制忽略的配置
├── babel.config.js: babel 的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件

3.1.4render函数

关于不同版本的Vue:

        1.vue.js与vue.runtime.xxx.js的区别:

                (1).vue.js是完整版的Vue,包含:核心功能+模板解析器。

                (2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。

        2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用

            render函数接收到的createElement函数去指定具体内容。

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

3.1.5修改默认配置

Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpack 配置, 请执行:
        vue inspect > output.js
不可以改的配置:文件夹:public、src;favicon.con、index.html、main.js
1、先创建一个vue.config.js
2、前往vue官网找到vue cli ,复制配置参考里面的pages

配置参考 | Vue CLI

语法检查lintOnSave(和pages同级)

module.exports = {
    pages: {
      index: {
        // page 的入口
        entry: 'src/main.js'
       
      }
  
    },
    lintOnSave:false//关闭语法检查
}

3.2ref属性

ref属性

1. 被用来给元素或子组件注册引用信息(id的替代者)
2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3. 使用方式:
    1. 打标识:```

.....

``` 或 ``````
    2. 获取:```this.$refs.xxx```






3.3props配置

props配置项

1. 功能:让组件接收外部传过来的数据(外部数据优先级大于内部)

2. 传递数据:``````

3. 接收数据:

    1. 第一种方式(只接收):```props:['name'] ```

    2. 第二种方式(限制类型):```props:{name:String}```

    3. 第三种方式(限制类型、限制必要性、指定默认值):
        props:{
            name:{
            type:String, //类型
            required:true, //必要性
            default:'老王' //默认值
            }
        }

    > 备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

student.vue





app.vue 





3.4mixin(混合、混入)

mixin(混入)

1. 功能:可以把多个组件共用的配置提取成一个混入对象(内部数据优先级大于外部)

2. 使用方式:

    第一步定义混合:

    ```
    {
        data(){....},
        methods:{....}
        ....
    }
    ```

    第二步使用混入:

    ​    全局混入:```Vue.mixin(xxx)```全局混入时在main.js里面引入


    ​    局部混入:```mixins:['xxx']    ```

mixin.js

export const a = {
    methods: {
        showName(){
            alert(this.name)
            console.log(666);
        }
    },
}

student.vue





school.vue





app.vue





main.js

/* 
  该文件是整个项目的入口文件
 */

// 引入vue
import Vue from 'vue'
// 引入APP组件,它是所有组件的父组件
import App from './App.vue'
// 关闭vue生产提示
Vue.config.productionTip = false
import {a} from './mixin.js'
Vue.mixin(a)
// 创建vue实例
new Vue({
  render: h => h(App),
}).$mount('#app')

3.5.插件

插件

1. 功能:用于增强Vue

2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。

3. 定义插件:

    ```js
    对象.install = function (Vue, options) {
        // 1. 添加全局过滤器
        Vue.filter(....)
    
        // 2. 添加全局指令
        Vue.directive(....)
    
        // 3. 配置全局混入(合)
        Vue.mixin(....)
    
        // 4. 添加实例方法
        Vue.prototype.$myMethod = function () {...}
        Vue.prototype.$myProperty = xxxx
    }
    ```

4. 使用插件:```Vue.use()```

尚硅谷Vue笔记_第9张图片

3.6scoped样式

scoped样式

1. 作用:让样式在局部生效,防止冲突。
2. 写法:```

mylist




myheader




myfooter





myapp





总结TodoList案例

1. 组件化编码流程:

    ​    (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。

    ​    (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:

    ​            1).一个组件在用:放在组件自身即可。

    ​            2). 一些组件在用:放在他们共同的父组件上(状态提升)。

    ​    (3).实现交互:从绑定事件开始。

2. props适用于:

    ​    (1).父组件 ==> 子组件 通信

    ​    (2).子组件 ==> 父组件 通信(要求父先给子一个函数)

3. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!

4. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。


3.8WebStorage

webStorage

1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)

2. 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。

3. 相关API:

    1. ```xxxxxStorage.setItem('key', 'value');```
                        该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。

    2. ```xxxxxStorage.getItem('person');```

        ​        该方法接受一个键名作为参数,返回键名对应的值。

    3. ```xxxxxStorage.removeItem('key');```

        ​        该方法接受一个键名作为参数,并把该键名从存储中删除。

    4. ``` xxxxxStorage.clear()```

        ​        该方法会清空存储中的所有数据。

4. 备注:

    1. SessionStorage存储的内容会随着浏览器窗口关闭而消失。
    2. LocalStorage存储的内容,需要手动清除才会消失。
    3. ```xxxxxStorage.getItem(xxx)```如果xxx对应的value获取不到,那么getItem的返回值是null。
    4. ```JSON.parse(null)```的结果依然是null。

3.9todoList本地存储

app





myfooter





3.10组件自定义事件

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:

    2. 第二种方式,在父组件中:

      
      ......
      mounted(){
         this.$refs.xxx.$on('atguigu',this.test)
      }
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

  4. 触发自定义事件:this.$emit('atguigu',数据)

  5. 解绑自定义事件this.$off('atguigu')

  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  7. 注意:通过this.$refs.xxx.$on('atguigu',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题! 

通过props实现子给父传值(以下是student给APP传值):

 app.vue



student.vue



总结:给父组件配置方法传递给子组件,子组件通过props接收后,通过调用该方法将值传递给父组件。

通过自定义事件子给父传值(以下是student给APP传值):(第一种方式)

app.vue



通过自定义事件子给父传值(以下是student给APP传值):(第二种方式)

app.vue



student.vue



3.11全局事件总线

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

  2. 安装全局事件总线:

    new Vue({
        ......
        beforeCreate() {
            Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
        },
        ......
    }) 
  3. 使用事件总线:

    1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.$bus.$on('xxxx',this.demo)
      }
    2. 提供数据:this.$bus.$emit('xxxx',数据)

  4. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

main.js

// 引入vue
import Vue from 'vue'
// 引入APP组件,它是所有组件的父组件
import App from './App.vue'
// 关闭vue生产提示
Vue.config.productionTip = false

// 创建vue实例
new Vue({
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus = this
  },
  
}).$mount('#app')

 school.vue



student.vue



3.12消息订阅与发布(pubsub)

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

  2. 使用步骤:

    1. 安装pubsub:npm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'

    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }
    4. 提供数据:pubsub.publish('xxx',数据)

    5. 最好在beforeDestroy钩子中,用PubSub.unsubscribe(this.pid)去取消订阅。

 student.vue



school.vue



3.13nextTick

  1. 语法:this.$nextTick(回调函数)

  2. 作用:在下一次 DOM 更新结束后执行其指定的回调。

  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。

视频中是先让dom结构发生改变后,然后获取焦点,就把这个获取焦点的回调函数放在nextTick中 

尚硅谷Vue笔记_第10张图片

 3.14Vue封装的过渡与动画

1.作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名

2.图示:

尚硅谷Vue笔记_第11张图片

3.写法:

  1. 准备好样式:

    • 元素进入的样式:

      1. v-enter:进入的起点

      2. v-enter-active:进入过程中

      3. v-enter-to:进入的终点

    • 元素离开的样式:

      1. v-leave:离开的起点

      2. v-leave-active:离开过程中

      3. v-leave-to:离开的终点

  2. 使用包裹要过度的元素,并配置name属性:

    
        

    你好啊!

  3. 备注:若有多个元素需要过度,则需要使用:,且每个元素都要指定key值。

 第一种:封装动画





第二种:用过渡





4.Vue中的ajax

4.1vue脚手架配置代理

方法一

在vue.config.js中添加如下配置:

devServer:{
  proxy:"http://localhost:8080"
}

说明:

  1. 优点:配置简单,请求资源时直接发给前端(8080)即可。

  2. 缺点:不能配置多个代理,不能灵活的控制请求是否走代理(如果public文件夹里面有的话,优先提供public里面的数据,这样就走不了代理)。

  3. 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)

方法二

编写vue.config.js配置具体代理规则:

module.exports = {
    devServer: {
      proxy: {
      '/api1': {// 匹配所有以 '/api1'开头的请求路径
        target: 'http://localhost:5000',// 代理目标的基础路径
        changeOrigin: true,
        ws: true,//用于支持websocket
        pathRewrite: {'^/api1': ''}//将路径带api1的都变成'',再加后面字符串
      },
      '/api2': {// 匹配所有以 '/api2'开头的请求路径
        target: 'http://localhost:5001',// 代理目标的基础路径
        changeOrigin: true,
        pathRewrite: {'^/api2': ''}
      }
    }
  }
}
/*
   changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
   changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
   changeOrigin默认值为true
*/

说明:

  1. 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。

  2. 缺点:配置略微繁琐,请求资源时必须加前缀。

vue.config.js

module.exports = {
    pages: {
      index: {
        // page 的入口
        entry: 'src/main.js'
       
      }
  
    },
    lintOnSave:false,//关闭语法检查
    // 服务器代理(方式一)
    /* devServer: {
      proxy: 'http://localhost:5000'
    } */

    // 服务器代理(方式二)
    devServer: {
      proxy: {
        '/api': {//匹配所有以 '/api'开头的请求路径
          target: 'http://localhost:5000',
          pathRewrite:{'^/api':''},//将路径带api的都变成'',再加后面字符串
          ws: true,//用于支持websocket
          changeOrigin: true//当为true时,告诉请求服务器host为5000,如果为false,则告诉请求服务器host为8080
        },
        '/demo': {//匹配所有以 '/demo'开头的请求路径
          target: 'http://localhost:5001',
          pathRewrite:{'^/demo':''},
          ws: true,//用于支持websocket
          changeOrigin: true//当为true时,告诉请求服务器host为5000,如果为false,则告诉请求服务器host为8080
        },
        
      }
    }
}

app.vue




4.2vue-resource(了解)

下载 vue-resource库:npm i vue-resource

使用:在main.js中引用,vue.use(vueResource),在需要发送请求的地方,以前用的是axios.get,现在需要this.$http.get就可以使用了。

vue项目常用的两个Ajax库:

  1. axios:通用的Ajax请求库,官方推荐,效率高
  2. vue-resource:vue插件库,vue 1.x使用广泛,官方已不维护

main.js

// 引入vue
import Vue from 'vue'
// 引入APP组件,它是所有组件的父组件
import App from './App.vue'
import vueResource from "vue-resource";
// 关闭vue生产提示
Vue.config.productionTip = false
Vue.use(vueResource)
// 创建vue实例
new Vue({
  render: h => h(App),
}).$mount('#app')

app.vue



4.3插槽

  1. 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件

  2. 分类:默认插槽、具名插槽、作用域插槽

  3. 使用方式:

    1. 默认插槽:

      父组件中:
              
                 
      html结构1
             
      子组件中:        
    2. 具名插槽:

      父组件中:
              
                  
      ​
                  
              
      子组件中:
              
    3. 作用域插槽:

      1. 理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)

      2. 具体编码:

        父组件中:
                
                    
                
                    
                
        子组件中:
                
                
                

 默认插槽用法:

app.vue




category.vue





具名插槽(有名字)

app.vue




category.vue





作用域插槽

app.vue





category.vue





5.vuex

1.概念

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

2.何时使用?

多个组件需要共享数据时

3.搭建vuex环境

下载vuexnpm i 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加工。(类似vue中的computed)

  2. store.js中追加getters配置

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

不用vuex写的

count.vue





用纯vuex写

count.vue





main.js

// 引入vue
import Vue from 'vue'
// 引入APP组件,它是所有组件的父组件
import App from './App.vue'
import vueResource from "vue-resource";
import store from './store/index'
// 关闭vue生产提示
Vue.config.productionTip = false
Vue.use(vueResource)
// 创建vue实例
new Vue({
  render: h => h(App),
  store,
  beforeCreate(){
    Vue.prototype.$bus = this
  }
}).$mount('#app')

store/index.js

import Vue from "vue"
import Vuex  from 'vuex'
//使用vuex插件
Vue.use(Vuex)
// 创建actions--用于响应组件中的行为
const actions = {
    increment(context,value){
        console.log('action被调用');
        context.commit('increment',value)
    },
    decrement(context,value){
        console.log('action中decrement被调动');
        context.commit('decrement',value)
    }
    
}
//创建mutations--用于操作数据(state)
const mutations = {
    increment(state,value){
        console.log('mutations中jia被调用');
        state.sum += value
    },
    decrement(state,value){
        console.log('mutations中decrement被调动');
        state.sum -= value
    }
}
//创建state--用于存储数据
const state = {
    sum:0
}
const getters = {
    BigSum(state){
        return state.sum * 10
    }
}
//创建并暴露store
export default new Vuex.Store({
    actions,mutations,state,getters
})

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(数组写法)
        ...mapGetters(['bigSum'])
    },
  3. mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

    methods:{
        //靠mapActions生成:incrementOdd、incrementWait(对象形式)
        ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    ​
        //靠mapActions生成:incrementOdd、incrementWait(数组形式)
        ...mapActions(['jiaOdd','jiaWait'])
    }
  4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

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

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

count.vue





 index.js

//该文件用于创建vuex中核心--store
import Vue from "vue"
import Vuex  from 'vuex'
//使用vuex插件
Vue.use(Vuex)
// 创建actions--用于响应组件中的行为
const actions = {
    increment(context,value){
        console.log('action被调用');
        context.commit('increment',value)
    },
    decrement(context,value){
        console.log('action中decrement被调动');
        context.commit('decrement',value)
    },
    incrementOdd(context,value){
        if(context.state.sum % 2){
            context.commit('increment',value)
        }
    },
    incrementWait(context,value){
        setTimeout(()=>{
            context.commit('increment',value)
        },500)
    }
    
}
//创建mutations--用于操作数据(state)
const mutations = {
    increment(state,value){
        console.log('mutations中jia被调用');
        state.sum += value
    },
    decrement(state,value){
        console.log('mutations中decrement被调动');
        state.sum -= value
    }
}
//创建state--用于存储数据
const state = {
    sum:0
}
const getters = {
    BigSum(state){
        return state.sum * 10
    }
}
//创建并暴露store
export default new Vuex.Store({
    actions,mutations,state,getters
})

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'}),

count.vue





 person.vue





index.js

//该文件用于创建vuex中核心--store

import Vue from "vue"
import Vuex  from 'vuex'
import countAbout  from './countAbout'
import personAbout  from './personAbout'
//使用vuex插件
Vue.use(Vuex)

//创建并暴露store
export default new Vuex.Store({
    //引入的模块写在配置项modules中
    modules:{
        countAbout,personAbout
    }
})

countAbout.vue

export default {
    //开启命名空间,默认是false,开启后就可以访问
    namespaced:true,
    actions:{
        increment(context,value){
            console.log('action被调用');
            context.commit('increment',value)
        },
        decrement(context,value){
            console.log('action中decrement被调动');
            context.commit('decrement',value)
        },
        incrementOdd(context,value){
            if(context.state.sum % 2){
                context.commit('increment',value)
            }
        },
        incrementWait(context,value){
            setTimeout(()=>{
                context.commit('increment',value)
            },500)
        }
    },
    mutations:{
        increment(state,value){
            console.log('mutations中jia被调用');
            state.sum += value
        },
        decrement(state,value){
            console.log('mutations中decrement被调动');
            state.sum -= value
        },
    },
    state:{
        sum:0,
    },
    getters:{
        BigSum(state){
            return state.sum * 10
        }
    }
}

personAbout.vue

import { nanoid } from "nanoid"
import axios from "axios"
export default {
    //开启命名空间,默认是false,开启后就可以访问
    namespaced:true,
    actions:{
        addPersonServe(context){
            console.log(context);
            axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
                response =>{
                    context.commit('addPerson',{name:response.data,id:nanoid()})
                },
                erro =>{
                    console.log(erro.message);
                }
            )
        }
    },
    mutations:{
        addPerson(state,value){
            state.personList.unshift(value)
        },
    },
    state:{
        personList:[{name:'张三',id:nanoid()}]

    },
    getters:{
        
    }
}

6.路由

尚硅谷Vue笔记_第12张图片

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

  2. 前端路由:key是路径,value是组件。

1.基本使用

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

  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可配置高亮样式)

    About
  5. 指定展示位置

2.几个注意点

  1. 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹。

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

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

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

 app.vue



home.vue和about.vue差不多





main.js

/* 
  该文件是整个项目的入口文件
 */

// 引入vue
import Vue from 'vue'
// 引入APP组件,它是所有组件的父组件
import App from './App.vue'
//引入Vuerouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router/index'
// import store from './store/index'
// 关闭vue生产提示
Vue.config.productionTip = false
//使用VueRouter
Vue.use(VueRouter)
// 创建vue实例
new Vue({
  render: h => h(App),
  router,
}).$mount('#app')

router/index.js

//该文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
import about from '../components/about.vue'
import home from '../components/home.vue'
//创建一个路由器
export default new VueRouter({
    routes:[{
        path:'/about',
        component:about
    },{
        path:'/home',
        component:home
    }]
})

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. 跳转(要写完整路径):

    News

home.vue





 router/index.js

//该文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
import about from '../pages/about.vue'
import home from '../pages/home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
//创建一个路由器
export default new VueRouter({
    routes:[{
        path:'/about',
        component:about
    },{
        path:'/home',
        component:home,
        children:[{
            path:'News',
            component:News
        },{
            path:'Message',
            component:Message
        }]
    }]
})

4.路由的query参数

  1. 传递参数

    跳转跳转
  2. 接收参数:

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

message.vue 



 detail.vue





5.命名路由

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

  2. 如何使用

    1. 给路由命名:

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

      跳转跳转跳转

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. 传递参数

    跳转
    {{ m.title}}             
    
    跳转

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

  3. 接收参数:

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

message.vue



 detail.vue





router/index.js 

//该文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
import about from '../pages/about.vue'
import home from '../pages/home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import detail from '../pages/detail.vue'
//创建一个路由器
export default new VueRouter({
    routes:[{
        path:'/about',
        component:about
    },{
        path:'/home',
        component:home,
        children:[{
            path:'News',
            component:News
        },{
            
            path:'Message',
            component:Message,
            children:[{
                // name:'detail',
                path:'detail/:id/:title',
                component:detail
            }]
        }]
    }]
})

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

router/index.js

import VueRouter from 'vue-router'
import about from '../pages/about.vue'
import home from '../pages/home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import detail from '../pages/detail.vue'
//创建一个路由器
export default new VueRouter({
    routes:[{
        path:'/about',
        component:about
    },{
        path:'/home',
        component:home,
        children:[{
            path:'News',
            component:News
        },{
            
            path:'Message',
            component:Message,
            children:[{
                // name:'detail',
                path:'detail',
                component:detail,

                /* //props的第一种写法,不推荐,值是对象,该对象中所有key-value都会以props形式传给detail组件
                props:{
                    id:'001',
                    title:'hello'
                } */
                /* //props的第二种写法,值为布尔值,若值为真,就会把该组件接收到的所有params参数,以pros形式传给detail组件
                props:true */
                //props的第三种写法,值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
                props($route){
                    return {id:$route.query.id,title:$route.query.title}
                }
            }]
        }]
    }]
})

 detail.vue





message.vue



8.的replace属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式

  2. 浏览器的历史记录有两种写入方式:分别为pushreplacepush是追加历史记录,replace是替换当前记录。路由跳转时候默认为push

  3. 如何开启replace模式:News

9.编程式路由导航

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

  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() //可前进也可后退,里面的参数是正的时候就是前进的步数,负就是后退的

10.缓存路由组件

​​​​​​​

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