vue3.0新特性composition-api介绍

新安装方式

  • npm install -g @vue/cli
  • vue create my-project  
  • npm install @vue/composition-api --save        
  • main.js文件中 import composition-api from ‘composition-api’   
  • Vue.use(composition-api)

新Api(composition-api)

setup(props , context)

  • setup() 函数为API提供了统一的入口
  • 执行时机:beforeCreate() 之后,Created之前
  • setup() 中访问不到this,只能通过setup的第二个参数context拿到对应类似this的操作属性。context替代了this

props

  • setup获取外界传入的prop,先在export default中声明props对象,接着声明传入参数的数据类型,最后调用时,通过setup的第一个参数props调用
export default{

    props:{

       transData: string

    }

    setup(props , context){

       console.log(prop.transData)

    }

}
  • props是响应式的,用ES6解构会消除他的响应式,可以用toRef(props)来解构

reactive({…})

  • 接收一个普通的对象,返回一个响应式的数据对象
  • 使用前需要先import引入
  • reactive() 只能在 setup() 中使用
  • 如果外界(template中)调用,setup() 会return一个响应式数据,setup() 内部调用,使用的是响应式的数据变量调用某一属性,外界调用,使用的是普通的数据变量
export default {
    setup(props,context) {
        let tempData = reactive({name: "jack",age:18})    //创建数据对象,里边可包含多个数据
        console.log(tempData.name)    //setup中,使用返回的响应式对象调用
        console.log(tempData.age)
        return {
            ...toRefs(tempData)    //return响应式对象
        };
    }
}

<template>
    <div>我的名字{{ name }}<div/>    //模板中使用的还是普通的数据变量
<template/>

ref()

  • 根据给定的值(基本数据类型)创建一个响应式数据对象,返回一个只包含.value属性的对象。
  • ref只能用于setup() 中
  • 如果外界(template中)调用,setup() 会return一个响应式数据变量,setup() 内部调用,使用的是响应式的数据变量的value值,外界调用,使用的是return的响应式数据变量,不能使用.value,也不能使用普通数据变量。
export default {
    setup(props,context) {
        let tempData = ref(18)    //创建数据对象,里边只能是一个基本数据,如string, number
        console.log(tempData.value)    //setup中,使用返回的响应式数据的value属性拿到值
        return {
            tempData    //return响应式对象
        };
    }
}

<template>
    <div>我的年龄{{ tempData }}<div/>    //模板中使用的是响应式的数据变量
<template/>
  • ref在传值为null时可以作为获取虚拟DOM使用,如果 VNode 的 ref 键对应于渲染上下文中的 ref,则 VNode 的相应元素或组件实例将被分配给该 ref 的值。这是在虚拟 DOM 挂载/打补丁过程中执行的,因此模板引用只会在初始渲染之后获得赋值。
<script>
  import { ref, onMounted } from 'vue'
  export default {
    setup() {
      const root = ref(null)
      onMounted(() => {
        // DOM元素将在初始渲染后分配给ref
        console.log(root.value)    // <div>这是根元素</div>
      })
      return {
        root
      }
    }
  }
</script>

<template>
    <div ref="root">This is a root element</div>
</template>

reactive() & ref()

  • 二者都用于将普通数据转为响应式数据
  • 当把 ref() 创建出来的响应式数据对象,挂载到 reactive() 上时,会自动把响应式数据对象展开为原始的值,不需通过 .value 就可以直接被访问
  • ref加入到reactive中,调用时使用state.ref形式,新传入的ref会覆盖掉原来的ref值,但是ref和state是相互独立的state.ref值得改变不会影响到ref值,因此新传入的ref覆盖旧的ref,覆盖的只是指向数据的指针
  • ref用于简单的数据类型,reactive用于复杂的数据类型
  • ref在return时不需要解构,state在return时需要解构
  • ref在外界调用直接调用响应数据变量,reactive调用的时普通数据变量

isRef()

  • 判断某个值是否是通过ref函数创建出来的
const unwrapped = isRef(foo) ? foo.value : foo

toRefs()

  • 将reactive创建出来的响应式数据对象转为普通对象,只不过这个普通对象的每一个属性节点都是ref类型的响应式数据,此处用到了扩展运算符,会将state转为普通对象,因此需要用torefs将其转为响应式数据。
export default {
    setup() {
        const state = reactive({ count: 0 })
        const increment = () => {    // 定义页面上可用的事件处理函数
            state.count++
        }
        // 这个返回对象中可以包含响应式的数据,也可以包含事件处理函数
        return {
          ...toRefs(state),
          increment
        }
    }
}

<template>
  <div>
    <p>当前的count值为:{{count}}</p>
    <button @click="increment">+1</button>
  </div>
</template>

computed()

  • 创建计算属性,返回值是一个ref实例,因此也有.value属性
  • 使用前需导入
  • 创建只读的计算属性:
export default {
    setup(props, context) {
        const tempData = ref(0);
        const computeData = computed(() => { 
            tempData.value += 1;    //返回的computeData也是ref类型
        })
        console.log(tempData.value)    //0
        console.log(computeData.value)    //1
    }
}
  • 创建可读可写的计算属性:
export default {
    setup(props, context) {
        const tempData = ref(0);
        const computeData = computed({
            get: () => {
                tempData.value += 1;
            },
            set: (val) => {
                tempData.value = val - 1;
            }
        })
        console.log(tempData.value)    //0
        console.log(computeData.value)    //1
        computeData.value = 9;
        console.log(tempData.value)    //8
    }
}

