Vue基础

操作真实DOM所消耗的时间 和 操作数据所消耗的时间

下面用案例解释

  一:
 // 操作真实DOM
  let count = 0
  console.time('b')
  var box = document.querySelector( '.box' )
  for( var i = 0 ; i <= 10000; i++ ){
    count = i  
    box.innerHTML = count  // 这里我就在操作真实dom       10000次
  }
 console.timeEnd('b')



二:
//操作真实DOM   操作数据
  let n = 0 ;
  console.time('c')
  for ( var i = 0 ; i<= 10000; i++ ){
    n = i
  }
  box.innerHTML = n // 这里操作了一次
  console.timeEnd('c')

第二种方法耗时比较小

diff算法

  1. 这个算法来源于后端,它的作用就是比较两个文件,然后将两个文件中的不同之处挑选出来
  2. 将挑选出来的内容,形成补丁对象

render 方法 【 渲染函数 】

  1. 将vdom渲染为真实dom (vdom:虚拟dom)

  2. 在javascript中书写dom结构,

  3. javascript + xml 结合生成了一种新的语法糖: JSX

    render () {
               return (
                  <div>
                    <ul>
                      <li> 数据 </li>  
                    </ul>  
                  </div>
               )
             }
    
  4. 使用jsx结构模拟vdom,但是vdom是对象模型,必须将jsx 转换 vdom对象模型

  5. 然后在渲染页面【 真实dom生成 】

下面用例子展示

// 1. 获取数据

  var model = {
    msg: 'hello '
  }

  // 2. 创建 VDOM
  var vdom = {
    tag: 'DIV',
    attr: {
      className: 'box'
    },
    children: [
      {
        tag: 'UL',
        attr: {},
        children: [
          {
            tag: 'li',
            attr: {},
            content: model.msg
          }
        ]
      }
    ]
  }

  //3. 渲染dom 【 render 】

    var box = document.createElement('DIV')
    var ul = document.createElement('UL')
    var li = document.createElement('LI')

    box.className = vdom.attr.className
    li.innerHTML = vdom.children[0].children[0].content

    ul.appendChild(li)
    box.appendChild(ul)
    document.body.appendChild( box )


 // 4. 数据改变
    model.msg = "hello 1905"  

 // 5. 重新生产vdom  [ render ]
    vdom = {
      tag: 'DIV',
      attr: {
        className: 'box'
      },
      children: [
        {
          tag: 'UL',
          attr: {},
          children: [
            {
              tag: 'li',
              attr: {},
              content: model.msg
            }
          ]
        }
      ]
    }
	//6. 通过diff算法进行两个vdom的比较,将不同之处挑选出来,形成一个patch对象【 补丁对象 】,再去重新渲染页面

key

key: 作用: 给vdom打标记,实现同层级比较

经验:列表渲染都要加key,key一定是要唯一的标识,最好是id

案例:

 
<div id="app">
    <ul>
      <li
        v-for = "(item,index) in todos"
        :key = "item.id"  //此时要用key做唯一标识   如果没有   则删除第一项时   此时列表只剩下一项,   剩下的这一项将变成第一项  也将有未删除前第一项的属性(背景颜色)
      >
        <p> {{ item.task }} </p>
        <div class="btn_box">
          <button @click = "modify"> 修改 </button>
          <button @click = "remove( index  )"> 删除 </button>
        </div>
      </li>
    </ul>
  </div>
new Vue({
    el: '#app',
    data: {
      msg: 'hello ',
      todos: [
        {
          id: 1,
          task: '任务一'
        },
        {
          id: 2,
          task: '任务二'
        }
      ]
    },
    methods: {
      remove ( index ) {
        this.todos.splice( index,1 )
      },
      modify ( e ) {
        // 点击修改让整个li的背景颜色为红色
        // 以下代码我是用来说明key的作用的,在真实项目中不允许使用
        const li = e.target.parentNode.parentNode 
        li.style.background = 'red'
      }
    }
  })

模拟数据实现方式?

  1. 为什么要写模拟假数据?

    • 前后端分离, 前后端同步开发,接口是没有的
  2. mock.js生成 http://mockjs.com/

    • 使用经验:

      • 安装
        npm install mockjs
        
      • 使用的时候找字段结构相近的案例,然后复制语法,然后对应修改

    // 使用 Mock
    var Mock = require('mockjs')
    var fs=require('fs')
    var data = Mock.mock({
        // 属性 list 的值是一个数组,其中含有 4 个元素
        'list|4': [{
            // 属性 id 是一个自增数,起始值为 1,每次增 1
            'id|+1': 1,
            //name   属性    没次输出一个
            'name|1':["qweq","gfd","nbvc","ytre","hgfd"]
        }]
    })
    // 输出结果
    console.log(JSON.stringify(data, null, 4))
    
  3. 拷贝线上相近的json

    • 浏览器开发者工具/ netWork / XHR / copy response
  4. easy mock https://easy-mock.com/login

    • 生成数据接口
      • 登录easy mock官网 点击右下角加号 创建接口

数据请求: axios fetch

