Vue基础知识的加深理解

2.1 watch监视的表示


watch:{

isHot:{

immediate:true,

//handler什么时候调用?即是isHot发生改变的时候

handler(newValue,oldValue){

//这里通常可以根据新旧值之间的变化而执行有些操作

console.log(‘isHot被修改了,新值为:’+newvalue+‘旧值为:’+oldvalue)

}

}

}

ps:

  1. 这里watch监视的是isHot属性,你可以尝试改变isHot的值,你会发现便会触发isHot中的handler函数,控制台输出相应的提示;

  2. isHot是一个对象,其中具有多个配置属性,这里immediate表示isHot被初始化的时候调用,而handler则是isHot发生改变的时候再触发。

2.2 watch深度监听


深度监听是可以监听对象内部值的变化

  1. Vue中的watch默认不检测对象内部值的变化(它只能监听一层)

  2. 配置deep:true可以监听对象内部值的变化(多层数据结构)

备注:Vue自身是可以监听对象内部值的改变,但是Vue提供的watch默认不可以

使用watch时,根据数据的具体结构,决定是否采用深度监听

注意 :watch的监听建立在已经存在的属性上,注意下面错误示范

错误方式①:

data: {

numbers: {

a: 1,

b: 2

}

}

watch: {

a: {

handler(){

console.log(‘a被改变了’)

}

}

}

错误方式②

因此,正确的方式是,为该属性开启深度监听

还要要注意一个问题是,当使用简写的方式进行属性监听的时候,只有该属性不需要配置其他属性时,比如深度监听或者初始化时监听

2.3 vue循环列表中绑定:key的作用


首先按官网介绍的,可以主要用在Vue的虚拟Dom算法,在新旧节点对比时辨识VNodes。使用key时,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。

有相同父元素的子元素必须有独特的key,重复的key会造成渲染错误。

vue中循环列表时,绑定:key的值往往有两种方式,一是将循环列表的索引值index作为key,而是根据返回数据中的唯一标识作为key。不管以什么方式绑定key,key的值在列表中必须是唯一的,可以使用index的原因是索引值必然是唯一的。、

以下举例子说明以index或者唯一标识符绑定key的时的执行流程

2.3.1 index作为key

1.比如有初始数据如下:

{id:‘001’,name:‘张三’,age:‘18’},

{id:‘002’,name:‘李四’,age:‘19’},

{id:‘003’,name:‘王五’,age:‘20’}

