Vue3.2 setup语法糖、Composition API使用

1.起初 Vue3.0 暴露变量必须 return 出来,template中才能使用;

2.Vue3.2 中 只需要在 script 标签上加上 setup 属性,组件在编译的过程中代码运行的上下文是在 setup() 函数中,无需return,template可直接使用。

一、文件结构

<template>
  // Vue2中,template标签中只能有一个根元素,在Vue3中没有此限制
  // ...
</template>

<script setup>
  // ...
</script>

<style lang="scss" scoped>
  // 支持CSS变量注入v-bind(color)
</style>

二、computed

<script setup>
  import {
    
     computed, ref } from 'vue'

  const count = ref(1)

  // 通过computed获得doubleCount
  const doubleCount = computed(() => {
    
    
    return count.value * 2
  })
</script>

三、watch

<script setup>
  import {
    
     watch, reactive } from 'vue'

  const state = reactive({
    
    
    count: 1
  })

  // 声明方法
  const changeCount = () => {
    
    
    state.count = state.count * 2
  }

  // 监听count
  watch(
    () => state.count,
    (newVal, oldVal) => {
    
    
      console.log(state.count)
      console.log(`watch监听变化前的数据:${
     
     oldVal}`)
      console.log(`watch监听变化后的数据:${
     
     newVal}`)
    },
    {
    
    
      immediate: true, // 立即执行
      deep: true // 深度监听
    }
  )
</script>

四、v-model

子组件

<template>
  <span @click="changeInfo">我叫{
    
    {
    
     modelValue }},今年{
    
    {
    
     age }}</span>
</template>

<script setup>
  // import {
    
     defineEmits, defineProps } from 'vue'
  // defineEmits和defineProps在<script setup>中自动可用,无需导入
  // 需在.eslintrc.js文件中【globals】下配置【defineEmits: true】、【defineProps: true】

  defineProps({
    
    
    modelValue: String,
    age: Number
  })

  const emit = defineEmits(['update:modelValue', 'update:age'])
  const changeInfo = () => {
    
    
    // 触发父组件值更新
    emit('update:modelValue', 'Tom')
    emit('update:age', 30)
  }
</script>

父组件

<template>
  // v-model:modelValue简写为v-model
  // 可绑定多个v-model
  <child
    v-model="state.name"
    v-model:age="state.age"
  />
</template>

<script setup>
  import {
    
     reactive } from 'vue'
  // 引入子组件
  import child from './child.vue'

  const state = reactive({
    
    
    name: 'Jerry',
    age: 20
  })
</script>

五、子组件ref变量和defineExpose

在标准组件写法里,子组件的数据都是默认隐式暴露给父组件的,但在 script-setup 模式下,所有数据只是默认 return 给 template 使用,不会暴露到组件外,所以父组件是无法直接通过挂载 ref 变量获取子组件的数据。
如果要调用子组件的数据,需要先在子组件显示的暴露出来,才能够正确的拿到,这个操作,就是由 defineExpose 来完成。

六、、路由useRoute和useRouter

<script setup>
  import {
    
     useRoute, useRouter } from 'vue-router'
	
  // 必须先声明调用
  const route = useRoute()
  const router = useRouter()
	
  // 路由信息
  console.log(route.query)

  // 路由跳转
  router.push('/newPage')
</script>

七、路由导航守卫

<script setup>
  import {
    
     onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
	
  // 添加一个导航守卫,在当前组件将要离开时触发。
  onBeforeRouteLeave((to, from, next) => {
    
    
    next()
  })

  // 添加一个导航守卫,在当前组件更新时触发。
  // 在当前路由改变,但是该组件被复用时调用。
  onBeforeRouteUpdate((to, from, next) => {
    
    
    next()
  })
</script>

八、store

*Vue3 中的Vuex不再提供辅助函数写法

<script setup>
  import {
    
     useStore } from 'vuex'
  import {
    
     key } from '../store/index'

  // 必须先声明调用
  const store = useStore(key)
	
  // 获取Vuex的state
  store.state.xxx

  // 触发mutations的方法
  store.commit('fnName')

  // 触发actions的方法
  store.dispatch('fnName')

  // 获取Getters
  store.getters.xxx
</script>

九、CSS变量注入

<template>
  <span>Jerry</span>  
</template>

<script setup>
  import {
    
     reactive } from 'vue'

  const state = reactive({
    
    
    color: 'red'
  })
</script>
  
<style scoped>
  span {
    
    
    // 使用v-bind绑定state中的变量
    color: v-bind('state.color');
  }  
</style>

十、原型绑定与组件内使用

main.js

import {
    
     createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)

// 获取原型
const prototype = app.config.globalProperties

// 绑定参数
prototype.name = 'Jerry'

组件内部使用

import {
    
     createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)

// 获取原型
const prototype = app.config.globalProperties

// 绑定参数
prototype.name = 'Jerry'

十一、对 await 的支持

不必再配合 async 就可以直接使用 await 了,这种情况下,组件的 setup 会自动变成 async setup 。

<script setup>
  const post = await fetch('/api').then(() => {
    
    })
</script>

十二、定义组件的name

用单独的

<script>
  export default {
    
    
    name: 'ComponentName',
  }
</script>

十三、provide和inject

父组件

<template>
  <child/>
</template>

<script setup>
  import {
    
     provide } from 'vue'
  import {
    
     ref, watch } from 'vue'
  // 引入子组件
  import child from './child.vue'

  let name = ref('Jerry')
  // 声明provide
  provide('provideState', {
    
    
    name,
    changeName: () => {
    
    
      name.value = 'Tom'
    }
  })

  // 监听name改变
  watch(name, () => {
    
    
    console.log(`name变成了${
     
     name}`)
    setTimeout(() => {
    
    
      console.log(name.value) // Tom
    }, 1000)
  })
</script>

子组件

<script setup>
  import {
    
     inject } from 'vue'
	// 注入
  const provideState = inject('provideState')
  
  // 子组件触发name改变
  provideState.changeName()
</script>

猜你喜欢

转载自blog.csdn.net/weixin_45361998/article/details/121395318