2020-11-02vue新特性(二)

2020-11-03  本文已影响0人  夏天的风2020

//vue3新特性巡礼
//vue2大部分特性都完全的保留到vue3中,你可以像使用vue2一样原封不动的使用vue3,
//这是它遵循的渐进式准则
//v3.vuejs.org

1.性能提升 
  打包大小减少41%
  初次渲染快55%,更新快133%
  内存使用减少 54%

//这得益于重写虚拟DOM的实现和 的优化


2.composition API (新推出的API)
  在vue2中遇到一个问题,复杂组件的代码变得越来越难以维护,
  缺少一种比较干净的,在多个组件之间题提取和复用逻辑的机制,
  现在的重用机制都有一些弊端,
  所以vue3中隆重推出了composition API
  composition---组合

//ref和reactive
//computed和watch 
//新的生命周期函数
//自定义函数--Hooks函数(重要)


3.其他新特性
  Teleport--瞬间组件的位置
  Suspense--异步加载组件的新福音
  全局API的修改和优化
  更多的实验性特性

4.更好的TypeScript的支持

使用vue-cli配置vue3开发环境

  node -v  //node版本10以上
  (怎么安装多个node版本)
官网: https://cli.vuejs.org/zh/
安装或者升级:npm install -g @vue/cli
查看版本:vue --version
保证vue-cli版本在4.5.0以上,这个版本以上的vue-cli才能支持vue3

创建项目(两种方式~)
1.vue creat vue3-basic (回车)
//选项中没有vue 3 Preview,说明vue-cli是旧的版本,
//以下为创建步骤
//按上下箭头可以在选项中进行切换,按空格进行选择,


2.启动图形化界面创建
  vue ui 

项目文件结构分析和推荐插件安装

 eslint插件
//解决eslint不生效的问题
//新建文件夹.vscode
//.vscode下新建文件settings.json

Vetur插件
//打vue  出现vue格式的文件
//在不同模板上提示指令

vue3--ref的妙用

在vue3中不需要写data和methods
可以用setup(){}中写方法
//setup---准备
//在data,computed,methods和生命周期函数之前运行的
//在这个方法中我们没法访问到this,
//在setup中我们需要和data中一样的一个响应式的对象,
//这时候不仅仅像data中那样之前返回一个对象,它就是响应式的,
//我们要使用vue3提供的一个API,它称之为ref
//import { ref } from 'vue'
//ref是一个函数,它接受一个参数,返回的是一个神奇的响应式对象
//setup(){
//   const count = ref(0)    //ref她它是一个函数,我们传入一个初始值,这个初始值是0
// }                        //这个时候count就是一个响应式对象了 
//此时,鼠标放在count上,ts显示count是一个ref类型



//响应式对象在未来可以检测到改变,并作出对应的响应


//这时候这个对象的值在模板中要展示,首先把这个值返回出去,返回一个对象,
setup(){
   const count = ref(0)   
     return {
      count   //我们称这个key也叫count,之后就可以省略掉这个key:value的写法,直接返回count
    } 
 }     
//这时我们就可以展示{{count}}
// 返回这个对象,包括key为count的对象,告诉模板,你可以在tempilate中使用count这个变量了,



要使用这样导出的方式是不是有点繁琐?
要写好多return
其实vue3是有意设计成这样的,为了达到上节所说的目标,
我们需要精确控制哪些属性和方法要被导出使用,可以更好的追踪引用和更新的情况,

//展示完毕以后,可以更新一个值了,添加一个按钮,
//添加一个方法,点击一下,+1

//在vue2中方法都是写在methods中的,现在我们可以在setup中写方法,
//也非常简单,其实它就是一个纯的javascript,毫无特殊

setup(){
   const count = ref(0)
    const increase = ()=>{
      count.value++  //注意:count是一个充满魔法的响应式对象,要更新它不能直接在count上更新
     }               //count上边有一个值:value,它本身是一个object,value才是真正保存它值的地方
      return {
      count,
     increase   //假如你在模板中想使用它,记得导出去
    } 
 } 



刚才我们展示了响应式对象ref和方法(一个普通的函数), 
现在来创建一个计算值computed-value,还是在setup中创建,
我们需要另一个API,computed
computed是一个函数,
它有一个参数,这个参数是一个函数回调,在这个回调中我们可以处理你想返回的值,
import { ref,computed } from 'vue'

setup(){
   const count = ref(0)
    const double = computed(()=>{
      return count.value*2
     })
    const increase = ()=>{
      count.value++  
     }              
     return {
      count,
     increase,   
     double  //假如你在模板中想使用它,记得导出去
    } 
 } 

//鼠标移至dobule上可以看到dobule是computedRef,
//它也是一个类似ref对象的数据类型,它可以直接在模板中进行使用

