vue3.0(持续更新中)

预备知识:
vue3亮点
1.性能比vue2.x快;
2.按需编译,体积变小;
3.组合api 类似与react hooks;
4.更好的ts支持
5.暴露了自定义渲染api
6.更先进的组件;
vue是如何变快的?
1.diff算法优化;
vue 2.x 采用的diff算法是,全量对比;
vue 3 采用diff算法是,只对比待有静态标志符的;
2.静态提升
vue2.x不论元素是否参与更新,每次重新创建,然后再渲染;
vue3中对于不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可;
怎么提升的?
静态提升之前:

 import { toDisplayString as _toDisplayString, createVNode as _createVNode, createTextVNode as _createTextVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"

  export function render(_ctx, _cache, $props, $setup, $data, $options) {
    return (_openBlock(), _createBlock("div", null, [
      _createTextVNode(" Hello World! "),
      _createVNode("p", null, _toDisplayString(_ctx.msd), 1 /* TEXT */),
      _createVNode("p", null, "ffff"),
      _createVNode("p", null, "ffffww")
    ]))
  }
静态提升之后:
 import { toDisplayString as _toDisplayString, createVNode as _createVNode, createTextVNode as _createTextVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"

    const _hoisted_1 = /*#__PURE__*/_createTextVNode(" Hello World! ")
    const _hoisted_2 = /*#__PURE__*/_createVNode("p", null, "ffff", -1 /* HOISTED */)
    const _hoisted_3 = /*#__PURE__*/_createVNode("p", null, "ffffww", -1 /* HOISTED */)

    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock("div", null, [
        _hoisted_1,
        _createVNode("p", null, _toDisplayString(_ctx.msd), 1 /* TEXT */),
        _hoisted_2,
        _hoisted_3
      ]))
    }
这样每次render的时候,就不会被多次创建;只在第一次的时候创建。

3.事件侦听缓存
默认情况下,onclick会被认为是动态绑定的,所以每次都会追踪她的变化;但是因为是同一个函数,所以没有追踪变化,直接从缓存起来复用。

开启事件缓存之前:
 import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"

    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock("div", null, [
        _createVNode("button", { onClick: _ctx.onclick }, "点击", 8 /* PROPS */, ["onClick"])
      ]))
    }
静态标记  8  代表的:动态属性; 
把onclick事件当成动态属性,那么动态属性就会在下一次的渲染时候,发生对比。


开启事件缓存之后:
 import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"

    export function render(_ctx, _cache, $props, $setup, $data, $options) {
      return (_openBlock(), _createBlock("div", null, [
        _createVNode("button", {
          onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onclick && _ctx.onclick(...args)))
        }, "点击")
      ]))
    }

注意: 我们观擦到没有了静态标志,在vue3中 diff算法只有有静态标志,才会进行追踪。 
------------------------------------------------------------------
1. vue3.0 3中创建方式。
 vue-cli
 webpack
 vite
2. 什么是vite?
 vite 是vue作者开发的一款意图取代webpack的工具;
 -- 其实原理就是:利用es6的import 会发送请求去加载文件的特性,拦截这些请求,做一些预编译,省去webpack冗长的打包时间;
 
 -安装vite;
 npm install -g create-vite-app
 -利用vite创建项目
 create-vite-app projectName
 -安装依赖运行项目
 cd projectName
 npm install
 ------------------------------------------------
 setup() {}
执行时机
注意点;
1.执行时机,setup先于beforeCreate;
beforeCreate data和methods 还没有初始化好;
created  data和methods 还没有初始化好;

2. 注意点
在setup 中无法使用data和methods;
vue为了避免错误使用,它直接将setup中的this修改成了undefined;

setup 只能是同步的,不能是异步的。
-------------------------------------------------
reactive。
1.什么是reactive?
  是vue3.0中提供响应式数据的方法;
  vue2.x中实现响应式数据:object.defineProperty
  vue3.0中实现响应式数据:es6中的proxy;
2.reactive注意点。
  参数必须是对象;
  如果给reactive传递了其他对象,界面不会自动更新;
  如果想更新,可以通过重新赋值的方法; 
-------------------------------------------------
ref
ref(18) -》 reactive({value:18})
底层的本质就是reactive,但是在vue使用的时候就是age;
在setup中改变的时候就是,age.value;
-------------------------------------------------
ref 和 reactive的区别?
如果使用reactive创建数据,在temple中不会自动添加value;
如果使用的是ref,会自动添加.value;
isRef isReactive 判断当前数据类型 ref reactive
使用方法:
isRef(age)
isReactive(age)
-------------------------------------------------
递归监听:
  通过ref reactive创建的数据默认就是递归监听;
非递归监听:
  只监听第一层;
  shallowReactive
  shallowRef 通过这两个创建的就是非递归监听;

1.使用vue2.x实现简单的todolist
实现删除:点击对应的数据,就删除掉此条数据

<template>
    <ul>
      <li v-for="(stu, index) in stus" :key="stu.id" @click="remStu(index)">
        {{index}} -- {{stu.name}} -- {{stu.age}}
      </li>
    </ul>
  </div>
</template>
export default {
  name: 'App',
  data(){
    return {
      stus:[
        {id:1, name:"zs", age:10},
        {id:2, name:"ls", age:20},
        {id:3, name:"ww", age:30},
      ]
    }
  },
  methods:{
    remStu(index) {
      this.stus = this.stus.filter((stu,idx) => idx!== index);
    },
  }
}

实现添加todo:

<template>
  <div>
    <form >
      id: <input type="text" v-model="stu.id">
      name: <input type="text" v-model="stu.name">
      age: <input type="text" v-model="stu.age">
      <input type="submit" @click="addStu ">
    </form>
    <ul>
      <li v-for="(stu, index) in stus" :key="stu.id" @click="remStu(index)">
        {{index}} -- {{stu.name}} -- {{stu.age}}
      </li>
    </ul>
  </div>
