Vue(day3)

第三天

异步 DOM 更新

  1. Vue 中采用了 异步DOM更新 的机制
  2. 如何更新页面?
  • 数据发生改变后, vue 没有立即将数据的改变更新到视图中,

  • 而是等到数据不再变化的时候 一次性的 将 数据的改变更新到视图中

     //1. 验证了
     for (let i = 0; i < 1000; i++) {
         this.count++
     }
    
  1. 为什么是异步 DOM 更新?
  • 性能的考虑
  • 因为对于前端来说, 修改数据进行 DOM 操作是常有的事情,如果频繁操作 DOM,会严重影响页面的加载性能
  • DOM 操作这是前端的性能的瓶颈
  • 比如 : for (let i = 1; i < 10000; i++>) 如果同步 就要重新渲染 1000 次
  1. 验证 异步 DOM 更新 :
 //2. 直接获取data 中的值 ,会立马获取成功
console.log(this.count)
this.count++
console.log(this.count)

// 但是 通过dom来获取count的值,因为DOM更新这个count值是异步的,是需要一点时间的
console.log(document.querySelector('h1').innerText) // 0
this.count = 100
console.log(document.querySelector('h1').innerText) // 0
  1. 需求 : 在数据更新后,立即获取到更新后的内容???>

    DOM 更新后,会执行 this.$nextTick() 的回调函数,所以能拿到值

// setTimeout(() => {
//      console.log(document.querySelector('h1').innerText)
//   }, 1000)
this.$nextTick(() => {
  console.log(document.querySelector('h1').innerText) // 100
})

三 : 监听 watch

  1. 说明 : Vue 中可以通过 watch 配置项,来监听 vue 实例中数据的变化

  2. 基本使用

    watch: {
        // 监听name属性的数据变化
        // 作用 : 只要name的值发生变化,这个方法就会被调用
        // 第一个参数 : 新值
        // 第二个参数 : 旧值,之前的前
        name(newVal,oldVal){
                console.log('新 :',newVal);
                console.log('旧 :',oldVal);
        }
    }
    
  3. 基本使用案例 :
    需求 : 监听用户名文本框字符个数(3-6),并显示格式验证

<input type="text" v-model="name" />
<span v-show="isShow">用户名的字符 在 6-12之间</span> if
(/^[0-9a-zA-Z]{3,6}$/.test(newVal)) { 验证 }
  1. 监听对象 (数组也属于对象)
// data :
 data: {
   obj: {
   name: 'zs'
   }
},
// 组件
<input type="text" v-model="obj.name" />
// 监听
  1. 开始监听对象的属性
// 从对象的角度来监听的
 因为对象和数组都是引用类型,引用类型变量存的是地址,地址没有变,所以不会触发watch
obj:{
    // 深度监听 属性的变化
    deep:true,
    // 立即处理 进入页面就触发
    immediate: true,  
    // 数据发生变化就会调用这个函数  
    handler( newVal ) {
      console.log( newVal.name );
     }
  },
 // 从属性的角度来监听
 'obj.name' ( newVal ) {
      console.log('监听对象的属性',newVal);
 }
  1. 计算属性和watch的区别
computed 和 watch的区别
computed :  计算属性
    - 1.根据已知值 ,得到一个新值 
        - 2. 新值随着已知值(相关的数据)变化而变化 
        1. 计算属性 ==> (得到的是)新值
        2. 计算属性(num)  ==> 是别人影响了我

watch : 监听器
1. 监听 ==> (监听)已知值
2. 监听数据 (num2) => 是我影响到了别人

四 : TodoMVC 数据持久化

需求 : 将todoMVC中的数据,保存到 本地存储中 (本地持久化)

  1. 何时存储数据?

    因为功能中的 CRUD 都会修改 list 数据,所以,只要 list 数据发生改变,就要保存到本地存储中;
    方法一 : 在 CRUD 中 分别调用保存数据的方法,(不推荐 太繁琐)
    方法二 : 想办法监听 list 数据的改变,只要 list 数据变了, 就调用保存数据的方法

