目录
  • 一、选项式api 和 组合式api 区别
  • 二、setup 具体怎么用?
    • 2.1、setup 什么时候执行?
    • 2.2、setup 数据和方法如何使用?
    • 2.3、setup 内部有 this 吗?
    • 2.5、setup与钩子函数关系
  • 三、setup 参数
    • 3.1、props
    • 3.2、context
  • 四、setup 特性总结

    本篇文章干货较多,建议收藏!

    从 vue2 升级到 vue3,vue3 是可以兼容 vue2 的,所以 vue3 可以采用 vue2 的选项式api。由于选项式api一个变量存在于多处,如果出现问题时,就需要去多个函数内检查,项目较大时,遇到问题,增加排故的难度。所以 vue3 中新增了 setup 配置项,用它来写组合式api。

    一、选项式api 和 组合式api 区别

    有些同学稀里糊涂用了vue一年了,竟然不知道选项式api !你是那个同学吗?是的话,赶紧收藏起来。

    vue2 中的 options api 就是选项式api,一个中文,一个英文,怎么叫都可以。

    在一个 vue 文件内,会有 data、methods、mounted、computed、watch 等等用来定义属性和方法,共同来处理页面逻辑,我们把这种方式称为 options api。

    示例1:计数器

    <template>
     <div>
      <button @click="add">+</button>
       {{num}}
      <button @click="reduce">-</button>
     </div>
    </template>
    <script>
    export default {
     data(){
      return {
       num:0
      }
     },
     methods:{
      add(){
       this.num++
      },
      reduce(){
       this.num--
      }
     }
    }
    </script>

    观察上述示例,我们发现 num 值的处理涉及到 data 和 methods 两个选项,业务处理的比较分散,项目小了看着清晰明了,但是项目变大之后,data 和 methods会包含很多属性和方法,此时就很难分清哪个属性对应哪个方法。所以 vue3 新增 setup 写组合式api。

    vue3 的 composition api 就是组合式api。

    组合式api 就是一个功能所定义的 api 会放在一起,这样子即使项目变大,功能增大,我们能够很快找到功能相关的所有api,不像 options api 功能分散,需要改动时,需要多处查找过程比较困难。

    示例2:计数器

    <template>
     <div>
      <button @click="add">+</button>
       {{num}}
      <button @click="reduce">-</button>
     </div>
    </template>
    <script>
     import { ref } from 'vue'
     export default{
      setup(){
       const num = ref(1)
       return{
        num,
        add(){
         num.value++
        },
        reduce(){
         num.value--
       }
      }
     }
    }
    </script>

    ref 是让基础数据类型具备响应式的,下篇文章具体介绍它的用法,需要的同学可以点个关注不迷路!

    用一张图告诉你它们的区别:

    二、setup 具体怎么用?

    2.1、setup 什么时候执行?

    setup 用来写组合式 api,从生命周期钩子函数角度分析,相当于取代了 beforecreate 。会在 creted 之前执行。

    <script>
     export default{
      created(){
       console.log('created');
      },
      setup(){
       console.log('setup');
      }
     }
    </script>

    执行之后,setup 打印结果始终在前边。

    2.2、setup 数据和方法如何使用?

    示例3:直接定义使用变量

    <template>
     {{a}}
    </template>
    <script>
     export default{
      setup(){
       const a = 0
      }
     }
    </script>

    运行后发现结果异常:

    runtime-core.esm-bundler.js?5c40:6584 [vue warn]: property “a” was accessed during render but is not defined on instance.

    提示我们访问的属性 a 并没有挂载到实例上。

    setup 内部的属性和方法,必须 return 暴露出来,将属性挂载到实例上,否则没有办法使用,上述代码添加return:

    <script>
     export default{
      setup(){
       const a = 0
       return{
        a
       }
      }
     }
    </script>

    2.3、setup 内部有 this 吗?

    自己在 setup 中打印下 this ,返回结果 是undefined 。说明在 setup 内部是不存在 this ,不能挂载 this 相关的东西。

    2.4、setup 内钩子函数如何使用?

    vue3 是可以兼容 vue2 的选项式写法,所以 钩子函数可以与 setup 并列存在,就相当于 options api。

    示例4:

    export default{
     setup(){
      console.log('setup');
     },
     mounted(){
      console.log('mounted');
     }
    }

    vue3 新增的 setup() 函数用来写组合式 api,所以不建议这样写代码。所以需要使用 onxxx 一族的函数来注册钩子函数,注册成功之后调用时传递的是一个回调函数。

    示例5:

    import { onmounted } from "vue";
    export default{
     setup(){
      const a = 0
      return{
       a
      },
      onmounted(()=>{
       console.log("执行");
     })
     }
    }

    注册的这些生命周期钩子函数只能在 setup 期间同步使用,因为它们依赖全局内部状态来定位当前组件实例,不在当前组件下调用函数时会抛出错误。

    其他的钩子函数是一样的,根据需要引入就好了。

    2.5、setup与钩子函数关系

    setup 与钩子函数并列时,setup 不能调用生命周期相关函数,但生命周期可以调用 setup 相关的属性和方法。

    示例6:

    <template>
     <button @click="log">点我</button>
    </template>
    <script>
    export default{
     setup(){
      const a = 0
      return{
       a
      }
     },
     methods:{
      log(){
       console.log( this.$options.setup() );//返回一个对象
      }
     }
    }
    </script>

    this.$options.setup() 返回的是一个大对象,该对象内包含了 setup 内的所有属性和方法。

    三、setup 参数

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

    3.1、props

    第一个参数是 props ,表示父组件给子组件传值,props 是响应式的,当传入新的 props 时,自动更新。

    示例7:

    export default{
     props: {
      msg: string,
      ans: string,
     },
     setup(props,context){
      console.log(props);//proxy {msg: "着急找对象", ans: "你有对象吗?"}
     },
    }

    因为 props 是响应式的,不能使用 es6 解构,会消除prop的响应特性,此时需要借用 torefs 解构。示例8:

    import { torefs } from "vue";
     export default{
      props: {
       msg: string,
       ans: string,
      },
      setup(props,context){
       console.log(props);
       const { msg,ans } = torefs(props)
       console.log(msg.value); //着急找对象
       console.log(ans.value); //你有对象吗?
      },
     }

    使用组件时,经常会遇到可选参时,有些地方需要传递某个值,有些时候不需要,该如何处理呢?

    如果 ans 是一个可选参数,则传入 props 中可能没有 ans 。在这种情况下 torefs 将不会为 ans 创建一个 ref ,需要使用 toref 代替它。

    import { toref } from "vue";
    setup(props,context){
     let ans  = toref(props ,'ans')// 不存在时,创建一个ans
     console.log(ans.value);
    }

    3.2、context

    context 上下文环境,其中包含了 属性、插槽、自定义事件三部分。

    setup(props,context){
     const { attrs,slots,emit } = context
     // attrs 获取组件传递过来的属性值,
     // slots 组件内的插槽
     // emit 自定义事件 子组件
    }

    attrs 是一个非响应式对象,主要接收 no-props 属性,经常用来传递一些样式属性。

    slots 是一个 proxy 对象,其中 slots.default() 获取到的是一个数组,数组长度由组件的插槽决定,数组内是插槽内容。

    setup 内不存在this,所以 emit 用来替换 之前 this.$emit 的,用于子传父时,自定义事件触发。

    示例9:

    <template>
     <div :style="attrs.style">
      <slot></slot>  
      <slot name="hh"></slot>
      <button @click="emit('getval','传递值')">子向父传值</button> 
     </div> 
    </template>
    <script>
    import { torefs,toref } from "vue";
    export default{
     setup(props,context){
      const { attrs,slots,emit } = context
      // attrs 获取组件传递过来 style 属性
     console.log('slots',slots.default());//插槽数组
     console.log('插槽属性',slots.default()[1].props); //获取插槽的属性   
     return{
      attrs,
      emit
       }
      },
     }
    </script>

    四、setup 特性总结

    1、这个函数会在 created 之前执行,上述已解释。

    2、setup 内部没有 this,不能挂载 this 相关的东西。

    3、setup 内部的属性和方法,必须 return 暴漏出来,否则没有办法使用。

    4、setup 内部数据不是响应式的。

    5、setup不能调用生命周期相关函数,但生命周期函数可以调用setup内的函数。

    到此这篇关于vue3 setup() 高级用法的文章就介绍到这了,更多相关vue3 setup() 用法内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!