vue3--reactive

上节课我们介绍了setup方法,还有ref和computed的API,
    把javascript的原始类型转换成响应式的对象,
    我们发现使用ref一般传入的是原始类型,而且几个变量count/double/increase都分散在各处,
    有没有什么办法把这几个变量都包裹在一个对象中呢?
    引入一个新的API---reactive  
    import {ref,computed,reactive} from 'vue'
    它和ref非常相似,它也是一个函数,只不过它里面的参数不是一个原始类型,
    而是一个object,这样我们就可以把一系列的响应式数据放进去,


//改造一下
setup() {
   const count = ref(0)
   const double = computed(() => {
     return count.value * 2
   })
   const increase = () => {
     count.value++
   }
  const data = reactive({  //reactive参数是一个对象{}
    count:0,
    increase:()=>{data.count++}, //reactive生成的响应式对象修改里面的值的时候,比如data.count,我们不需要.value了,
                                 //我们直接把它当作对象的一项操作就好了
    double:computed(()=>{data.count*2})
  })
  return {
  }
},

//这时候我们发现data标红,出现了类型错误,
//这是因为在回调中,只用data.count会造成类型推论的循环,
//由于ts的局限性,vue3暂时没法解决这个问题,
//它会自动将data推断成any类型,
//将double去掉,报错消失,鼠标移至data,显示推断出了正确的类型,

//解决方案就是我们需要显示的给data指定一个类型,
//这里可以先不管这个警告,它不会影响最终结果,
//或者可以新建一个类型,
interface DataProps{
   count:number;
   double:number;
   increase:()=>void
 }

//以下不再报错
setup() {
    const count = ref(0)
   const double = computed(() => {
     return count.value * 2
   })
   const increase = () => {
     count.value++
   }
   const data: DataProps = reactive({  
     count:0,
     increase:()=>{data.count++},                            
     double:computed(()=>{data.count*2})
   })
   return {
     data   //值返回出去
   }
 }

//{{data.count}}
//{{data.double}}
//@click="data.increase"

优化一下(data写的太多)
可以用es6的spread操作,把对象展开,
//   return {
//     ...data   //值返回出去
//   }

//   return {
//     count:data.count,
//     count:data.increase,
//     count:data.double
//   }

//以上写法在页面上做操作也没反应

//原因:
//鼠标移至data.count,可以发现是number类型,就是普通的javascript类型,
//而并不是响应式的数据,
//响应式是一个ref类型的数据,
//只有响应式的类型在模板中表现才是响应式的,
//我们把这些值从响应式的对象中取出来,就代表他们会失去响应式的活力,
//变成普通的javascript类型,现在它就是个number,所以它自然就不会自动更新了,



针对这个问题,vue3推出了API--toRefs()
import {ref,computed,reactive,toRefs} from 'vue'

//顾名思义它就是一个函数,它接受一个reactive对象作为参数,返回一个普通的对象,
//这个对象的每一项都变成了ref类型的对象,
   setup() {
     const count = ref(0)
     const double = computed(() => {
       return count.value * 2
     })
     const increase = () => {
       count.value++
     }
     const data: DataProps = reactive({  
       count:0,
       increase:()=>{data.count++},                            
       double:computed(()=>{data.count*2})
     })
     const refData = toRefs(data)
     //refData.double    //鼠标移至refData.double,显示ref类型
     return {
       ...refData   
     }
   }
// 以上可以正常运行了



//特别注意:模板中应用的是否为响应式数据类型,这样才能根据你的数据改变做出模板更新的工作,

ref和reactive的区别:

    ref和reactive的区别:
    //用写普通标准的javascript来类比,
    //第一种:(类似ref)
    let x = 0
    let y = 0

     function updataNumber(){
       x= 2
       y= 3
      }

    //第2种:(像在用reactive)
    const pos = {
       x:0,
       y:0
     }

     function updataObject(){
       pos.x= 2
       pos.y= 3
     }

    //这样会遇到和reactive一样的问题,
    //x,y必须和对象在一起才能保持引入,
    // const { x } = pos 
    // pos.x = 3 //x还是旧的值
    //这样会丧失它的响应式

     

使用 ref 还是 reactive 可以选择这样的准则:

    第一,就像刚才的原生 javascript 的代码一样,像你平常写普通的 js 代码选择原始类型和对象类型一样来选择是使用 ref 还是 reactive。
    第二,所有场景都使用 reactive,但是要记得使用 toRefs 保证 reactive 对象属性保持响应性。


  这节课我们学习了reactive语法,他是和ref对应的一个生成响应式对象的语法,
  特别注意,如果它的属性单独拿出来可能会丧失响应性,
  我们可以toRefs来解决这个问题。
上一篇 下一篇

猜你喜欢

热点阅读