2. 在模板使用v-for循坏该数据。以列表li的形式显示

    • {item.name} - {item.age}

      3. 那么vue会根据数据生成虚拟DOM,生成的虚拟DOM形式如下:

    • 张三 - 18
    • 李四 - 19
    • 王五 - 20
    • 4.将虚拟DOM转成真实的DOM

      ---------------------分割:以上是vue从绑定数据且从虚拟DOM转成真实DOM的过程----------------------

      5.接下来说明数据发现变化时,key绑定值位index时数据的改变,改变数据如下

      {id:‘004’,name:‘老刘’,age:‘20’},

      {id:‘001’,name:‘张三’,age:‘18’},

      {id:‘002’,name:‘李四’,age:‘19’},

      {id:‘003’,name:‘王五’,age:‘30’}

      6.此时由于数据变化了,那么vue就会重复数据渲染过程,此时根据新数据生成的虚拟DOM如下

    • 老刘 - 30
    • 张三 - 18
    • 李四 - 19
    • 王五 - 20
    • 7.将虚拟DOM转成真实DOM

      8.接下来解释为什么会出现以上的情况?

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

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

      -  旧虚拟DOM中内容没有变化的时候,则直接使用之前的真实DOM(比如上面的input的内容)

      -  若虚拟DOM中的内容发生变化了,则直接生成新的DOM,随后替换掉页面中之前的真实DOM

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

      • 直接创建新的真实DOM,随后渲染到页面上

      (3) 由于以上例子并没有绑定key值,那么每次循环的时候key值都是自上而下从0-n,而自上而下input值没有发生改变,因此直接复用

      3 Vue中数据绑定的原理

      =============

      下面先同个例子来简单说明一下vue中的双向数据绑定

      3.1 例子1


      比如我想通过点击按钮来直接该百年数组persons中某一项的数据:this.persons[0]={id:‘001’,name:‘马老师’,age:‘50’,sex:‘男’}

      却发现页面没有跟新:

      那么我们会发现,直接对persons数组中某一项进行更改是无效的,那么根据Vue双向数据绑定的原理,怎么样才能有效更改呢?

      以下是有效的更改方式:(即是对数组项的指定属性进行修改)

      this.persons[0].name=‘马老师’;

      this.persons[0].age=50;

      this.persons[0].sex=“男”

      3.2 例子2


      当你想给vue添加信新的属性时,也不能直接使用**this.student.sex='**男’进行增加,因此这样新增加的新属性是不具备数据的双向绑定的:

      那么问题来了,应该怎么样添加新的属性才可以达到响应式呢?根据vue官网提示,当你不是一开始在data中定义的数据,直接添加是不具备响应式的,如果想又不是直接在data中添加,而是后期想用的时候在某个地方添加的时候,可以通过API实现,如下:

      Vue.set(target,propertyName/index,value)

      1. 参数:

      • target :{Object |Array}

      • propertyName/index:{ staring | number }

      • value :{any}

      2. 返回值:设置的值

      3. 用法:

      向响应式随想中添加一个property,并确保这个新peopety同样是响应式的,且出发视图更新。它必须用于相映式对象上添加新property,因为Vue无法探测普通的新增property(比如this.myObject.newProperty=‘hi’)

      注意:对象不能是Vue实例,或者Vue实例的根数据对象

      实例:

      methods: {

      addSex() {

      Vue.set(this.student, ‘sex’, ‘男’)

      }

      }

      3.3 例子3

      3.4 总结


      1. Vue会监视data中所有层次的数据

      2. 如何检测对象中的数据?

      通过setter实现监视,且要在new Vue时就传入要检测的数据

      (1)对象中后追加的属性。Vue默认不做响应式处理

      (2)如需要给后添加的属性做响应式,请使用如下API:

      Vue.set(target,propertyName/index,value) 或

      vm.$set(arget,propertyName/index,value)

      1. 如何检测数组中的数据?

      通过包裹数组跟新元素的方法实现,本质上就是做了两件事:(Vue中对操作数组的相关方法进行包装,可以达到数据双向绑定)

      (1)调用原生对应的方法对数组进行更新

      (2)重新解析模板,进而更新页面。

      1. 在Vue修改数组中的某个元素一定要用如下方法:

      (1)使用这个API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()、

      (2)Vue.set() 或者 vm.$set()

      特别注意:Vue.set()和vm.$set()不能给vm或者**vm的根数据(vm._data)**对象添加属性

      4.收集表单数据

      ========

      4.1 核心原理


      核心是通过v-model指令和给表单元素添加value属性

      注意,在使用v-model指令实现数据双向绑定时,v-model实质上接收到的是表单元素的value值。由于对于输入框比如**“input、textarea”**用户输入的值即为value值,因此不用额外给input绑定value值。而对于其他非输入框的表单元素(比如:radio、checkbox等),想要使用v-model实现双向绑定时,通常需为其添加value属性,

      例子如下:

      4.2 总结


      1. ,则v-model收集的是value值,用户输入的就是value值

      2. ,则v-model收集的是value值,且要给标签配置value值

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

      (2)配置input的value属性:

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

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

      4.v-model的三个修饰符

      (1)lazy:失去焦点再收集数据

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

      (3)trim:过滤首尾空格

      5 过滤器

      =====

      6. 指令

      =======

      6.1 v-html指令


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

      2. 与插值语法区别

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

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

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

      (1)在网站上动态渲染任意html是非常危险的,容易倒是xss攻击

      (2)一定要在可信内容中使用v-html,永远不要在用户提交的内容上!(比如一些恶意人会通过其获取你的cookie等)

      6.2 v-cloak指令


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

      2. 使用css配合v-cloak可以解决网速慢时也买你展示出{{xxx}}的问题

      6.3 v-once指令


      1. v-once所在节点在初次动态渲染后,就视为静态内容了(即只读一次)

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

      6.4 v-pre指令


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

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

      6.5 自定义指令


      ! 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 [](()

      7 vue的生命周期

      ==========

      Vue的生命周期按执行顺序有:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestory、destoryed。

      7.1 beforeCreate


      vue在beforeCeate钩子函数中,进行了初始化、因为此时数据监测和数据代理还没开始,因此还无法通过vm访问到data中的数据、methods中的方法。

      7.2 created


      此时,已经完成数据检测、数据代理,因此可以在这里通过vm访问到data中的数据、methods中配置的方法。

      注意:警告created之后,由于Vue并没有开始编译了,需要经过下面的beforeMount、mounted阶段才完成模板解析。

      7.3 beforeMounted


      此阶段vue已经开始解析模板、生成虚拟dom(内存中),页面还不能显示解析好的内容。即此时页面呈现的是未经Vue编译的DOM结构。所有对DOM的操作,最终都不奏效。

      7.4 mounted


      经过上面的beforeMount之后,此时vue已经将内存中的虚拟DOM转成真实的DOM插入到页面中了。

      • 页面中呈现的是经过Vue编译的DOM

      • 对DOM的操作均有效(尽避免操作DOM),至此初始化过程结束,

      • 一般在此阶段运行:开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作。


      7.5 beforeUpdate


      经过上面的周期函数之后,页面已经渲染完毕,也可以相应数据。

      在这里,如果数据发生变化,那么在这里数据新的,只不过页面是旧的,也就是说页面尚未和数据保持同步更新。

      7.6 updated


      这里根据新数据,生成新的虚拟DOM,随后与旧的虚拟DOM进行比较,最终完成页面的更新,即完成了Model->View的更新。此时,数据是新的,页面也是新的。即保持数据和页面同步。

      总结图

      8 组件

      ====

      组件是可以复用的Vue实例,且带有一个名字。

      关于VueComponent:

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

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

      3. 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!(Vue内部会自动帮我们执行new VueComponent(options))

      4. 关于this的指向:

      5. 组件配置中:

      6. data函数、methods中的函数、watch中的函数、computed中的函数,它们的this指向均是【VueComponent实例对象】

      2.new Vue()配置中

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

      5.VueComponent的实例对象,可以简称为vc(组件实例对象)

      Vue实例对象,简称vm

      8.1 内置对象


      8.1.1  以下先引入原型对象

      function Demo(){

      this.a=1,

      this.b=2

      }

      //创建一个Demo的实例对象

      const d = new Demo()

      console.log(Demo.prototype)//显示原型属性

      console.log(d.proto)//隐式原型属性

      1.每个对象(或者构造函数)都有一个原型属性prototype

      2.每个对象的实例都有一个隐形原型属性

      3. 构造函数的原型属性和实例的原型属性均指向原型对象

      Demo.prototype === d.proto

      4.以下验证`Demo.prototype === d.__proto__`

      //通过显示原型属性操作原型对象,追加一个x属性,值为99

      Demo.prototype.x=99;

      console.log(‘@’,d.proto.x)

      //或者直接输出d.x(因为找不到时也会往原型链上查找)

      console.log(d.x)

      8.1.2 Vue与VueCompontent的关系

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

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

      注意:实例的隐形原型属性,一定是指向自己构造这的原型对象,那么显而易见

      Vue的实例对象vm的隐形属性指向Vue的原型对象

      Vue的原型对象的原型属性又指向Object的原型对象

      思考:那么Vue和VueComponent是如何联系起来的呢?

      Vue内部将VueConponent的原型对象指向了Vue的原型对象(目的:使得不管是Vue实例还是VueConponent实例均能公用Vue的方法以及实例)

      1.

      比如我要在vc上找x属性,当vc上没有x属性时,会沿着__proto__上去找(这个proto指向VueCompontent的原型对象),当VueCompontent的原型对象上没有找到x时,则往proto上找x,此时,vue中将VueCompontent的原型对象的原型属性proto(指向了Vue原型对象),此时在Vue原型对象上找x,此可以找到,注意,如果在Vue的原型对象中也没有找到的时候,则继续往Vue原型对象的proto上找,即找到Object

      9.render函数的理解

      =============

      在入口文件main.js文件中,默认引入的vue不是完整版的,是vue开发者在vue完整版基础上改动的(这里称之为“残缺”版本),且这个引入的vue是不具备编译模板功能的。因此,当你在main.js入口文件,在创建Vue实例的时候,试图同时实现模板编译时,如下,是会出错的

      报错如下:

      因此,vue团队引入render函数,实现template模板编译,render函数的本质作用是生成节点

      //完整版的rander函数

      render(createElement){

      return createElement(‘h1’,‘你好啊’) //render函数需要返回值

      }

      //简写

      render:(q)=>{

      return q(‘h1’,‘你好啊’)

      }

      //精简简写

      render: q=>q(App)//这里的App是import引入的App.vue组件

      //

      new Vue({

      el:‘#app’,

      //下面这行代码,完成了将App组件放入容器中

      render:h=>h(App)

      })

      思考:既然是要进行模板编译的,那为什么vue团队一开始不引入完整的,直接实现模板编译功能呢?原因是当你功能实现了之后,你的代码是需要通过webpack或者其他打包工具进行打包的,那么在进行打包之后,此时一些vue文件已经被编译成了浏览器能够识别的html、js、css等文件,那么在线上即是也不需要这个编译功能的。避免多此一举又占内存,因此vue团队一开始就是引入不带编译功能的vue。

      **疑问:**如果引入的“残缺”版本的vue,那么在其他组件中的标签是如何编译的呢?

      答:vue中专门引入了一个包,用来解析组件中的额标签

      总结:关于不同版本的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函数接收到的ceateElement函数去指定具体内容。

      9. 对脚手架进行功能定制化

      ===============

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

      2.新建一个vue.config.js可以对脚手架进行个性化定制,详见:[配置参考 | Vue CLI](()

      1. 脚手架的文件结构

      10.ref属性

      =========

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

      2. 应用在html标签(如div、h1等等)上获取的是DOM元素,应用在组件标签(.vue)上是组件实例对象(vc)

      3. 使用方式

      打标识:

      或者

      获取:this.$refs.xxx

      11. prop属性

      ===========

      prop属性在实现父子组件之间的通信中起到重要作用。

      使用方式如下:

      11.1 使用方式


      父组件中:  在引入的子组件中直接:<子组件 变量名1="值1“  变量名2="值2”  :变量名3=“值3”/>

      子组件中:

      使用props属性进行接收父组件传过来的数据(使用props接收过来的数据,类似在data中定义的数据,直接挂在到vm上,因此在模板上可以直接使用,但是不能直接更改props中从父组件接接收过来的数据,可以间接改变,下面会讲到)

      ps:当你想改变由父组件传递过来的数据时,不要企图直接修改,可以重新在data中定义一个变量来接收这个数据,然后通过更改data中这个新定义的变量去改变。

      在父组件向子组件传递数据的时候,需要使用v-bind(简写:)指令告诉vue其中传入的时js表达式,而不是字符串。当你不适用v-bind指令的时候,那么vue就会默认你传入的数据时字符串类型。

      11.2 单向数据流


      1. 所有的prop都使得其父子prop之间形成一个单向下行绑定:父级rpop的更新会向下流动到子组件中,但是反过来不行,这样会防止从子组件意外更变父组件的状态,从而导致你的应用的数据难以理解

      2. 额外的,每次父级组件发生改变时,子组件中所有prop都将会刷新到最新的值这样意味着你不应该在一个子组件内部中改变prop,如果你这样做了,vue会在浏览器的控制台中发出警告。

      11.3 总结


      功能:让组件接收外部传过来的数据

      (1)传递数据:

    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值