Vue学习笔记

初始Vue

  • 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
  • root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法
  • root容器里的代码被称为vue模板
  • Vue实例和容器是一一对应的
  • 真实开发中只有一个Vue实例,并且会配合组件一起使用
  • {{xxx}}中的xxx要写js表达式,并且xxx可以自动读取到data中的所有属性,一旦data中的数据发生改变,那么模板中用到该数据的地方也会自动更新
  • js表达式和js语句的区别:表达式:一个表达式会产生一个值,并且可以放在任何一个需要值的地方,如:a,q+b,function(1),x===y?a:b;js语句:if(),for()

  

hello,{{name}}

模板语法

  • 插值语法:

    功能:用于解析标签体内容

    写法:{{xxx}},xxx是js表达式,并且可以直接读取到data中的所有属性
  • 指令语法:

    功能:用于解析标签(包括:标签属性,标签体内容,绑定事件...)
    举例:v-bind:href="xxx" 或 简写成 :href="xxx",xxx同样要写成js表达式,并且可以直接读取data值的所有值

数据绑定

vue中有两种数据绑定的方式

  • 单向绑定(v-bind):数据只能从data流向页面
  • 双向数据流(v-model):数据不仅能从data流向页面,还能从页面流向data

1.双向绑定一般懂用于表单类元素上(如:input,select等),2.v-model:value 可以简写成v-model,因为v-model默认的是value的值

el与data的两种写法

  • el的两种写法:a:new Vue()的时候配置el属性,b:先创建Vue实例,随后通过vm.$mount("#root")指定el的值
  • data的两种写法:a:对象式,b:函数式.如何选择:在组件中写的时候必须用函数式,否则会报错.

一个重要的原则:由Vue管理的函数,一定不要写成箭头函数,一旦写成箭头函数,this的指向就不再是Vue实例了

Object.defineProperty


数据代理

  • 通过一个对象代理对另一个对象中属性的操作(读/写)
let obj = {x:100}
  let obj2 = {y:200}

  Object.defineProperties(obj2,'x',{
    get(){
      return obj.x
    },
    set(value){
      obj.x = value
    }
  })
  console.log(obj2.x) //输出结果为100
  obj2.x = 300,
  console.log(obj.x) //输出值为300 直接打印obj也可以看出
  
  //上述代码通过数据代理,通过obj2就可以操作obj中x的值

Vue中的数据代理

  • 1.Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
  • 2.Vue中数据代理的好处:更加方便的操作data中的数据
  • 3.基本原理:通过Object.defineProperties()把data中的所有属性添加到vm身上.为每一个添加vm身上的属性都指定一个对应的setter和getter.在getter和setter内部去操作(读/写)data中对应的属性

常见指令

  • 事件处理v-on:xxx

事件的基本使用:1.使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名.2.事件的回调需要配置在methods对象中,最终会在vm上.3.mehods中配置的函数,不要用箭头函数,否则this就不是vm了.4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象.5.@click="demo"和@click=demo($event)效果一样,但后者可以传参

 
  



vue中的事件修饰符
  • prevent 阻止默认事件(常用)
  • stop 阻止冒泡事件(常用)
  • once 事件只触发一次(常用)
  • capture 使用事件的捕获模式
  • self 只有event.target是当前操作的元素时才触发事件
  • passive 事件的默认行为立即执行,无需等待事件回调执行完毕
键盘事件
  • enter 会车键
  • delete 删除
  • esc 退出
  • tab 换行(特殊,必须配合keydown使用)

计算属性与监视


  

{{fullName}}

深度监视
  • vue中的watch默认不监测对象内部值的改变(一层)
  • 配置deep:true可以检测对象内部的改变(多层)

  

今天天气很{{info}}

computed和watch的区别

1.computed能完成的功能,watch都可以完成,2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作

两个重要小原则

1.所被vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象

2.所有不被vue所管理的函数(定时器的回调函数,ajax的回调函数,promise的回调函数)
,最好写成箭头函数,这样this的指向才是vm或组件实例对象

绑定样式

  • class样式
    :class="xxx", xxx可以是字符串,对象,数组.字符串写法用于:类型不确定,需要动态获取.对象写法适用于:要绑定多个样式,个数不确定,名字也不确定.数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用
  • style样式
    :style = "{fontSize:xxx}" 其中xxx是动态值.:style='[a,b]' 其中a,b是样式对象

  
{{name}}