可以使用 vue 的 watch 监听 list 的数据改变

  1. 存储值

    监听数组和监听对象一样 需要深度监听
    保存值,记得把对象转化为字符串(存的快 省空间)

   // 监听
   watch: {
      // 监听list
      todoList: {
         deep: true,
         handler(newVal) {
            // console.log('发生变化了', newVal)
            // 保存起来
            localStorage.setItem('todoList', JSON.stringify(newVal))
         }
      }
   },
  1. 取值 , 在 data 中可以初始值

    记得给一个默认值 空数组 []

	const todoList =  JSON.parse(localStorage.getItem('todoList')) || [],

过滤器

  1. 概念 :
  • vue 中的过滤器(filter) : 数据格式化 ,
  • 也就是说,让数据按照我们规定的一种格式输出
  • 比如 : 对于日期来说,将日期格式化转化为 年-月-日 小时:分:秒 格式的过程
 // 直接显示
 <h1>{{ date  }}</h1>
 显示 :   2019-01-11T10:11:19.566Z
 不是我们想要的
 我们想要的 : 2019-01-11 18-11-53
  1. 全局过滤器 和 局部过滤器
  • 说明 : 通过全局方式创建的过滤器,在任何一个 Vue 实例中都可以使用 (一般情况下,为了项目方便管理,都是一个 vue 实例)
  • 注意点: 使用全局过滤器的时候,应该先创建全局过滤器,再创建 Vue 实例
  • 局部创建的过滤器 只能在当前 vue 实例中使用
  1. 怎么注册 全局过滤器
// 第一个参数 : 过滤器的名字
// 第二个参数 : 是一个回调函数,只要使用过滤器的时候,这个回调函数就会执行
///           通过回调函数的返回值得到格式化后的数据
Vue.filter('date', res => {
  return '嘻嘻'
})
  1. 使用过滤器 示例 :
// 组件
 <h1>时间戳-格式 {{ date2 | date }}</h1>

// js
  Vue.filter('date', res => {
         return `${res.getFullYear()}-${res.getMonth()}-${res.getDate()} ${res.getHours()}:${res.getMinutes()}:${res.getSeconds()}`
      })
  1. moment 插件
  • moment 地址

  • 使用

    1. 安装 : `npm i moment`
    2. 引入 :
    3. 使用
    
  • 日期 => 指定格式 moment(res).format('YYYY-MM-DD HH-mm-ss')

  • 时间戳 => 指定格式 moment(res).format('YYYY-MM-DD HH-mm-ss')

  • // 全局
    Vue.filter('date', res => {
      return moment(res).format('YYYY-MM-DD HH-mm-ss')
    })
    
  1. 参数问题
  • 示例
<h1>时间戳-格式 {{ date2 | date('YYYY-MM-DD HH-mm-ss',888) }}</h1>

// 默认值
Vue.filter('date', (res, format = 'YYYY-MM-DD', arg) => {
  console.log(arg)
  return moment(res).format(format)
})
  1. 局部过滤器

    在 vm 的配置项里写一个 filters
    对应的是一个对象

 filters: {
    date(res, format = 'YYYY-MM-DD', arg) {
      return moment(res).format(format)
    }
  }

五、生命周期函数

  • 所有的 vue 组件,都是 vue 实例, 一个组件对应一个实例,并且接收相同的选项对象(一些根实例特有的选项除外)
  • 实例生命周期也叫做 : 组件生命周期

生命周期介绍

vue 生命周期钩子函数

  • 简单说 : 一个组件(实例) 从开始到最后消灭所经历的各种状态,就是一个组件(实例)的生命周期
  • 生命周期钩子函数的定义 : 从组件被创建,到组件挂在到页面上运行,再到页面关闭组件被销毁,这三个阶段总是伴随着组件各种的事件,这些事件,统称为组件的生命周期函数 (简称 : 钩子函数)
  • 开发人员可以通过 vue 提供的钩子函数,让我们写的代码参与到 vue 的生命周期里面来,让我们的代码在合适的阶段起到相应的作用
