Vue学习笔记(1)

157 阅读12分钟

优秀的VUE学习笔记
xmind思维导图软件

Vue初识

  • 1.为什么要学习vuejs
    • vue是一个渐进式框架,不需要对原来的框架全部重构,可以一点点的引入作为应用的一部分嵌入其中
      vue全家桶 core+Vue-router+Vuex
    • Vue特点和web开发中的高级功能
      解耦视图和数据;可复用组件;前端路由技术;状态管理;虚拟DOM
  • 2.Vuejs的安装
  • 3.vuejs的MVVM
    Model ViewModel View
  • 4.vue的生命周期

Vue基础语法

  • 1.插值操作
    • Mustache语法(双大括号)
    • V-once指令:使界面不进行跟随改变 (后不接等号)
    • V-html指令:将属性按照html格式进行解析并且显示对应内容
<h2 V-html="link"></h2>
Vue实例中 link:'<a href="http://www.baidu.com">百度一下</a>' 
  • V-text指令:和Mustache作用一样,将数据在页面中显示 。
    缺点:会覆盖掉标签中的固定文本内容
<h2>{{message}}</h2> ---Mustache
<h2 V-text="message"></h2>---V-text指令
  • V-pre指令:和Mustache作用一样,原封不动的将内容显示出来
  • V-cloak指令:在Vue解析之前,div中有属性V-cloak;解析之后,无属性V-cloak。因此,可以在V-cloak属性存在时添加隐藏样式,以此来避免因vue没有解析-来不及渲染页面-直接将源代码显示在页面中的问题
<style>[v-cloak]{display:none;}</style>
<div id="app" v-cloak>{{message}}</div>

  • 2.动态绑定属性V-bind
    • V-bind动态绑定基本属性
      V-bind:src
      V-bind:href

    • V-bind动态绑定class
      对象语法: (语法糖-简写):class='{类名:boolean}'

    • V-bind动态绑定style
      github源码

  • 3.计算属性computed
    github源码
    • 基础用法:在options里面添加computed属性并在其中直接添加函数(实际上是简写了set,get函数方法,这也就解释了为什么在model中调用计算属性时不加括号---虽然表面上是函数形式,但是实际上只个属性
    • 计算属性的set和get
      一般情况下计算属性没有set方法(不希望用户去修改属性)因此计算属性是个只读属性,将只含get方法的计算属性进行简写得到上一条中的基础写法
    • 计算属性与method(方法)的对比
      • methods(方法),即使关联属性没有改变,也需要再次执行,调用多少次执行多少次
      • 计算属性有缓存,只有关联属性改变才会再次计算,只要关联属性不变就只需要执行一次
  • 4.ES6中的块级作用域
    ** ES5之前由于if和for没有块级作用域的概念,所以在很多时候必须借助function(ES5中只有函数有作用域)的作用域(闭包)来解决外部变量会产生影响的问题;ES6中加入了let使得if、for有了块级作用域 **
    在ES6开发中优先使用const,只有需要改变某一个标识符的时候才使用let
    • 一旦给const修饰的标识符赋值之后,不能修改
    • 在使用const定义标识符,必须进行赋值,声明和赋值同时操作
    • 常量const的含义是指向的对象(内存地址)不能修改,但是可以 改变对象内部的属性
  • 5.事件监听
    V-on(@) 绑定事件监听器
    • 基本使用---事件调用的方法没有参数(无参无小括号)
    • 带参使用
      1.在事件定义时,调用方法省略了小括号,但是方法本身是需要一个参数的。这个时候VUE会默认将浏览器生产的event事件对象作为参数传入到方法。
      2.在方法定义时,需要event对象,同时又需要其他参数
      在调用时,通过$event获取到浏览器参数的event对象
    • V-on的修饰符
      @click.stop 调用event.stopPropagation()阻止事件冒泡
      @click.prevent 调用event.preventDefault()阻止默认行为 @click.once 只触发一次回调函数
  • 6.条件判断
    • V-if="true/false(boolean)"
      根据引号里面的布尔值(可以通过options来定义)控制是否需要渲染该标签中的文本内容
    • V-else
      当上一个标签中的V-if中的值为false时,则渲染当前标签中的文本内容
    • V-else-if
      条件渲染小案例:切换用户登录方式
      用户登录切换时input复用问题:
    • V-show
  • 7.循环遍历
    • 循环遍历数组
    • 循环遍历对象 循环遍历时,给对应元素或组件添加上 :key属性
*对于未绑定key属性的元素,在中间插入元素以后,需要对元素进行依次位移  
(效率低)  
*对于绑定key属性的元素(key属性和绑定的元素是一一对应关系,相当于给  
该元素添加了唯一标识),在中间插入元素以后需要判断内部元素是否发生变化,  
如果没有发生变化直接复用,提高虚拟DOM的效率 
*这种机制与vue的虚拟Dom算法有关系,使用key给每个节点做一个唯一标识,  
Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。   
key的作用主要是为了高效的更新虚拟Dom

  • 8.数组中的响应式方法(检测数组更新)
    Vue是响应式MVVM框架,当数据发生变化时,Vue会(监听)自动检测数据变换,视图会发生对应的更新
    Vue中包含了一组观察数组编译的方法,使它们改变数组也会触发视图的更新
    数组中的响应式方法: 作业案例:

    购物车案例(阶段综合案例important)
  • 9.JS高阶函数的使用
    高阶函数的意义是高阶函数的一些参数也是函数
    数组的三个高阶函数:
    • (1)fiter()---过滤函数
    • (2)map()---映射函数
      map函数是给数组中的每个元素做回调函数中的操作得到新的数组
    • (3)reduce()--汇总函数 牛逼!!!!
  • 10.V-model
    Vue中使用V-model实现数据和视图的双向绑定
    • v-model的基本使用
      • v-model:改变data中的message会使input中的text同时发生变化;同样地,改变input中的text也会使data中的message发生相应的变化。如此,V-model实现了message和input的双向绑定
      • v-bind:(语法糖格式):value="message"实现绑定动态属性--单向绑定,message的变化影响input文本内容发生变化,但是input文本文内容的变化不会影响message中的数据)
      • input内部有一个input事件,用于监听input文本框的内容是否发生变化,也可以实现双向绑定
    • v-model与radio(单选框)结合使用
      radio是一个选择按钮
      实现按钮互斥:给两个input(radio)添加一个同一个name属性,使用label不仅可以在点击按钮时选中,在选中文字时也可以选中(使用label需要添加id属性启动label效果) v-model与radio结合使用实现双向绑定(如果绑定同一个变量,则自动实现互斥效果)
    • v-model与checkbox(复选框)结合使用
    • v-model与select结合使用
    • 值绑定:值不要写死,而是动态的去绑定
    • v-model修饰符的使用 v-model.lazy
      v-model.number
      v-model.trim