</template>
export default {
  name: 'App',
  data(){
    return {
      stu: {
        id:'',
        name:"",
        age:''
      },
      stus:[
        {id:1, name:"zs", age:10},
        {id:2, name:"ls", age:20},
        {id:3, name:"ww", age:30},
      ]
    }
  },
  methods:{
    remStu(index) {
      this.stus = this.stus.filter((stu,idx) => idx!== index);
    },
    addStu(e) {
      e.preventDefault();
      const stu = Object.assign({}, this.stu);
      this.stus.push(stu);
      this.stu.id="";
      this.stu.name="";
      this.stu.age="";
    }
  }
}

从中我们可以发现:
vue2.x中的缺点: 新增一个功能,就要在data(){}中新增定义一个数据结构;业务逻辑就要在methods 或computed 或 watch 中添加业务逻辑;维护起来比较麻烦;
vue3.0就很好的解决了这个缺点。
使用vue3实现同样的功能:

<template>
    <form action="">
      id: <input type="text" v-model="state2.stu.id">
      name: <input type="text" v-model="state2.stu.name">
      age: <input type="text" v-model="state2.stu.age">
      <input type="submit" @click="addStu ">
    </form>
  <ul>
    <li v-for="(stu, index) in state.stus" :key="stu.id" @click="remStu(index)">
      {{index}} -- {{stu.name}} -- {{stu.age}}
    </li>
  </ul>
</template>
import { reactive } from 'vue';
// ref 函数只能监听简单数据结构,不能监听复杂的数据结构(数组/对象);
// reactive 可以;

import userRemoveStudent from './js/removeStu';
import userAddStudent from './js/addStu';
export default {
  name: 'App', 
  // setup函数是组合api的入口函数;
  setup() {
    // let state = reactive({
    //   stus:[
    //     {id:1, name:"zs", age:10},
    //     {id:2, name:"ls", age:20},
    //     {id:3, name:"ww", age:30},
    //   ]
    // });

    // function remStu(index) {
    //   state.stus = state.stus.filter((stu, idx) => idx !== index );
    // };
    // let state2 = reactive({
    //   stu:{
    //     id:"",
    //     name:"",
    //     age:""
    //   }
    // });

    // function addStu(e) {
    //   e.preventDefault();
    //   const stu = Object.assign({}, state2.stu);
    //   state.stus.push(stu);
    //   state2.stu.id="";
    //   state2.stu.name="";
    //   state2.stu.age="";
    // }



    let { state, remStu, } = userRemoveStudent();
    let {state2,  addStu, } =  userAddStudent(state);

    return {
      state,
      remStu,
      state2, 
      addStu,
    }
  },
 
}


import { reactive } from 'vue';
function userRemoveStudent() {
  let state = reactive({
    stus:[
      {id:1, name:"zs", age:10},
      {id:2, name:"ls", age:20},
      {id:3, name:"ww", age:30},
    ]
  });

  function remStu(index) {
    state.stus = state.stus.filter((stu, idx) => idx !== index );
  };

  return {
    state,
    remStu,
  }
}

export default userRemoveStudent;
import { reactive } from 'vue';
export default function userAddStudent(state) {
  let state2 = reactive({
    stu:{
      id:"",
      name:"",
      age:""
    }
  });

  function addStu(e) {
    e.preventDefault();
    const stu = Object.assign({}, state2.stu);
    state.stus.push(stu);
    state2.stu.id="";
    state2.stu.name="";
    state2.stu.age="";
  };

  return {
    state2,
    addStu,
  }
}

说明:reactive接受的是一个对象;
ref 接受的是简单的数据类型;

  1. ref实例:
<template>
  <div>
    {{ count }}
  </div>
  <button @click="addCount"></button>
</template>


<script>
// vue3.0 中使用组合api 进行优化;
import { ref, reactive } from 'vue';
// ref 函数只能监听简单数据结构,不能监听复杂的数据结构(数组/对象);
// reactive 可以监听对象;

export default {
  name: 'App', 
  // setup函数是组合api的入口函数;
  setup() {
    // 定义一个变量,初始值为0;
    // 这个变量发生变化后,vue ui 会自动发生变化;
    let count = ref(0);
    // 在组合API中,如果想定义方法,不用在methods中定义,直接定义就好;
    function addCount () {
      console.log(count,'count')
      count.value += 1;
    };
    // 将变量暴露出去;
    return {
      count,
      addCount,
    }
  }

}
</script>

3.customRef 自定义一个ref

<template>
  <div>
   <ul>
     <li v-for="(item, index) in state" :key="item">
       {{index}} -- {{item.name}}--{{item.age}}
     </li>
   </ul>
  </div>
  <button @click="myFun">按钮</button>
</template>

<script>
// customRef:自定义一个ref
import {customRef} from 'vue';

function myRef(value) {
  return customRef((track, trigger) => {
    fetch(value)
    .then(res => {
      console.log('res1', res);
      return res.json();
    })
    .then(data => {
      
      value = data;
      trigger();
    })
    .catch(err => {
      console.log('err', err);
    })
    return {
      get() {
        // 注意不能在get方法中进行忘了请求;
        // 渲染界面 -》调用get -》 发送网络请求
        // 保存数据-》 更新界面-》 调用get; 
        track(); // 告诉vue 需要被追踪;
        return value;
      },
      set(newValue){
        value = newValue;
        trigger();// 告诉vue更新界面;
      }
    }
  })
} 
export default {
  name: 'App',
  setup(){
    let state = myRef('../public/data.json');
    return {
      state
    }
  }
}

</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值