vue3 setup语法糖

我心飞翔 分类:vue

vue3支持三种写法

  • option(选项)API
  • composition(组合式)API
  • <script setup>composition API的语法糖

option API

  • 这种方式也就是我们之前vue2中使用的方式。我们通过一个个的配置,来实现这个组件。
  • 然后如果使用ts的话,就增加了一些ts的类型约束。
  • defineComponent从vue中导入,只是给组件包装成默认的组件类型。
<script lang="ts">

import { defineComponent } from "vue"

export default defineComponent({
    name:'Test',
    // props
    props : {
      msg:{
          type:String,
          default:''
      }
    },
    // 数据
    data(){
        return{
            count:0
        }
    },
    // 声明周期函数
    mounted(){
        console.log('mounted')
    },
    // 自定义方法
    methods:{
        increment(){
            this.count++
        }
    }
})
</script>
复制代码

这个方法相对于vue2语法,并没有变得很简便,所以我们不提倡用这种方法。

composition API

和选项api的最大不同就是新增了 setup()。我们要处理的逻辑都放到了setup()中

export default defineComponent({
    name:'Test',
    props : {
      msg:{
          type:String,
          default:''
      },
      second:{
          type:String,
          default:'默认'
      }
    },
   setup(){
      // 响应式数据
      const count = ref(0)
      const increment = ()=>{
          count.value++
      }
     // 返回出去 供模板使用
      return {
          count,
          increment
      }
   }
})
复制代码

setup

在其内部处理数据、和一些逻辑方法。最后需要将这些数据和方法return出去,才可以供模板使用。

如下按钮点击触发increment方法,让count增加1.

<template>

{{count}}
<el-button @click="increment">增加</el-button>
</template>

<script lang="ts">

import { defineComponent, ref } from "vue"
export default defineComponent({
    name:'Test',
   setup(){
      // 响应式数据
      const count = ref(0)
      const increment = ()=>{
          count.value++
      }
     // 返回出去 供模板使用
      return {
          count,
          increment
      }
   }
})
</script>
复制代码

响应式数据

上面的代码中可以看到 ref的使用。那么他的用途就是使 数据成为响应式的数据。

普通数据

我们可以试一试把它改成普通数据,是可以渲染到模板中的。但是点击按钮,页面的渲染是不会改变的。并且,我们分别在increment函数内、和setup作用域中分别打印count。setup内打印只执行了一次,并且当点击按钮时不会打印。

setup(){
      // 响应式数据
      let count = 1
      const increment = ()=>{
          count++
          console.log(count,'count函数内打印')
      }
       console.log(count,'count setup内打印')
     // 返回出去 供模板使用
      return {
          count,
          increment
      }
   }
复制代码
vue3 setup语法糖

响应式数据

需要从vue中导出ref

import { defineComponent, ref } from "vue"
复制代码

将使用的数据包在ref()中,在对count重新赋值的时候,需要对count的.value属性赋值。因为经过ref()处理,这个count成了一个对象。我们打印一下可以发现。

     let count = ref(0)
     const increment = ()=>{
          count.value++
          console.log(count)
      }
复制代码
vue3 setup语法糖

📢 在模板中不需要.value,在<script>部分使用count需要.value

缺点

所有方法都要写在setup()中,并且还都需要return出去。当代码中使用的变量和方法较多后。也就不方便了。

setup语法糖

在使用setup语法糖这种写法的时候,我们不需要再去export导出(它默认的把整个<script setup>标签的内容都进行了export),并且声明props也不可以向上面那么写了。

<script lang="ts" setup>

import { defineComponent, ref } from "vue"

</script>
复制代码

使用响应式数据

一定要注意📢

响应式数据赋值是对其.value进行。并且声明响应式数据时,是可以使用const关键字的。因为我们是对一个ref对象进行操作的。

<template>
{{count}}
<el-button @click="increment">增加</el-button>
</template>
<script lang="ts" setup>
import { defineComponent, ref } from "vue"
let count = ref(100)
const increment  = ()=>{
    count.value++
}
</script>

<style>

</style>
复制代码

官方文档

setup语法糖还没有更新到官方文档。我们可以去 GitHub看详细的用法API。

vue3 setup语法糖

props数据

使用defineProps()API。这个API其实是不用引入的,但是如果报错提示其没有定义,就从vue中导入一下。

父组件

<template>
  <Test msg="from father"/>
</template>
<script lang="ts" setup>
import Test from './Test.vue';
</script>
<style>
</style>
复制代码

子组件

如下使用defineProps()API,然后我们props接收的值就可以像组合式API中那么写了。这里其实将 defineProps()赋值给 porps是为了我们在 <script lang="ts" setup>内使用props值(这样使用 props.msg),如果只有模板中使用props值的话,也可以不这样做。

  • js 部分使用props,props.xxx
  • template 部分使用porps, porps.xxx xxx
<template>
{{msg}}
<!-- 对应props数据 可以使用props. 也可以不使用 -->
{{props.second}}
{{count}}
<el-button @click="increment">增加</el-button>
</template>
<script lang="ts" setup>
import { defineComponent, defineProps,ref } from "vue"
let count = ref(100)

const props = defineProps({
    msg:{
       type:String,
       default:''
    },
    second:{
       type:String,
       default:'second'
    }
})
const increment  = ()=>{
    count.value++
    console.log(props.msg)
}
</script>

<style>

</style>
复制代码
vue3 setup语法糖

defineProps中也可以使用数组 这种情况下就没有默认的 default了。

defineProps(['second','msg'])
复制代码

不要和props内变量同名

注意📢

我们在 <script lang="ts" setup>内部声明的其他变量,不要和props中的变量同名。

let msg = '不是props'
const props = defineProps({
    msg:{
       type:String,
       default:''
    },
    second:{
       type:String,
       default:'second'
    }
})
复制代码

如图,页面中的值并不是props中的msg。

vue3 setup语法糖

子组件传值给父组件

vue3中有类似vue2emit的API:defineEmits

子组件

  • 定义一个变量emit来接收defineEmits()方法返回的对象。defineEmits(),其接收一个数组,数组中写我们要传给父组件的回调函数名(如:increment)。
  • 在这个回调函数中调用emit emit('increment',param) 第一个参数是回调函数名,第二个参数是函数的参数,如果没有就需要写
<template>
{{msg}}
{{second}}
{{count}}
<el-button @click="increment('test')">增加</el-button>
</template>
<script lang="ts" setup>
import { defineEmits, defineProps,ref } from "vue"
let count = ref(100)
const props = defineProps({
    msg:{
       type:String,
       default:''
    },
    second:{
       type:String,
       default:'second'
    }
})
// 接收返回值
const emit = defineEmits(['increment'])
const increment  = (param:string)=>{
    count.value++
    emit('increment',param)
}
</script>
<style>
</style>
复制代码

父组件

  • 注意这个回调方法要用 @
  • 还要声明相应的方法 increment
<template>
  <Test msg="from father" @increment="increment"/>
</template>

<script lang="ts" setup>
import { getLoginInfo } from '@/api/common';
import Test from './Test.vue';
import { onMounted } from 'vue';
const increment = (param:string)=>{
  console.log(param)
}
</script>

<style>

</style>

回复

我来回复
  • 暂无回复内容