← 返回首页
Vue3基础教程(二十一)
发表时间:2021-08-10 16:07:22
setup详解

1.setup执行的时机

实例:

App.vue

<template>
    <!--与vue2模板的区别:不需要定义一个根标签-->
    <h1>Setup()执行的时机</h1>
    <hr>
    <div>
        {{msg}}
    </div>
    <div>
        <button @click="changeMsg">更新msg内容</button>
    </div>
    <hr>
    <Child :msg="msg"></Child>
</template>

<script lang="ts">
    import {defineComponent, ref, reactive} from 'vue';
    import Child from "@/components/Child.vue";

    export default defineComponent({
        name: 'App',
        //注册子组件
        components:{
          Child
        },
        beforeCreate() {
           console.log('App Vue: beforeCreate()....');
        },
        setup() {
            console.log('App Vue: setup()...');
            console.log(this);
            let msg= ref('Hello,Javascript!');
            function changeMsg() {
                msg.value += "^_^";
            }
            return {
                msg,
                changeMsg
            }
        }
    });
</script>

Child.vue

<template>
    <div>
        <h2>子组件Child</h2>
        <hr>
        <div>
            {{msg}}
        </div>
    </div>
</template>

<script lang="ts">
    import {defineComponent} from 'vue';

    export default defineComponent({
        name: 'Child',
        props: ['msg'],
        beforeCreate() {
            console.log('Child Vue: beforeCreate()...');
        },
        setup() {
            console.log("Child Vue: setup()....");
            console.log(this);
        }
    });
</script>

运行结果:

App Vue: setup()...
undefined
App Vue: beforeCreate()....
Child Vue: setup()....
undefined
Child Vue: beforeCreate()...

2.setup的返回值

注意: - 一般不要混合使用: methods中可以访问setup提供的属性和方法, 但在setup方法中不能访问data和methods - setup不能是一个async函数: 因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性数据

实例:

<template>
    <!--与vue2模板的区别:不需要定义一个根标签-->
    <h1>Setup()执行的时机</h1>
    <hr>
    <div>
        {{msg}}<br>
        计数器:{{count}}
    </div>
    <div>
        <button @click="changeMsg">更新msg内容</button>
    </div>
    <hr>
    <Child :msg="msg"></Child>
</template>

<script lang="ts">
    import {defineComponent, ref, reactive} from 'vue';
    import Child from "@/components/Child.vue";

    export default defineComponent({
        name: 'App',
        //注册子组件
        components:{
          Child
        },
        data(){
            return{
               count:0
            }
        },
        beforeCreate() {
           console.log('App Vue: beforeCreate()....');
        },

        mounted() {
           console.log(this); //this也变成了代理对象
           this.fn();
        },
        setup() {
            //let count = 'haha';  //error,不能重复定义属性
            console.log('App Vue: setup()...');
            console.log(this);
            let msg= ref('Hello,Javascript!');
            function changeMsg() {
                msg.value += "^_^";
            }
            function fn(){
               console.log('in setup fn()...');
            }
            return {
                msg,
                changeMsg,
                //fn   //error,返回重复的方法名字
                //count
            }
        },
        methods:{
            fn(){
                console.log('in methods fn()...');
            }
        }
    });
</script>

3.setup参数

实例:

App.vue

<template>
    <!--与vue2模板的区别:不需要定义一个根标签-->
    <h1>Setup()执行的时机</h1>
    <hr>
    <div>
        {{msg}}<br>
        计数器:{{count}}
    </div>
    <div>
        <button @click="changeMsg">更新msg内容</button>
    </div>
    <hr>
    <Child :msg="msg" :title="'my title'" @fun="fun"></Child>
</template>

<script lang="ts">
    import {defineComponent, ref, reactive} from 'vue';
    import Child from "@/components/Child.vue";

    export default defineComponent({
        name: 'App',
        //注册子组件
        components:{
          Child
        },
        data(){
            return{
               count:0
            }
        },
        beforeCreate() {
           console.log('App Vue: beforeCreate()....');
        },

        mounted() {
           console.log(this);
           this.fn();
        },
        setup() {
            //let count = 'haha';  //error,不能重复定义属性
            console.log('App Vue: setup()...');
            console.log(this);
            let msg= ref('Hello,Javascript!');
            function changeMsg() {
                msg.value += "^_^";
            }
            function fun(content:string){
               //console.log('in setup fn()...');
               msg.value += content;
            }
            return {
                msg,
                changeMsg,
                fun
            }
        },
        methods:{
            fn(){
                console.log('in methods fn()...');
            }
        }
    });
</script>

Child.vue

<template>
    <div>
        <h2>子组件Child</h2>
        <hr>
        <div>
            {{msg}}
        </div>
        <slot name="myslot">{{msg}}</slot>
        <br>
        <button @click="update">更新</button>
    </div>
</template>

<script lang="ts">
    import {defineComponent} from 'vue';

    export default defineComponent({
        name: 'Child',
        props: ['msg'],
        emits: ['fun'], // 可选的, 声明了更利于程序员阅读, 且可以对分发的事件数据进行校验
        beforeCreate() {
            console.log('Child Vue: beforeCreate()...');
        },
        setup(props, {attrs, slots, emit}) {
            console.log(props.msg);
            console.log(attrs.msg+","+attrs.title); //undefined ,mytitle
            console.log(slots);
            function update () {
                // 分发自定义事件
                emit('fun', '@_@')
            }
            return{
                update
            }
        }
    });
</script>