vue3.0 新特性 - 基础篇

1.setup()

setup() 函数是我们使用vue3的Composition API新特性提供了统一的入口。

  • 执行时机 setup函数会在 beforeCreate之后,created之情执行。
  • 接受参数
    第一个形参 props 数据
在 props 中定义当前组件允许外界传递过来的参数名称:
props: {
  p1: String
}
通过 setup 函数的第一个形参,接收 props 数据:
setup(props) {
    console.log(props.p1)
}

第二个形参是一个上下文对象,这个上下文对象中包含了一些有用的属性,这些属性在 vue 2.x 中需要通过 this 才能访问到,在 vue 3.x 中,它们的访问方式如下:

const MyComponent = {
  setup(props, context) {
    context.attrs
    context.slots
    context.parent
    context.root
    context.emit
    context.refs
  }
}
注意:在 setup() 函数中无法访问到 this

2.reactive() 与 ref()

基本语法:创建响应式数据对象,等价于 vue 2.x 中的 Vue.observable() 函数

  • reactive 和 ref 都是用来定义响应式数据的 reactive更推荐去定义复杂的数据类型 ref 更推荐定义基本类型

  • ref 和 reactive 本质我们可以简单地理解为ref是对reactive的二次包装, ref定义的数据访问的时候要多一个.value

  • 使用ref定义基本数据类型,ref也可以定义数组和对象。


    image.png

    image.png
  • 另外
    1.isRef() 用来判断某个值是否为 ref() 创建出来的对象。
    2.toRefs() 函数可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref() 类型的响应式数据。

3.watch()
  • 监视 reactive 类型的数据源:
// 定义数据源
const state = reactive({ count: 0 })
// 监视 state.count 这个数据节点的变化
watch(
  () => state.count,
  (count, prevCount) => {
    /* ... */
  }
)
const state = reactive({ count: 0, name: 'zs' })

watch(
  [() => state.count, () => state.name], // Object.values(toRefs(state)),
  ([count, name], [prevCount, prevName]) => {
    console.log(count) // 新的 count 值
    console.log(name) // 新的 name 值
    console.log('------------')
    console.log(prevCount) // 旧的 count 值
    console.log(prevName) // 新的 name 值
  },
  {
    lazy: true // 在 watch 被创建的时候,不执行回调函数中的代码
  }
)

setTimeout(() => {
  state.count++
  state.name = 'ls'
}, 1000)
  • 监视 ref 类型的数据源:
// 定义数据源
const count = ref(0)
// 指定要监视的数据源
watch(count, (count, prevCount) => {
  /* ... */
})
const count = ref(0)
const name = ref('zs')

watch(
  [count, name], // 需要被监视的多个 ref 数据源
  ([count, name], [prevCount, prevName]) => {
    console.log(count)
    console.log(name)
    console.log('-------------')
    console.log(prevCount)
    console.log(prevName)
  },
  {
    lazy: true
  }
)

setTimeout(() => {
  count.value++
  name.value = 'xiaomaolv'
}, 1000)
  • 清除监视
    在 setup() 函数内创建的 watch 监视,会在当前组件被销毁的时候自动停止。如果想要明确地停止某个监视,可以调用 watch() 函数的返回值即可,语法如下:
// 创建监视,并得到 停止函数
const stop = watch(() => {
  /* ... */
})

// 调用停止函数,清除对应的监视
stop()
  • 在watch中清除无效的异步任务
    有时候,当被 watch 监视的值发生变化时,或 watch 本身被 stop 之后,我们期望能够清除那些无效的异步任务,此时,watch 回调函数中提供了一个 cleanup registrator function 来执行清除的工作。这个清除函数会在如下情况下被调用:
    1.watch 被重复执行了
    2.watch 被强制 stop 了
/* template 中的代码 */ 
// 定义响应式数据 keywords
const keywords = ref('')
// 异步任务:打印用户输入的关键词
const asyncPrint = val => {
  // 延时 1 秒后打印
  return setTimeout(() => {
    console.log(val)
  }, 1000)
}
// 定义 watch 监听
watch(
  keywords,
  (keywords, prevKeywords, onCleanup) => {
    // 执行异步任务,并得到关闭异步任务的 timerId
    const timerId = asyncPrint(keywords)
    // 如果 watch 监听被重复执行了,则会先清除上次未完成的异步任务
    onCleanup(() => clearTimeout(timerId))
  },
  // watch 刚被创建的时候不执行
  { lazy: true }
)
// 把 template 中需要的数据 return 出去
return {
  keywords
}

4.LifeCycle Hooks

新版的生命周期,可以按需导入到组件中,且只能在 setup() 函数中使用,代码示例如下:

import { onMounted, onUpdated, onUnmounted } from '@vue/composition-api'

const MyComponent = {
  setup() {
    onMounted(() => {
      console.log('mounted!')
    })
    onUpdated(() => {
      console.log('updated!')
    })
    onUnmounted(() => {
      console.log('unmounted!')
    })
  }
}

下面的列表,是 vue 2.x 的生命周期函数与新版 Composition API 之间的映射关系:

  • beforeCreate-created -> use setup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured

5.provide 与 inject

provide() 和 inject() 可以实现嵌套组件之间的数据传递。这两个函数只能在 setup() 函数中使用。父级组件中使用 provide() 函数向下传递数据;子级组件中使用 inject() 获取上层传递过来的数据。

  • 共享普通数据






  • 共享ref响应式数据



6. template refs

通过 ref() 还可以引用页面上的元素或组件。

  • 元素的引用



  • 组件的引用






7.createComponent

这个函数不是必须的,除非你想要完美结合 TypeScript 提供的类型推断来进行项目的开发。

这个函数仅仅提供了类型推断,方便在结合 TypeScript 书写代码时,能为 setup() 中的 props 提供完整的类型推断。
import { createComponent } from 'vue'
export default createComponent({
  props: {
    foo: String
  },
  setup(props) {
    props.foo // <- type: string
  }
})

你可能感兴趣的:(vue3.0 新特性 - 基础篇)