【Vue3】setup示例,用法以及原理(持续更新)

目录

setup原理说明

由于setup 是在beforeCreate 和 create 生命周期阶段,组件还没有创建,即还没有进入 data 方法 阶段。
setup 返回的结果集 作为 (传统写法)data 和 method 的值,确切点说是绑定到 组件对象的属性。

setup函数特性

1、setup函数是处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之间的函数 也就说在 setup函数中是无法 使用 data 和 methods 中的数据和方法的
2、setup函数是 Composition API(组合API)的入口
3、在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用

setup 函数将接收两个参数,props&context
Props :props接收父组件传入的值,为Proxy对象,且为响应式,所以不能使用 ES6 解构,它会消除 prop 的响应性
context:官方解释=>context 是一个普通的 JavaScript 对象,它暴露组件的三个 property:

export default {
  setup(props, context) {
    // Attribute (非响应式对象)
    console.log(context.attrs)
 
    // 插槽 (非响应式对象)
    console.log(context.slots)
 
    // 触发事件 (方法)
    console.log(context.emit)
  }
}

setup函数注意点

1、由于在执行 setup函数的时候,还没有执行 Created 生命周期方法,所以在 setup 函数中,无法使用 data 和 methods 的变量和方法
2、由于我们不能在 setup函数中使用 data 和 methods,所以 Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined
3、setup函数只能是同步的不能是异步的

setup 包含的生命周期

onBeforeMount——挂载开始前调用
onMount——挂载后调用
onBeforeUpdate——当响应数据改变,且重新渲染前调用
onUpdated——重新渲染后调用
onBeforeUnmount——Vue实例销毁前调用
onUnmounted——实例销毁后调用
onActivated——当keep-alive组件被激活时调用
onDeactivated——当keep-alive组件取消激活时调用
onErrorCaptured——从子组件中捕获错误时调用

setup中的watch与computed

看下面的grandson.vue的例子

setup拆分实例

main.js

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

App.vue

<script setup>
import Parent from './components/parent.vue'
</script>

<template>
  <Parent></Parent>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

parent.vue

<template>
    <div @click="handleClick">我是父组件 {{info}}
        <son></son>
    </div>
</template>

<script>
import { defineComponent } from 'vue'
import son from './son.vue'
import useInfo from './info.js'

export default defineComponent({
    setup() {
        let {info, handleClick} = useInfo()
        return {
            info,
            handleClick
        }        
    },
    components: {
        son
    }
})
</script>

info.js


import {provide, reactive, ref } from 'vue'

let useInfo = () => {
    let info = ref(123);
        let datas = reactive({
            width: 100,
            height: 50,
            bg: 'pink'
        });
        const updateInfo = (val) => {
            info.value = val
        }

        const handleClick = () => {
            console.log('handleClick了');
            info.value++;
            console.log('info.value:' + info.value);
        }

        provide('info', info);
        provide('datas', datas)
        provide("updateInfo", updateInfo);

        return {
            info,
            handleClick
        }
}

export default useInfo


son.vue

<template>
    <div>我是子组件 {{info}}
        <grand-son ref="compa"></grand-son>
    </div>
</template>

<script>
import { defineComponent, inject } from 'vue'
import grandSon from './grandSon.vue';


export default defineComponent({
    setup() {
        const info = inject('info');
        
        return {
            info
        }
    },
    components: {
        grandSon
    }
})
</script>

grandson.vue

<template>
    <div>我是孙子组件 <button @click="updateInfo('456')">点击更新info</button>{{info}} computed: {{computedInfo}}<br />宽度{{datas.width}},  高度:{{datas.height}}, 背景: {{datas.bg}}</div>
</template>

<script>
import { defineComponent , inject, watch, computed} from 'vue'


export default defineComponent({
    setup() {
        const info = inject('info');
        const updateInfo = inject('updateInfo');
        const datas = inject('datas');
        
        
        watch(info, (val) => {
            console.log('变了');
            console.log(val);
        });

        const computedInfo = computed(() => { 
            console.log('computed 改变了info')
            return info.value + 10
        })


        return {
            info,
            datas,
            updateInfo,
            computedInfo
        }
    },
})
</script>


上一篇:Winform TreeView自定义样式侧边导航栏


下一篇:C#实现TabControl选项卡竖着排列,控件文字横向显示