{{anme}}


{{anme}}


{{anme}}


{{anme}}


{{anme}}


{{anme}}


条件渲染 v-show v-if

v-show是在样式上隐藏disply:none,v-if直接不创建这个组件.在开发中如果切换频率高的显示和隐藏用v-show

列表渲染 v-for

可以遍历数组,字典,字符串,指定次数


  

人员列表

    {{p.name}}---{{p.age}}
Vue中key的作用

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

  • 旧虚拟Dom中找到了与新虚拟Dom相同的key:1.若虚拟Dom中内容没有变化,直接使用之前的真实Dom.2.若虚拟Dom中内容变化了,则生成新的真实Dom,随后替换掉页面中之前变化的真实Dom
  • 旧虚拟Dom中未找到与新虚拟Dom相同的key:创建新的真实Dom,随后渲染到页面

Vue监视数据的原理

1.vue会检测data中的所有层次的数据

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

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

  • 对象中后裔追加的属性,Vue默认不做响应式处理
  • 如需给后添加的属性做响应式,请使用如下API:
Vue.set(target,propertyName/index,value)或者Vue.$set(target,propertyName/index,value)

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

通过包装数组更新元素方法的实现,本质上就是做了两件事

  • 1.调用原生对应的方法对数组进行更新
  • 2.重新解析模板,进而更新页面
    4.在Vue中修改数组中的某个元素一定要用如下方法(不要用下标赋值的方法去做):

    1.使用这些API:push(),pop(),shift(),splice(),sort(),reverse()

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

特别注意:Vue.set()和Vue.$set()不能给vm或者vm的根元素(data)添加属性

input表单有关

  • 若:,则v-model收集的是vlaue值,用户输入的就是value
  • 若:,则v-model收集的是value值,且要给标签配置value值
  • 若:
    1.没有配置input的value值,那么收集的就是checked(勾选 或 未勾选,是布尔值)

    2.配置input的value值:

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

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

v-model的三个修饰符:lazy:失去焦点再收集数据.number:输入字符串转为有效的数组.trim:输入收尾空格过滤

过滤器

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

语法:

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

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

备注: 1.过滤器也可以接收额外的参数,多个过滤器也可以串联.2.并没有改变原本的数据,是产生新的对应的数据.(过滤器的值是挨个传递的,第一个过滤器返回的值作为第二个返回值的参数使用值)


  

过滤器,显示格式化之后的时间

现在的时间是:{{time}}

现在的时间是):{{time | timeForamter}}

现在的时间是:{{time | timeForamter('YYYY_MM_DD') | mySlice}}

内置指令

  • v-text:向其所在的节点中渲染文本内容,与插值语法的区别:v-text会替换掉节点中的内容,{{xxx}}则不会
  • v-html:像指定节点渲染包含html结构的内容.ps:v-html有安全性问题,容易导致xss攻击(获取到网站上的cookie)
  • v-cloak:可以通过设置属性形式[v-cloak]的display:none在数据未加载之前隐藏节点,避免出现插值语法
  • v-once:只渲染一次
  • v-pre:预编译指令,跳过其所在的节点编译过程(不会解析节点所在的插值语法,指令语法)

自定义指令


  
  

{{name}}

当前的值是:

增加10倍的值是:

生命周期

常用的生命周期钩子:

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

2.beforeDestroy:清除定时器,解绑自定义事件,取消订阅消息等[收尾工作]

关于销毁Vue实例:

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

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

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

//无法通过vm访问data中的数据,methods中的方法
     beforeCreate() {
       
     },
    //可以通过vm访问到data中的数据,methods中配置的方法
     created() {
       
     },
    // 此时1.页面呈现的是未经Vue编译的Dom结构.2.所有对Dom的操作,最终都不奏效
     beforeMount() {
       
     },
     //Vue完成模板的解析,并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted.此时1.页面中呈现的是经过Vue编译的Dom.2.对Dom的操作均有效(尽可能避免).
     //至此初始化过程结束,一般在此进行:开启定时器,发送网络请求,订阅消息,绑定自定义事件等初始化操作
    mounted() {
      
    },
    //此时:数据是新的,但页面是旧的,即:页面尚未和数据保持同步
    beforeUpdate() {
      
    },
    // 此时:数据是新的,页面也是新的.即:页面和数据保持同步
    updated() {
      
    },
    // 此时:vm中所有的:data,methods,指令等等.都处于可用状态,马上要执行销毁过程.一般在此阶段:关闭定时器,取消订阅消息,解绑自定义事案件等收尾操作
    beforeDestroy() {
      
    },
    // 销毁完毕
    destroyed() {
      
    },