watch(arg1, arg2, arg3)

  • 监视数据变化,创建时会自动调用一次,可以通过watch的第三个参数{ lazy: true }关闭。第三个参数是用来配置监听参数,例如 immediately 等
  • 需要先导入
  • 单一数据监听:
export default {
    setup(prop, context) {
        //ref类型
        const tempData = ref(0)
        watch(
            tempData,
            (newVal, oldVal) => {
                console.log(newVal);
            },
            {
                lazy: true
            }
        )

        //reactive类型
        const tempData1 =reactive({count: 0})
        watch(
            ()=>tempData1.count,
            (newVal, oldVal) => {
                console.log(newVal);
            },
            {
                lazy: true
            }
        )
    }
}
  • 多数据监听:
export default {
    setup() {
        //ref类型
        const count = ref(0)
        const name = ref('jack')
        watch(
            [count, name],
            ([newcount, newname], [oldcount, oldname]) => {
                console.log(newcount, oldcount);
            },
            {
                lazy: true
            }
        )
        setTimeout(() => {
            count.value++
            name.value = 'lc'
        }, 1000)

        //reactive类型
        const state = reactive({
            count: 0,
            name : 'jack'
        })
        watch(
            [()=>state.count, ()=>state.name],    //监听的数据组
            ([newcount, newname], [oldcount, oldname]) => {    //回调函数
                console.log(newVal);
            },
            {
                lazy: true
            }
        )
        setTimeout(() => {
            state.count++
            state.name = 'lc'
        }, 1000)
    }
}
  • 清除监听
// 调用watch的返回值,执行一下就清除了。
const stop = watch(...)
stop()     //清除监听
  • 清除异步无效任务

        这个清除函数会在如下情况下被调用:

                watch 被重复执行了

                watch 被强制 stop 了

export default {
    setup() {
        const count = ref(0)
        //声明监听
        const stop = watch(
            count,
            (newVal, oldVal, onClear) => {
                const timeId = asyncPrint(newVal)    //调用异步方法
                onClear(() => {    //重复监听会删除之前的操作
                   clearTimeout(timeId)
                })
            },
            {lazy: true}
        )
        //异步方法
        const asyncPrint = (val) => {
            return setTimeout(() => {
                console.log(val)
            },3000)
        }
    }
}
  • watchEffect

        watchEffect在一开始的时候就会收集依赖,相比watch可控制初始化时是否立即监听,watchEffect在一开始的时候必须执行一遍,用于收集依赖,也因此watchEffect不会像watch那样会有第一个参数去指定依赖,但是在watchEffect中必须有需要监听的响应式数据才能触发监听,如果在外边改变ref1,而在watchEffect中console.log(ref2)是没效果的,但是watch是有效果的。      

import {  watchEffect  } from 'vue'

const state1 = reactive({name: 'jack'})
setTimeout(() => {
    state1.name = 'lc'
},8000)
watchEffect(() => {
    console.log(state1.name)      //无法监听到
})
  • vue3.0中,如果watch的是一个数组对象,那么push方法不会触发监听,必须重新给数组赋值才会触发。

生命周期

  • 生命周期写在setup( )中
  • 需提前import引入
  • 新旧生命周期对比:

        beforeCreate

                                    --- setup()        // beforeCreate和created被取消,换成了setup()

        created                 

        beforeMount        --- onBeforeMount(()=>{…})

        mounted              --- onMounted(()=>{…})

        beforeUpdate      --- onBeforeUpdate(()=>{…})

        updated               --- onUpdated(()=>{…})

        beforeDestroy     --- onBeforeUnmount(()=>{…})

        destroyed            --- onUnmounted(()=>{…})

        errorCaptured      --- onErrorCaptured(()=>{…})

provide

  • 可以实现嵌套组件之间的数据传递, 父级组件中使用 provide() 函数向子组件传递数据
  • 不限层级,只要是嵌套的子级组件
  • 在setup() 中使用
  • 需要先引入
  • 共享普通数据
export default {
    setup() {
        provide('globalColor','red')
    }
}
  • 共享ref响应式数据
export default {
    setup() {
        const color = ref('red')
        provide('globalColor', color)
    }
}

inject

  • 可以实现嵌套组件之间的数据传递, 子级组件中使用 inject() 函数接收父组件的数据
  • 不限层级,只要是其父级组件,
  • 在setup() 中使用
  • 需要先引入
  • 接收父级的传参
export default {
    setup() {
        inject('globalColor')
    }
}

template—refs

  • 通过ref() 实现对页面DOM元素和组件的引用和操作
  • 父组件可以操作子组件,能拿到子组件的数据
  • 实例:
export default {
    setup() {
        const h3ref = ref(null)    //定义ref,值为null
        const comChild = ref(null)
        onMounted(()=>{
            // h3ref.value相当于一个原生DOM
            h3ref.value.style.color = 'red'
        })

        //能拿到子组件的DOM
        const showNumber = () => {
            console.log(comChild.value.count)
        }
        return {
            h3ref,
            comChild,
            showNumber
        }
    }
}

<template>
    <h3 ref='h3ref'><h3/>    //绑定return的响应对象数据
    <com-child ref='comChild'/>
<template/>

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值