学习来源

1.简介

setup函数是一个新的组件选项。作为在组件内使用Composition API的入口点。

2.调用时机

创建组件实例,然后初始化props,紧接着就调用setup函数,从生命周期钩子的视角来看,它会在beforeCreate钩子之前被调用。

3.模板中使用

如果setup返回一个对象,则对象的属性将会被合并到组件模板的渲染上下文。

<template>
  <button>
    {{count}}---{{object.foo}}
  </button>
</template>

<script>
  import {ref,reactive} from 'vue';
  export default{
    setup(){
      const count = ref(0)
      const object = reactive({
        foo:'bar'
      })

      return {
        count,
        object,
      }
    },
  }
</script>

Tips:setup()是函数,具有return,return函数中定义的变量,把其暴露给模板。

4.渲染函数 / JSX中使用

setup也可以返回一个函数,函数中也能使用当前setup函数作用域中的响应式数据。

<script>
  import {h,ref,reactive} from 'vue';
  export default{
    setup(){
      const count = ref(0);
      const object = reactive({
        foo:'foo'
      })

      return ()=> h('div',[count.value,'----',object.foo])
    }
  }
</script>

Tips: 3和4中,虽然都是用ref来定义count的初始值,但在使用过程中却不同,直接return出去暴露给模板的不需要.value,可以自动被解开,所以直接使用{{count}}即可。但是h函数中,却需要count.value才能获取相应的值。

5.参数

5.1 Props第一个参数

setup函数接收props作为其第一个参数,props对象是响应式的,watchEffect或watch会观察和响应props的更新。不要对props对象进行解构,那样会失去响应性。在开发过程中,props对象对用户空间代码时不可变的,用户尝试修改props时会触发警告。

eg1:props作为setup的第一个参数

// 父组件 Home.vue
<template>
  <div class="home">
    <About :name="sendData"/>
  </div>
</template>
<script>
  import {ref} from 'vue'; 
  import About from './About'
  export default{
    components:{
      About,
    },
    setup(){
      const sendData = ref('这世界很酷');
      return {
        sendData
      }
    }
  }
</script>

// 子组件About.vue
<template>
  <div class="about">
  {{propContent}}
  </div>
</template>
<script>
  import {watchEffect} from 'vue';
  export default{
    props:{
      name:String
    },
    setup(props){
      let propContent;
      watchEffect(()=>{
        propContent = props.name
      })
      return {
        propContent
      }
    }
  }
</script>

5.2 Context上下文对象第二个参数

第二个参数提供了一个上下文对象

// 父组件 Home.vue
<template>
  <div class="home">
  
    <About :name="sendData.val" @name-changed=changeName>
      世界变化不停,人潮川流不息
    </About>
  </div>
</template>
<script>
  import {reactive} from 'vue';
  import About from './About';
  export default{
    components:{
      About,
    },
    setup(){
      const sendData = reactive({
        val:'sendData'
      })

      setTimeout(()=>{
        sendData.val+=1;
      },1000)

      function changeName(){
        console.log("事件传送出来了")
      }
      return {
        sendData,
        changeName,
      }
    }
  }
</script>

//子组件 About.vue
<template>
  <div class="about">
    
  </div>
</template>
<script>
  import {watch} from 'vue';
  export default {
    props:{
      name:String
    },
    setup(props, context) {
      console.log(context,"上下文");
      watch(()=>props.name,(newName,oldName)=>{
        console.log(newName,oldName);
        context.emit('name-changed')
      }
    );
    },
  }
</script>

5.3 为什么props没有被包含在上下文中?

 1.组件使用props的场景更多,有时甚至只需要使用props
 2.将props独立出来作为一个参数,可以让TypeScript对props单独做类型推导,不会和上下文中其他属性混淆。这也使得setup、render和其他使用了TSX的函数式组件的签名保持一致。

5.4 this的用法

this在setup中不可用,方法和声明周期都可以写在setup中,如果在方法中访问setup中的变量时,直接变量名就可以使用。方法名和变量名要在setup中return出去才可以正常执行。

实例:
<template>
  <div class="home">
    <button @click='add'>{{count.val}}--{{count.doubleVal}}</button>
  </div>
</template>
<script>
  import {reactive,computed} from 'vue';
export default{
  setup(){
    const count = reactive({
      val:0,
      doubleVal:computed(()=>count.val*2)
    })
    function add(){
      count.val ++;
    }
    return {
      count,
      add,
    }
  }
}
</script>

学习Vue3的第一天,加油!

Logo

前往低代码交流专区

更多推荐