组件

实现应用中局部功能代码和资源的集合.分为非单文件组件和单文件组件.非单文件一般是在html中包含很多组件.单文件组件一般是值一个.vue文件就是一个组件

使用(非单文件组价)组件的步骤:

  • 1.创建组件
 //Vue.extend()可以省略
 const school =  Vue.extend({
      // 注意Vue2只允许也有个根标签
      template:`
      

{{schoolname}}

{{schooladdress}}

`, // 组件中的data必须用函数式,不然不能保证数据修改不互相影响 data() { return { schoolname:'上海高级中学', schooladdress:'青浦区十二河西路45号' } }, })
  • 2.注册组件
 const vm = new Vue({
     dta:{
       name:"世界你好",
       n:1
     },
    //  此处为局部注册
     components:{
      school:school
     }
 })
 
 //全局注册
vue.component('school',school)
    
  • 3.使用组件
 
  • 关于组件名的注意点:
    一个单词组成的:school,School.多个单词组成的my-school,MyScool(需要脚手架支持)
关于VueComponent
  • 1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的
  • 2.我们只需要写,Vue解析时会帮助我们创school的实例对象,即帮助我们执行:new VueComponent(optios)
  • 3.特别注意:每次调用Vue.extend({}),返回的都是一个全新的VueComponent
  • 4.关于this的指向
    (1).组件配置中:

    data函数.methods函数,watch中的函数,computed中的函数,他们的this均是(VueComponent实例对象)

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

    data函数.methods函数,watch中的函数,computed中的函数,他们的this均是(Vue实例对象)
  • 5.Vuecomponent的实例对象,以后简称VC(也可成为组件实例对象).vue的实例对象简称VM

Vue中重要的内置关系

  • 1.VueComponent.prototype.proto === Vue.prototype
  • 2.为什么有这个内置关系:让组件的实例对象(vc)可以访问到Vue原型上的属性和方法
//参考原型
//实例的隐式原型属性永远指向自己缔造者的原型对象
 //定义一个构造函数
    function Demo(){
      this.a = 1
      this.b = 2
    }
    //创建一个demo的实例对象
    const d = new Demo()
    console.log(Demo.prototype) //显式原型属性(只有函数才有的)
    console.log(d.__proto__) //隐式原型属性(对象中有的)

    //指向同一个原型对象
    console.log(Demo.prototype === d.__proto__) //输出true

    //程序员通过显式原型属性操作原型对象,追加一个x属性,值为99
    Demo.prototype.x = 99
    
    // 下面两种写法一样
    console.log(d.__proto__.x)
    console.log(d.x)

单文件组件(xxx.vue)

//快捷键

  

学校名字:{{name}}

学校地址:{{address}}

ref属性

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

    打标识:

    ...

    或者

    获取:this.$refs.xxx




props属性

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

  • 1.数据传递

  • 2.接收数据
    第一种方式(只接受):
props:['name']

第二种方式(限制类型):

props:{
    name:String
}

第三种方式(限制类型,限制必要性,指定默认值):

props:{
    name:{
        type:String, //类型
        require:true, //必要性
        default:'老王' //默认值
    }
}

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

mixin 混入

// mixin.js把公共的抽离出来
export const hunhe = {
    data:{
        x:10,
        y:100
    },
    //methods中的方法如果和被混入对象中的方法一样时,以被混入对象的为准
    methods:{
        click(){
            console.log('点击了')
        }
    },
    //和被混入对象中的钩子函数都调用
    mounted(){
        console.log('这是钩子函数')
    }
}
//-------------------------
//组件vc
// 1.导入  2.使用
import { hunhe } from '../mixin.js'
{
    data:{
        name:小明
    },
    //以数组形式加入混合
    mixins:[ hunhe ]
    methods:{
        
    },
    mounted(){
        
    }
}

插件

功能:用于增强Vue

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

定义插件:

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

使用插件:

导入 import plugin from '../plugins.js'
//用Vue.use(插件名)
Vue.use(plugin)

scoped样式

作用:让样式在局部生效,防止冲突.

写法: