Vue3_vite

目录

使用Vue-cli创建

使用vite创建

Composition API 组合API

setup

执行时机

setup的参数

ref函数

reactive函数

Vue3.0中的响应式原理

Vue2的响应式

实现原理 

Vue3的响应式

 实现原理

通过Proxy(代理):拦截对象中任意属性的变化,包括属性值的读写,属性的添加,属性的删除。

通过Reflect(反射):对被代理对象的属性进行操作。

计算属性与监视

computed函数


使用Vue-cli创建

Vue3_vite_第1张图片

使用vite创建

Vue3_vite_第2张图片

Composition API 组合API

setup

1.Vue3中的一个新的配置项,值为一个函数

2.可以将组件中所用到的数据,方法等配置在setup中.

3.setup函数的两种返回值

        3.1若返回一个对象,则对象中的属性,方法,在模板中均可以直接使用.

        3.2若返回一个渲染函数,则可以自定义渲染内容.

注意:Vue2.0配置(data,methos,computed,...)中可以访问到setup中的属性,方法.但在setup中不能访问(data,methos,computed,...).如果有重名,setup优先

执行时机

在beforeCreate生命周期前执行一次,this是undefined

setup的参数

  • props:值为对象,包含父组件传递过来,且组件内部生命接收了的属性。
    • export default {
      
          props:['name','id'],
          emits:['事件名称'],
          setup(props,context){
              // props:{name:'',id:''}
              console.log(props)
          }
      }
  • context:上下文对象
    • attrs:值为对象,包含父组件传递过来但没有在props配置中声明的属性,相当于Vue2的this.$attrs.
    • slots:收到的插槽内容,相当于Vue2的this.$slots.Vue3中的具名插槽要用v-slot:name
    • emit:分发自定义事件的函数,相当于Vue2的this.$emit.(需要再emits配置中声明)

ref函数

定义一个响应式数据

const xxx = ref(initValue)

创建一个包含响应式数据的引用对象(RefImpl)

JS中操作数据:xxx.value

模板中读取数据不需要.value

备注:

  1. 接收的数据可以是:基本数据类型,也可以是对象类型
  2. 基本数据类型:响应式依然是用Object.defineProperty()的get与set完成的.

reactive函数

  1. 定义一个对象类型的响应式数据
  2. const 对象 = reactive(对象),接收一个对象或数组,返回一个代理对象(Proxy对象)
  3. reactive定义的响应式数据是"深层次的"
  4. 基于ES6的Proxy实现,通过代理对象操作源对象内部数据都是响应式的.

reactive对比ref

从定义数据角度对比:

  • ref定义基本数据类型
  • reactive定义引用数据类型
  • ref也可以定义引用数据类型,但是内部还是通过reactive转为代理对象

从原理角度对比:

  • ref通过Object.defineProperty()的get和set实现数据响应(数据劫持)
  • reactive通过Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据

从使用角度对比:

  • ref定义的数据:操作数据时需要.value,在模板中不需要
  • reactive定义的数据:操作数据与读取数据均不需要.value

Vue3.0中的响应式原理

Vue2的响应式

  • 实现原理 

         对象类型:通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持).

        数组类型:通过重写更新数组的一系列方法来实现拦截.(对数组的变更方法进行了包裹).

  • 存在问题

        新增属性,删除属性,界面不会更新.(可以使用this.$set()和this.$delete())

        直接通过下标修改数组元素,界面不会更新.(通过splice修改数组元素) 

Vue3的响应式

  •  实现原理

  • 通过Proxy(代理):拦截对象中任意属性的变化,包括属性值的读写,属性的添加,属性的删除。

  • 通过Reflect(反射):对被代理对象的属性进行操作。

new Proxy(data,{
    // 拦截读取属性值
    get(target,propertyName){
        // target 源对象
        // propertyName 属性名
        return Reflect.get(target[propertyName])
    },
    set(target,propertyName,value){
        // value 修改的值
        return Reflect.set(target,propertyName,value)
    },
    deleteProperty(target,propertyName){
        return Reflect.deleteProperty(target[propertyName])
    }
})

计算属性与监视

computed函数

Vue3_vite_第3张图片

watch函数 

 Vue3_vite_第4张图片

watchEffect函数

Vue3_vite_第5张图片

toRef和toRefs

  • 作用:创建一个ref对象,其value值指向另一个对象中的某个属性

  • 语法:const value = toRef(person,'属性名')

  • 应用:将响应式对象中的某个属性单独提供给外部使用时

  • 扩展: toRefs与toRef功能一致,但是可以批量创建多个ref对象。(toRefs(person)返回一个对象,对象中的所有属性都是一个RefImpl对象,其value值都指向person对象中对应的属性值)

其它Compositon Api 

shallowReactive与shallowRef

  • shallowReactive:只处理对象最外层属性的响应式(浅响应式)。在一个对象数据,结构比较深,但变化时只是外层属性变化时使用。
  • shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。在一个对象数据,后续功能不会修改对象的属性,而是生成新的对象来替换时使用。
    • 传入基本数据类型,跟ref功能一致。
    • 传入对象,返回的RefImpl对象的value值是一个普通的Object对象,没有响应式。

readonly与shallowReadonly 

  • readonly:让一个响应式数据变为只读的(深只读)。
  • shallowReadonly:让一个响应式数据变为只读的(浅只读)

不希望数据被修改时使用 

toRaw与markRaw

  • toRaw:将一个由reactive生成的响应式对象转换为普通对象。
    • 用于读取响应式对象对应的普通对象,对这个普通对象的所有操作不会引起页面更新。
  • markRaw:标记一个对象,使其永远不会再成为响应式对象。
    • 有些值不应该被设置为响应式的,例如复杂的第三方类库等。
    • 当渲染具有不可变数据源的列表时,跳过响应式转换可以提高性能。

customRef

  • 创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显式控制.
setup(){
    //自定义一个myRef
    function myRef(value,delay){
        return customRef((track,trigger)=>{
            let timer
            return {
                get(){
                    track() // 通知Vue追踪value的变化,
                    return value
                },
                set(newValue){
                    clearTimeout(timer)
                    timer = setTimeout(()=>{
                        value = newValue
                        trigger() // 通知Vue重新解析模板
                    },delay)
                    
                }
            }
        })
    }
    return {
        value:myRef('初始值',500)
    }
}

provide与inject 

  • 实现祖孙组件间的通信
// 祖组件中使用provide提供数据
setup(){
    let car = reactive({name:'name',price:'price'})
    provide('car',car)
}
// 孙组件中使用inject接收数据
setup(){
    const car = inject('car')
    return {car}
}

Teleport组件

Vue3_vite_第6张图片

Suspense组件

Vue3_vite_第7张图片

Vue3的其他改变 

Vue3_vite_第8张图片

Vue3_vite_第9张图片 

Vue3_vite_第10张图片 

你可能感兴趣的:(前端,javascript,vue.js)