• Vue2进阶篇学习笔记


    Vue2进阶学习笔记

    前言

    欢迎来到知识汲取者的个人博客!在这篇文章中,我将为你介绍Vue.js的一些进阶知识,帮助你快速入门并掌握Vue开发的一些进阶技巧。Vue.js是一个流行的JavaScript框架,被广泛用于构建现代化、交互式的Web应用程序。它采用了MVVM(Model-View-ViewModel)架构模式,通过数据驱动视图的方式实现了高效的前端开发。在这片文章中我们将学习Vue脚手架的使用、组件的封装与使用事件与动画插槽VuexVueRouter、最后还有一些常用Vue组件库的推荐,如果你是一个初学者,相信通过本文的学习,一定可以让你对Vue有一个更加深入的认知,同时快速掌握这些进阶知识。

    PS:对于文章一些描述不当、存在错误的地方,还请大家指出,笔者不胜感激

    推荐阅读

    1、Vue脚手架学习

    1.1 Vue脚手架概述

    • 什么是脚手架

      image-20221216085217117

      上面是Vue脚手架的官方介绍,我们可以理解脚手架就是为自动帮我们构建项目的工具。Vue脚手架全名:Vue Command Line Interface,简称:VueCLI直接翻译就是Vue命令接口工具,不得不佩服第一次将这个东西翻译成”脚手架“这个词的人,VueCLI正如工地上的脚手架一样,能够快速帮我们自动搭建好Vue项目

      👉Home | Vue CLI (vuejs.org):Vue脚手架官方文档

    • 脚手架有什么作用

      自动一键生成vue+webpack的项目模版,包括依赖库,从而大大减少项目构建所需的时间

    • 脚手架如何使用

      下文会讲

    1.2 Vue脚手架安装

    • Step1:安装node.js

      参考文章:

      我们需要用到npm命令

    • Step2:安装VueCLI

      npm install -g @vue/cli
      
      • 1

      下载过慢的可以配置淘宝镜像

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

      image-20221216091409804

      安装后,重启cmd窗口,输入vue指令,如果呈现以下这样,就说明你的Vue脚手架已经安装好了

      image-20221216091739987

    • Step3:创建Vue项目

      vue create 项目名
      
      • 1

      注意:时你要切换到你需要创建项目的目录,不要在VueCLI的安装目录下直接创建Vue项目

      image-20221216092403014

      image-20221216092508627

    • Step4:运行创建好的Vue项目

      注意:要先使用cd vue_test指令进入刚刚创建好的Vue项目中,然后再执行npm run serve指令,运行Vue项目,在Vue脚手架初始化创建项目时,他会自带一个helloword,并且它会将这个项目默认部署在一个微型服务器上,这个服务器的默认端口号是8080,所以成功运行后,可以直接在浏览器访问到Vue脚手架自带的HelloWord项目

      image-20221216092748259

      备注:停止运行,直接在cmd窗口中按Ctrl + C

    image-20221216093357212

    可以看到项目无法访问了

    image-20221216093412842

    Vue模板项目的结构:

    image-20221216100909601

    Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpakc 配置, 请执行:vue inspect > output命令

    模板项目默认是引入精简版的Vue(缺少模板解析器,这只是一种精简版,此外还有很多不同的精简版),引入精简版Vue的目的是节约内存,因为如果一直使用完整版的Vue,当我们的项目被webpack打包时,会讲模板解析器打包,而webpack打包后的项目是已经经过解析了的,此时模板解析器显得很多余。所以当我们要使用精简版vue使用tempate添加DOM时,会报错,可以使用render函数解决

    render(createElement){
    	return 'h1','你好'
    }
    //简写:
    render:h => h(‘h1’,'你好')
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.3 常用属性

    • ref:用来给元组或子组件注册引用信息(id的替代者)

      当用在HTML标签上,是获取真实的DOM元素(和id的作用一样),当用在组件标签上,则是获取组件的实例对象(这个和id不一样,id是获取组件所在根标签的真实DOM,即获取的是组件最外层的div)

      实例

      <div ref="a">div>
      this.$refs.a
      
      • 1
      • 2
    • props

      App组件

      
      <Student name="张三" :age="18">Student>
      
      • 1
      • 2

      Student组件:

      {{name}}

      {{age+1}}

      //简单接收 props['name','age'] //接收且对数据进行限制 props:{ name:String, age:Number } //更加完善的配置 props:{ name:{ String, required:true //name是必要的,没有app组件没有传name过来就会报错 } age:{ Number, default:18 // 设置默认值,没有传age,age默认就是18 } }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20

      注意:如果props和data中数据出现重名,props中的数据优先级更高,props中的数据最好不要去修改,否则会出现警告,可能会导致Vue发生奇怪的bug,所以要按规范写,如果真的想要修改,可以在组件中重新定义一个变量

    • mixin:混合,把多个组件共有的配置提取成一个混入对象,作用是提高代码的复用性

      mixin.js:

      用于存放要复用的代码,可以复用数据、函数(包括生命周期函数),如果数据和普通函数在原组件中也存在,则以原来的为准,原来没有的,混合(mixin.js)中有的,就直接在原来的组件中加上。但是对于生命周期函数而言,两者都要

      //混合1:
      export const mixin = {
       	data(){
      		return{
      			name:"张三"
      		}
       	}
      }
      //混合2
      export const minx2 = {
      	mounted(){
      		console.log("mounted被执行了")
      	}
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      Student组件:

      import {mixin,mixin2} from '../mixin'
      export default{
          name:'School',
          data(){
              return{
                  name:'一中'
              }
          }//局部混合
          mixins:[mixin,mixin2]
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      main.js:

      //引入APP组件
      import {mixin,mixin2} from './mixin'
      Vue.mixin(mixin)
      Vue.mixin(mixin2)
      
      • 1
      • 2
      • 3
      • 4
    • scoped:随机生成一个data-v,类似于UUID

      作用:方式样式冲突,因为在一个Vue项目中,最终所有的样式都会汇总到一起,如果出现重名就会发生样式覆盖,后引入的组件会覆盖前引入组件的样式(就是学CSS时的”就近原则“)

      <style scoped class="demo">
      style>
      
      • 1
      • 2

    1.4 插件

    作用:用于增强Vue

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

    • Step1:定义一个插件

      export default {
          install(Vue, name){
              console.log(Vue+"++++"+name)
              
              //插件中还可以进行一些全局配置,比如:过滤器、全局指令、在Vue原型中添加数据、定义混入对象...
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • Step2:使用插件

      Vue.use(plugins, '张三')
      
      • 1

    2、组件基本概述

    • 什么是模块

      模块是一个提供特定功能的JS程序,一般的表现形式就是一个JS文件。模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程,有多种属性,分别反映其内部特性。

    • 模块化的作用

      • 提高复用率,模块化对每一个功能进行了划分,能够更好地移植相同代码
      • 提高编码的效率,降低编码的复杂度,模块化很好的界定各个功能,特别是对于大型系统的开发,让开发者能够分工明确
      • 提高系统的可维护性,模块化让系统更加清晰,能够更好地定位问题和修改代码
    • 什么是组件

      组件实现应用中局部功能代码和资源的集合组件化是指解耦复杂系统时将多个功能模块拆分、重组的过程,由多种属性、状态反映其内部特性。

      个人见解:是一个可重复利用的Vue实例,本质是代码的复用,类似于Java中的类,Java中的类也可以看作是一个组件

    • 组件化的优点

      • 提高复用率。
      • 提高编码效率。
      • 高扩展性。
      • 提高了可维护性。
    • 组件化和模块化的区别

      两者一般很难区分,因为两者的主要目的都相同, 都是为了提高代码的复用率,模块就是完成某一功能的程序,而组件是可重用代码的集合,组件和模块有时是可以相互转换的。但一般而言,模块的层级是要大于组件的层级的,一个大型项目,会先进性模块划分,然后再对每个模块进行组件划分。

      PS:这两个概念,在我看来并不是说一定要马上进行区分,通过后期编写项目都是可以慢慢深入理解区分的,现在我们只需要大致了解即可,因为他对我们的编码并没有影响

    3、非单文件组件

    一个文件中包含n个组件(n>=2)

    3.1 非单文件组件的基本使用

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <script src="./js/vue.js">script>
    head>
    <div id="app">
        
        <school>school>
        <hr>
        <student>student>
    div>
    <script>
        Vue.config.productionTip = false;
        //Step1:创建组件
        const school = Vue.extend({
            template: `
            

    学校姓名:{{schoolName}}

    学校地址:{{schoolAddress}}

    `
    , data() { return { schoolName: '一中', schoolAddress: '长沙' } } }); //Step1:创建组件 const student = { template: `

    学生姓名:{{studentName}}

    学生年龄:{{studentAge}}

    `
    , data() { //此处return可以避免组件之间数据共享的冲突(使用return可以让每个组件互不影响) return { studentName: '张三', studentAge: 18 } } } //Step2:全局注册组件 Vue.component('student', student) new Vue({ el: '#app', //Step2:注册组件 components: { // school: school //简写形式: school } });
    script> <body> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    image-20221215184714883

    注意事项:

    • 当组件名是多个单词是,可以使用kebab-case方式和cameCase方式

      备注:使用kebab-case方式命名组件需要使用引号包裹,使用cameCase组件必须是在脚手架环境下(后面学脚手架时会详细学习),否则会报错

    • 组件名不能和HTML的标签同名,否则会报错

    • 组件的名字直接在注册时确定,但是可以使用name属性在创建组件时确定

    3.2 组件的嵌套

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <script src="./js/vue.js">script>
    head>
    
    <body>
        <div id="root">
            <app>app>
        div>
        <script>
            Vue.config.productionTip = false;
    
            //创建student组件
            const student = {
                template: `
                

    {{student}}

    `
    , data() { return { student: '张三' } } } //创建school组件 const school = { template: `

    {{school}}

    `
    , data() { return { school: '一中' } }, components: { student } } //创建app组件,vm下面就它一个组件 const app = { template: `
    `
    , components: { school } } //创建vm new Vue({ el: '#root', data: { }, components: { app } })
    script> body> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    image-20221215193454882

    知识拓展VueComponent

    • 上面组件的本质都是一个VueComnent的构造函数,且不是程序员定义的,是Vue.extend生成的
    • 我们只需要直接使用组件标签,Vue在解析模板时,会自动帮我们去调用VueComnent函数,也就是执行new VueComnent(options)
    • 每次调用Vue.extend,都会返回一个全新的VueComponent对象
    • 组件配置中(data函数、methods函数、watch函数等)的this都是VueComponent(简称vc,组件实例对象),而 new Vue配置中所有的this都是vm
    • 函数拥有显示原型对象,对象拥有隐式原型对象,两者都指向同一个原型对象
    • 一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype ,所以组件实例对象vc可以访问到Vue实例对象vm上的属性和方法

    4、单文件组件

    一个文件中只包含一个组件(常见形式)。

    4.1 快速体验

    编写功能组件
    编写app组件
    编写main.js
    编写index.html
    测试

    image-20221215215953127

    • Step1:编写功能组件

      每一个组件都是一个小的部件,完成一个小的功能

      1)Student组件

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

      2)School组件

      
      
      
      
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • Step2:编写APP组件

      App组件用户统一管理其它所有的组件,APP组件是”万人之上,一人之下“,它只归vm管理

      
      
      
      
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
    • Stpe3:编写main.js

      mian.js负责创建vm

      import App from './App.vue'
      
      new Vue({
          el: '#root',
          components: { App }
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • Step4:编写index.html

      index.html真正用来展示的网页

      DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Documenttitle>
      head>
      
      <body>
          <div id="root">
              <App>App>
          div>
          <script src="../js/vue.js">script>
          <script type="module" src="./main.js">script>
      body>
      
      html>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

    备注:暂时还看不到效果,因为单文本组件需要在脚手架环境下使用

    4.2 Todo案例

    采用Vue单文本组件的形式编写一个Todo案例,具体效果如下所示:

    image-20230119090603481

    • Step1:拆分组件

      image-20230119090945688

      技巧:将功能和位置在一块的看作一个整体,将其作为一个组件;组件内部若功能相同,且会发生动态变化,则可以拆分成一个子组件;组件的命名要能够见名知意,如果组件的命名不合理就说明有可能你的组件拆分不合理

      1. 一个组件在用,放在组件本身即可;一些组件再用,放在父组件上,提高复用性

      注意:组件名不要和HTML中的关键字发生冲突

    • Step2:搭建环境

      • 在我们要编码的目录,使用vue脚手架提供的vue指令vue create todo-list,初始化一个Vue工程
      • 然后进入todo-list目录,使用npm run serve命令运行项目
    • Step3:编码(细节、bug拉满😇,对于我这种初学Vue的人而言还是有难度的,还好张老师够牛,讲解很详细)

      1. CSS部分,