vue3的setup使用

setup的设计是为了使用组合式apisetup位于created 和beforeCreated之前,用于代替created 和beforeCreated,但是在setup函数里不能访问到this,另外setup内可以通过以下hook操作整个生命周期onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted,onErrorCaptured,onRenderTracked,onRenderTriggered

1. setup可以接收哪些参数?

使用 setup 函数时,它将接收两个参数:props,context

export default {
	props:{
		title: String
	},
	setup(props, ctx) {
		//setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。
		console.log(props.title)
		
		// Attribute (非响应式对象,等同于 $attrs)
	    console.log(context.attrs)
	
	    // 插槽 (非响应式对象,等同于 $slots)
	    console.log(context.slots)
	
	    // 触发事件 (方法,等同于 $emit)
	    console.log(context.emit)
	
	    // 暴露公共 property (函数)
	    console.log(context.expose)
	}
}
2. 在 setup() 内部,this 不是该活跃实例的引用

getCurrentInstance 获取当前组件的实例、上下文来操作router和vuex等。 (请不要把它当作在组合式 API 中获取 this 的替代方案来使用)

import { getCurrentInstance } from 'vue';
export default {
	setup() {
		console.log(this) // undefined
		
		const instance = getCurrentInstance();
		// 获取当前组件的上下文,下面两种方式都能获取到组件的上下文。
		const { ctx }  = getCurrentInstance();  //  方式一,这种方式只能在开发环境下使用,生产环境下的ctx将访问不到
		const { proxy }  = getCurrentInstance();  //  方式二,此方法在开发环境以及生产环境下都能放到组件上下文对象(推荐)
		// ctx 中包含了组件中由ref和reactive创建的响应式数据对象,以及以下对象及方法;
		proxy.$attrs
		proxy.$data
		proxy.$el
		proxy.$emit
		proxy.$forceUpdate
		proxy.$nextTick
		proxy.$options
		proxy.$parent
		proxy.$props
		proxy.$refs
		proxy.$root
		proxy.$slots
		proxy.$watch
	}
}
3. 在setup中通过ref获取dom
<template>
	<div ref="openLayer"></div>
</template>
import {ref,onMounted} from 'vue';
<script>
export default{
  setup(){
    let openLayer= ref(null);// 创建一个响应式数据,并且要把响应式数据暴露出去 
    onMounted(()=>{
      console.log(openLayer.value) // 当元素被创建出来的适合,就会给对应的响应数据赋值
    });
    return {openLayer}
  }
}
</script>
4. 在setup中使用eventbus

我们可以使用第三方库Vue3-Eventbus或者动手写一个也行

// bus.js
export default class EventBus{
    constructor(){
        this.events = {};
    }
    emit(eventName, data) {
        if (this.events[eventName]) {
            this.events[eventName].forEach(function(fn) {
                fn(data);
            });
        }
    }
    on(eventName, fn) {
        this.events[eventName] = this.events[eventName] || [];
        this.events[eventName].push(fn);
    }

    off(eventName, fn) {
        if (this.events[eventName]) {
            for (var i = 0; i < this.events[eventName].length; i++) {
                if (this.events[eventName][i] === fn) {
                    this.events[eventName].splice(i, 1);
                    break;
                }
            };
        }
    }
}

在main.js中挂载

// main.js
import { createApp } from 'vue'
const app = createApp(App)
import EventBus from '@/bus.js'
const bus = new EventBus()
// 1.使用provide注入
app.provide('$bus', bus)
// 2.挂载到this上
app.config.globalProperties.$bus = bus

在setup中使用

import { inject } from 'vue'
export default {
  setup() {
      const $bus = inject('$bus')
      $bus.emit('handler')
  },
  created() {
      this.$bus.emit('handler')
  }
}
5. 在setup中使用vuex

访问 State Getter Mutation Action

import { computed } from 'vue'
import { useStore } from 'vuex'

export default {
  setup () {
    const store = useStore()

    return {
      // 在 computed 函数中访问 state
      count: computed(() => store.state.count),

      // 在 computed 函数中访问 getter
      double: computed(() => store.getters.double)
	
	 // 使用 mutation
      increment: () => store.commit('increment'),

      // 使用 action
      asyncIncrement: () => store.dispatch('asyncIncrement')
    }
  }
}
Logo

前往低代码交流专区

更多推荐