数据请求的方式

  • 原生

    • ajax fetch

    • fetch:

       <!-- fetch  是原生js提供的   可以直接全局变量一样使用 -->
              <div id="app">
                      <div class="container">
                        <div class="row">
                          
                          <h3> 静态请求【 模拟数据  】 </h3>
                            <button type="button" class="btn btn-primary" @click = "getStatic" > getJson </button>
                          <h3> 动态请求 【 真实接口】 </h3>
                            <button type="button" class="btn btn-primary" @click = "get"> get </button>
                            <button type="button" class="btn btn-primary" @click = "post"> post </button>
                        </div>
                      </div>
                    </div>
                    <script src="./lib/vue.js"></script>
                    <script>
                        new Vue({
                            el:"#app",
                            methods:{
                              // 请求静态数据
                              getStatic(){
                              fetch('./mock/data/data.json')
                              .then(res=>res.json())//做数据格式化的
                              .then(data=>console.log(data))//获取数据格式化之后的结果
                              .catch(error=>console.log(error))//错误捕获
                              },
                              get(){
                                  fetch('http://localhost/get.php?a=1&b=2')
                                  .then(res=>res.text())
                                  .then(data=>console.log(data))
                                  .catch(error=>console.log(error))
                              },
                              post(){
                                  fetch('http://localhost/get.php?a=1&b=2',{
                                      method:'POST',//或PUT
                                      body:new URLSearchParams([["a",1],["b",2]]).toString(),
                                      headers: new Headers({
                                              'Content-Type': 'application/x-www-form-urlencoded'
                                          })
                                  })
                                  .then(res=>res.text())
                                  .then(data=>console.log(data))
                                  .catch(error=>console.log(error))
                              }
                            }
                        })
                    </script>
      
  • 封装

    • jq

    • vue 1.x vue-resource 弃用

    • axios现如今最好的封装的请求库

      • axios:
      <script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
          <!-- 引入axios   cdn之后会得到一个axios的全局变量 -->
      </head>
      <body>
          <div id="app">
              <div class="container">
                <div class="row">
                  
                  <h3> 静态请求【 模拟数据  】 </h3>
                    <button type="button" class="btn btn-primary" @click = "getStatic" > getJson </button>
                  <h3> 动态请求 【 真实接口】 </h3>
                    <button type="button" class="btn btn-primary" @click = "get"> get </button>
                    <button type="button" class="btn btn-primary" @click = "post"> post </button>
                </div>
              </div>
            </div>
            <script src="./lib/vue.js"></script>
            <script>
      
                // 以下代码是统一设置post请求的请求头
                      axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
      
      
                new Vue({
                    el:"#app",
                    methods:{
                      //   获取静态数据
                      getStatic(){
                          // console.log(axios({}))//Promise {<pending>}  证明axios它底层封装的Promise
                              axios({
                                  url:'./mock/data/data.json',
                                  method:'GET'
                              }).then(res=>console.log(res))
                                .catch(error=>console.log(error))
                      },
                      // 动态请求数据
                      get(){
                          // 写法一
                          // axios({
                          //     url:'http://localhost/get.php',//www下面的get.php文件
                          //     method:'GET',
                          //     params:{
                          //         a:1,
                          //         b:2
                          //     }
                          // }).then(res=>console.log(res))
                          //   .catch(error=>console.log(error))
      
                          // 写法二
                          //axios
                          // .get('http://localhost/get.php',{
                          //     params:{
                          //         a:1,
                          //         b:2
                          //     }
                          // }).then(res=>console.log(res))
                          //   .catch(error=>console.log(error))
                      },
                      post(){
                          const params=new URLSearchParams()
                          params.append('a',1)
                          params.append('b',2)
                          axios({
                              method:'post',
                              url:'http://localhost/post.php',
                              data:params
                          }).then(res=>console.log(res))
                            .catch(error=>console.log(error))
                      }
                    }
                })
            
            </script>
      
      • axios和vue-resource相似度 98%

深入响应式原理 【 数据驱动原理/ 双向数据绑定原理 】 【 面试题 - 王者 】

  1. 深入响应式原理

    • 数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新
      <div class="box">
          
            </div>
            <button> 点击 </button>
            
            <script>
                /* 
                    深入响应式原理:数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新
                    使用原生js来实现深入响应式原理
                */
            let box=document.querySelector('.box')
            let but=document.querySelector('button')
            var data={
                name:''
            }
    
            but.onclick=function(){
                data.name="zhansghan"   //点击修改数据
            }
    
            // Object.defineProperty(obj,对象的某一个属性)
            // Object.defineProperty( data, 'name',options)
            Object.defineProperty(data,'name',{
               get(){//给对象提供getter
                return "历史"//给对象赋初始值   赋值一次
               },
               set(val){//给对象提供setter
                        //val值得就是对象属性的新值
                console.log(val)
                box.innerHTML=val
               }
            })
            box.innerHTML=data.name
            </script>
    
  2. 数据驱动

    • 数据改变,视图改变
  3. 双向数据绑定原理

    • 使用v-model这个指令来实现,数据改变,视图改变,视图改变,数据也随之改变
  • 共用:
    vue是通过数据劫持和订阅发布来进行深入响应的,数据劫持指的是,vue通过es5的Object.defineProperty属性对data选项中的数据进行getter和setter设置,订阅发布指的是vue通过之定义自定义事件将data的变化反映到视图上去,vue通过observer观察者对象反应数据的变化,然后通知vue生成新的Virtual DOM ,进而渲染视图

  • 关键词:
    数据劫持
    订阅发布
    es5 Object.defineProperty getter setter
    observer对象
    将data选项中的数据全部做一遍getter和setter设置,然后他们的变化就会被observer监听到

Vue3.0会将 es5的Object.defineProperty 改用 es6/7 的observer 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值