注意 :
  1. 注意 : vue 在执行过程中 会自动调用 生命周期钩子函数, 我们只需要提供这些钩子函数即可
  2. 注意 : 钩子函数的名称都是 vue 中规定好的

5.0 学习 vue 组件生命周期 学什么?

  1. Vue 内部执行的流程(难)
  2. 钩子函数如何使用 (两个重要的钩子函数 created mounted)

5.1 钩子函数 - beforeCreate

  • 说明 : 在实例初始化之前,数据观测 和 event/watcher 事件配置之前被调用

  • 组件实例刚被创建,组件属性计算之前, 例如 data 属性 methods 属性

  • 注意 : 此时,无法获取 data 中的数据 和 methoids 中的方法

  • 场景 : 几乎不用


5.2 钩子函数 - created (掌握)

  • 说明 : 组件实例创建完成,属性已绑定, 可以调用 methods 中的方法、可以获取 data 值

  • vue 实例生命周期 参考 1

  • vue 实例生命周期 参考 2

  • 使用场景 : 1-发送 ajax 2-本地存储获取数据

  •  beforeCreate() {
         // 无法获取数据和事件
         console.warn('beforeCreate', this.msg, this.fn)
     },
     created() {
       console.warn('created', this.msg, this.fn)
     },
    

Has 'el' option ?

  1. YES => 就是正常的 el 边界
  2. NO => 可以注释,但是必须要手动添加 vm.$mount(el) 去指定边界
vm.$mount('#app')

Has template option?

  1. No => 将 el 的 outerHtml 作为模板进行编译 ( outerHTML = 自身 + innerHTML )
  2. YES =>
 // 如果提供了 template, 那么 vue 就会将 template 的内容进行编译,编译后,替换页面中 vue 管理的边界
   template : `
      <h1>嘻嘻</h1>
   `,

5.3 钩子函数 - beforeMounted()

  • 说明 : 在挂载开始之前被调用 (挂载:可以理解DOM 渲染)

5.3 钩子函数 - mounted() (掌握)

  • 说明 : 挂载之后, DOM 完成渲染

  • 使用场景 : 1-发送 ajax 2-操作 DOM

  • 记得把template去掉 
    // 渲染DOM之前
     beforeMount() {
         // 渲染之前的  <h1 id="h1" @click="fn">{{ msg }}</h1>
       console.log(document.querySelector('h1'))
     },
     // 渲染DOM之后  <h1 id="h1">测试</h1>
     mounted() {
       console.log(document.querySelector('h1'))
     }
    

5.4 钩子函数 - beforeUpdated()

  • 说明:数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
  • 注意:此处获取的数据是更新后的数据,但是获取页面中的 DOM 元素是更新之前的

    小提示 : 打印 this.$el ,打开小三角是之后的,是因为打印是有监听的功能,展示的是后面更改之后的


5.5 钩子函数 - updated()

  • 说明:组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。

  •  beforeUpdate() {
         // 更新之前的值  :  信息
       console.warn('beforeUpdate',document.querySelector('h1').innerText)
     },
     updated() {
         // 更新之后的值 : 信息1111
       console.warn('updated', document.querySelector('h1').innerText)
     }
    

5.6 钩子函数 - beforeDestroy()

  • 说明:实例销毁之前调用。在这一步,实例仍然完全可用。
  • 使用场景:实例销毁之前,执行清理任务,比如:清除定时器等
  created() {

   this.timerId =   setInterval(() => {
      console.log(1111);

      }, 500);
   },

 // 如果当组件销毁了,还不清除定时器会出现性能问题
 // 在浏览器中可以尝试销毁  vm.$destroy()
 // 最后销毁
beforeDestroy() {
      clearInterval(this.timerId)
 },

5.7 钩子函数 - destroyed()

说明:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。


六 : 使用钩子函数来完善 数据存储

created {
    this.list = JSON.parse(localStorage.getItem('list'))
}
posted @ 2020-04-19 23:24  handsomehe  阅读(200)  评论(0编辑  收藏  举报