组件(component)化开发

组件化是Vuejs中的重要思想,提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。任何应用都会被抽象成一颗组件树。

  • 组件的基本使用
    组件的使用三个步骤:创建组件构造器;注册组件;使用组件组件化的好处:提高代码的复用性
    ES6中新增 `` 来定义字符串,相比''和"",重要的优点是其可以换行,其他的两个字符串定义方法必须用+连接起来
  • 全局组件和局部组件
    • 组件的基本使用中的注册组件注册的就是全局组件,意味着可以在多个Vue的实例下使用
    • 只有在Vue实例中注册组件,才能注册为该实例下的局部组件
  • 父组件和子组件子组件只能在父组件的作用域中使用,无法单独在全局作用域下或根组件(vue实例)下使用,只能依托父组件使用;还有一个原因是,我们在编译父组件时,已经将包含在父组件中的子组件进了编译和渲染,无法再次单独编译
  • 组件注册的语法糖
    • 全局组件注册语法糖
    • 局部组件注册语法糖实际上语法糖就是将调用Vue.extend()省略,将组件构造器的内容直接用对象的形式添加到注册组件中。
  • 组件模板抽离写法
    用于将组件template(模板)中的html文本分离出来,使文本看起来简洁干净
  • 组件中的数据存储
    • 组件是一个单独的功能模块,有属于自己的HTML模板和数据data,组件无法直接访问vue实例中的数据(即使能访问,如果将所有的数据都放在vue实例中,vue实例会变的非常臃肿);
    • vue组件有自己保存数据的地方,即在注册组件时第二个参数对象中不仅包含template属性,还包含data属性用于存放数据;
    • data属性必须是个函数data(){}并且返回保存数据的对象,而不是个对象。
    • **组件中的data为什么必须是函数? **
      • 每注册一个相同组件,data函数都会返回一个新的对象(内存地址不同),使用同一数据的不同组件之间各自使用各自对象(内存地址指向不同),互不影响。每一个组件实例都应该有属于自己的状态
      • 但是如果data是对象,使用同一数据的不同组件指向同一块内存空间(内存地址指向不会发生变化),对任意组件进行操作都会影响其他组件中的数据
      • 在data是函数的前提下,如果开发需求就是需要相互影响,则需要将data函数return的对象单独写出来,此时的对象是唯一的对象(内存地址唯一),不能再创造,就实现了各组件之间公用一个对象,互相影响。
  • 父子组件通信 Vue提供两种方式进行父子组件之间的通信:
    • 通过props(propertie)向子组件传递数据(父传子props定义有很多种方式,开发中props不常用数组写法,常用对象写法(可以指定传入数据的类型;可以提供默认值(在没有传递值的时候子组件使用默认值)) 注意!!!
      @1.如果子组件中的props采用驼峰标识,那么在使用组件(步骤三)时父组件向子组件传递数据一定要将子组件(等号左边)的驼峰标识改为短线小写相接
      @2.定义子组件中的template时必须含有一个根标签(外层标签),不能多个标签并列且在毫无外层标签的包裹的情况下存在

    • 通过自定义事件向父组件发送消息(子传父)

  • 父子组件之间的通信案例
    • 父子组件之间互相通信--结合双向绑定案例该代码实现四个功能以及一些细节处理:
      (1)实现父传子:使用props,:(v-bind)
      (2)实现文本框和子组件的双向绑定:使用v-model(拆分为:和@) **注意!!!**对子组件中的props属性内容(也就是子组件中的数据)进行修改,最好通过父组件的重写对子组件进行改变,避免直接对子组件进行修改。因此,通过v-model进行双向绑定的时候,不能直接绑定在子组件props上,而应该在子组件中创建一个data或计算属性并绑定在其上,该案例中采用了在子组件中创建data属性来进行文本框和子组件的双向绑定
      (3)实现文本框传子再传父(由于文本框并未和父做直接绑定):使用emit@首先在第二个功能已经实现了文本框和子组件的双向绑定,即给子组件定义了methods属性添加两个函数num1Inputnum2Input。现在我们同时可以在这两个事件中添加 emit 和@ **首先**在第二个功能已经实现了文本框和子组件的双向绑定,即给子组件定义了methods属性添加两个函数num1Input和num2Input。现在我们同时可以在这两个事件中添加 emit发出numchange事件把子组件数据dnumber传递给父组件num
      其次 给父组件添加method属性,其中包含numchange事件监听文本框的内容发生改变,并接受子组件传递来的内容。 最后在使用组件div中添加@numchange
      (4)实现上文本框和下文本框之间的数据联动变化问题:也使用emit@在子组件methods中在此添加 emit 和@ 在子组件methods中在此添加 emit ,在num1Input发生num2change事件将修饰(dnumber1和dnumber2之间的关系)过后的子组件数据dnumber2传递给子组件并联动父组件进行改变,同理得另一个联动效果
    • 父子组件之间互相通信--结合双向绑定案例(watch实现)
      watch是组件对象的属性,和el、data、template是并列关系。watch是一个对象属性可以用于监听某些属性的改变
  • 父子组件的访问
    • 父组件访问子组件 children children或 refs(可访问多个子组件)
      • children是一个数组类型,它包含所有的子组件对象,由于通过下标值去获取数据一般是不太建议的(涉及到增删问题),只有在需要拿到所有子组件的时候才会使用,所以在真实开发中一般不会使用 children是一个数组类型,它包含所有的子组件对象,由于通过下标值去获取数据一般是不太建议的(涉及到增删问题),只有在需要拿到所有子组件的时候才会使用,所以在真实开发中一般不会使用 children获取子组件信息。
      • refs是一个对象类型,默认是个空对象一般开发中会使用 refs是一个对象类型,默认是个空对象 **一般开发中会使用 refs去获取信息,只需要在使用组件(第三步骤)时在相应的子组件中添加ref=“aaa”就可以在父组件methods中使用this.refs.aaa去获取该子组件对象、使用this. refs.aaa去获取该子组件对象、使用this. refs.aaa.name获取该子组件中的name**
    • 子组件访问父组件 parent子组件访问根组件parent 子组件访问根组件 root

组件化高级---插槽slot

插槽的目的是让我们原来的设备具备更多的扩展性。组件的插槽也是为了让我们封装的组件更加具有扩展性,提高复用性。让使用者可以决定组件内部的到底展示什么内容
例如,移动网站中的导航栏,每个页面的导航栏有共性,也有不同。最好的处理方式就是
将共性抽取到组件中,将不同暴露为插槽
,预留了插槽后就可以让使用者根据自己的需求觉得插槽中插入什么内容

  • 插槽的基本使用:在组件中写入<slot>默认值<slot/>,在使用组件时(第三步)要么什么都不写在插槽中直接使用默认值,要么在组件中写入替换值<cpn>替换值<cpn/>将插槽处替换为替换值
  • 具名插槽的使用---区分多个插槽
    实际开发中多用具名插槽,例如导航栏
  • 作用域插槽
    • 编译作用域
      在哪个模板下添加属性就只能在对应的组件中寻找对应属性。父组件模板的所用东西都会在父级作用域里编辑,子组件模板的所有东西都会在子级作用域里编译。例如,在根组件模板中添加了v-show属性,就需要在vue实例(根组件)中查找v-show对应的属性;在子组件模板中添加了v-show属性,就只能在子组件中查找v-show对应的属性并使用;
    • 作用域插槽的使用
      父组件模板只能去父组件查找数据,为了解决插槽之间数据不共享的缺点,提出作用域插槽。因此作用域插槽的目的是希望在父组件模板中使用插槽展示子组件数据

模块化开发

模块化存在的意义:可以解决多人协同开发时多个JS之间串用变量导致的问题(使用闭包解决又出现了代码复用性降低的缺点,但在闭包中定义一个对象用于存放需要导出的变量,使用return导出该对象,就可以将闭包中无法共享的变量传递出去,这就是模块化的雏形);解决原生JS对多个JS文件顺序的强制性
常见的模块化规范:commonJS、AMD、CMD、Modules(ES6)
模块化要在node环境中实现,单纯的模块化代码不起任何作用
模块化的核心:导出和导入从当前模块(一个JS 文件是一个模块)中导出一个对象{}包含需要导出的变量 从相应的JS文件中获取一个对象,再从对象中取出变量

  • ES6模块化实现---导入导出的注意事项
    1、使用export和import时一定要在相应的文件中添加属性type=“module”,才能让浏览器去解析导入导出
    2、export default是为了让使用导出对象的用户直接调用导出对象,非必需知道导出对象的名字,导入时随便用什么名字都可以。注意!一个文件只有一个export default
    3、统一全部导入
    import * as aaa from './bbb.js' aaa.flag

Webpack——前端模块化打包工具

  • 作用:模块化开发,处理模块间的依赖关系;文件压缩合并等打包成一个或多个包
  • grunt/guip更强调前端流程自动化,前端自动化任务管理工具,模块化不是它的核心;webpack强调模块化开发管理
  • webpack依赖node环境,node环境中包含各种依赖的包,其中npm工具(node packages manager)用于管理这些包
    webpack3.6和vue cli2匹配
  • webpack基本使用
    • 创建两个文件夹src各文件之间可以使用多种规范进行导入导出,但是都必须在终端中进行webpack打包才能解析成浏览器认识的东西
    • 在终端中使用webpack进行打包:将src文件夹中的入口文件(main.js)(其中包含了和入口文件有依赖关系的所有文件)打包并解析为dist文件夹中bundle.js
  • webpack配置
    webpack的基本使用[webpack .src/main.js .dist/bundle.js]比较啰嗦,需要输入待打包文件和目标文件。
    • 入口和出口函数的配置
      因此,我们需要一个webpack配置文件webpack.config.js直接将其配置好,在终端中直接输入[webpack]即可进行打包。
      在配置文件时需要在终端导入一些依赖node的包在src(开发者源码)生成package.json此时直接在终端中直接输入webpack即可打包
      以上我们使用的webpack都是全局webpack,在终端中直接输入webpack均使用的是全局,但是在开发过程中一般都使用本地webpack打包
    • 局部安装webpack
      我们需要在终端中输入 npm install webpack@版本号 --save-dev在本地安装webpack,此时在package.json中就会出现 开发依赖 的属性,代表已经在本地安装了webpack
      同时可以
      追加映射
      ,不仅可以在配置文件中将入口和出口直接映射到webpack,也可以将webpack映射到npm run build直接进行打包,并且优先使用的是本地webpack
  • webpack中CSS文件的配置——loaderwebpack打包时会根据入口函数中的依赖关系一层一层打包文件,不产生互相依赖关系的文件不会参与打包
    • 首先需要在入口函数中导入CSS文件产生依赖关系
    • 通过终端npm安装对应loader——>在webpack.config.js中进行配置
    • 终端输入 npm run build进行打包
  • webpack——图片文件处理
    • 图片处理:通过url把图片导入CSS后需要对其进行一系列的配置,才可以通过其与入口函数的依赖关系进行打包其中limit中有很多需要注意的地方!!! 当需要用filter-loader模块进行打包时,webpack自动将图片加载到dirt中并起了一个巨长的名字(防止重名)。但单纯的CSS文件中url指向当前文件夹src,因此调试过程中图片无法显示出来。此时就需要通过配置给CSS-url自动添加dirt
    • 修改文件名称
  • webpack——ES6语法处理(ES6转ES5)
  • webpack——使用Vue的配置过程
    之前使用vuejs是在官网上静态下载vuejs,再使用script标签引入vue.js(源码方式)并实例化vue对象进行操作
    现在我们需要在webpack环境中集成Vuejs(模块化方式管理vue)
    • 此时我们使用安装vuejs的第三种方式 “npm安装” 将vue安装到node_modules library root中
    • 此时可以将vue当做一个模块,通过 **import Vue from 'vue'**构建依赖,则将vue将引入
    • 创建好vue实例后我们需要npm run build再次打包,此时有可能会出现报错——注意!!!
    • 创建vue时el和template的区别
    • vue终极使用方案
      1.将上一小节中创建的template抽离出来,使用组件2.在src文件夹中创建一个vue文件夹专门用于存放vue代码,在该文件夹下创建一个.js文件,将组件直接写入该文件并导出,在实例化vue对象的js文件中直接导入即可3.上一步导出的组件依然没有将template和其他属性的js代码分离出来,所以可以创建一个Vue Component文件(一定要先npm再配置后使用)用于代替上一步操作,将一个完整的组件拆分为template和script,并且可以给模板定义style4.可以在上一个vue component文件中给组件添加一个子组件,进行层级操作,实现父子组件之间的通信(可以添加一层一层的子组件实现组件化开发)
  • webpack——plugin插件
    • 添加版权Plugin
    • 打包html的plugin此时再进行打包就可以在dirt(运行时代码)中创建index.html并自动生成script标签
      接下来,在dist文件夹下的index.html中进行一些实际操作与bundle.js中的内容进行绑定,并在当前情景下对一些之前配置的多余操作进行删除
      1.不需要在src中指定dist,因为index已经在dist文件夹下——>需要将webpack.config.js文件下publicpath删除
      2.自动生成<div id="app"></div>
    • js压缩的plugin
  • webpack——搭建本地服务器搭建本地服务器可以实现直接在webpack提供的端口下(也可以在dev中添加--open自动进入)进入浏览器查看修改数据后的结果(在本地服务器测试的结果)(浏览器自动刷新),无需每次修改都要编译打包再打开查看测试结果,减少了浏览器的消耗。等全部测试在本地服务器完成后,可以在终端中终止本地服务器测试操作并npm run build进行真正的打包
  • webpack——配置文件的分离
    • 对开发时、编译(发布)时用到的配置分别进行抽离开发时base.config.js+dev.config.js
      发布时base.config.js+pro.config.js
    • 合并配置文件现在使用三个配置文件代替webpack.congfig.js,同时还需要在package.json文件中指定配置文件,否则打包文件时会默认运行webpack.config.js而因找不到文件报错此时还会出现问题,在npm run build打包时会打包到build中,这是因为当时我们在设置创建dist路径时是在当前文件夹下创建一个dist文件修改为

vuecli-脚手架

(面试)runtime-complier和runtimeonly的区别
区别只在入口函数main.js中 使用render,createElement(组件)最终都会将组件解析成不含template的对象,但里面包含render函数,因此实际开发中直接使用runtimeonly直接进行render解析,而不是解析template

Vue CLI3

rc=run command 运行终端
vcs=version control system 版本控制系统