Vue的setup| 青训营笔记

88 阅读1分钟

ChMkJlah6XmIYC1_AA_mAyQe9GEAAHjsgMqgakAD-Yb054.jpg 这是我参与「第四届青训营 」笔记创作活动的第2天

后续会不断完善,欢迎指正

一、问题

Vue3.0中setup需要将声明的变量、函数以及 import 引入的内容通过return向外暴露,才能在<template/>使用

然而,在<script setup>中,我们无需return 声明的变量、函数以及import引入的内容 ,这中间的操作由<script setup>这个语法糖来帮我们完成,不再需要写export default{}

二、script setup的使用方式

1、组件注册:

不需要在引入组件后,通过 components:{}注册组件,可直接使用

2、组件通信:

<script setup>中必须使用 defineProps  defineEmits API 来替代 props 和 emits 。这两个API直接可用,不需要import,子组件使用时如下:

defineProps

<script setup>

//import {defineProps} from 'vue'   不需要引入

//语法糖必须使用defineProps替代props`

const  props = defineProps({

  title: {

   type: String

  }

});

//script-setup 需要通过props.xx获取父组件传递过来的props

console.log(props.title)  //父的值

</script>


and defineEmits

<script setup>

import {ref} from  'vue'

const name = ref('我是子组件')

//1、暴露内部数据

const  emits = defineEmits(['childFn']);

const  toEmits = () => {

    //2、触发父组件中暴露的childFn方法并携带数据

    emits('childFn',name)

}

</script>

补:defineEmits子组件向父组件传递值时,对于父组件,使用如下:

<Child  @childFn='fatherMethod'/>childFn是子组件中emit的名字,fatherMethod是父组件在自己的组件内定义的 用于接收的方法名

3、<slot/>attrs:

如果需要在script-setup中使用 slots 和 attrs 需要用useSlots 和 useAttrs替代

需要引入:import { useSlots ,useAttrs } form 'vue'

<template/>中通过 $slots 和 $attrs 来访问更方便

attrs用来获取父组件中非props(子组件如果在props里面声明了父组件传来的参数a,那么子组件就无法通过attrs来得到a)的传递到子组件的参数/方法, slots可以获取父组件中插槽传递的虚拟dom对象,在SFC模式应该用处不大,在JSX /TSX使用比较多

父组件

<template>

       <Child msg="非porps传值子组件用attrs接收">

           <!-- 匿名插槽 -->

           <span >默认插槽</span>

           <!-- 具名插槽 -->

           <template   #title> 

             <h1>具名插槽</h1> 

           </template> 

           <!-- 作用域插槽 --> 

           <template   #footer="{ scope }"> 

             <footer>作用域插槽——姓名:{{ scope.name }},年龄{{ scope.age }}</footer> 

           </template> 

     </Child> 

 </template> 

 <script setup> 

 // 引入子组件 

  import Child from  ``'./child.vue' 

 </script> 

子组件

 <template> 

     <!-- 匿名插槽 --> 

     <slot /> 

     <!-- 具名插槽 --> 

     <slot name= "title"  /> 

     <!-- 作用域插槽 --> 

     <slot name="footer":scope="state"/>

     <!-- $attrs 用来获取父组件中非props的传递到子组件的参数 -->

     <p>{{ attrs.msg == $attrs.msg }}</p>

     <!--true  没想到有啥作用... -->

     <p>{{ slots == $slots }}</p>

</template>

<script setup>

    import { useSlots, useAttrs, reactive, toRef } from  'vue'

    const state = reactive({

       name:  '张三',

       age:  '18'

    })

    const slots = useSlots()

    console.log(slots.default ());  //获取到默认插槽的虚拟dom对象

    console.log(slots.title());    //获取到具名title插槽的虚拟dom对象

    // console.log(slots.footer()); //报错  不知道为啥有插槽作用域的无法获取

    //useAttrs() 用来获取父组件传递的过来的属性数据的(也就是非 props 的属性值)。

    const attrs = useAttrs()

</script>

4、在setup访问路由

setup 里不能访问 this,不能再直接访问 this.$router 或 this.$route。 (getCurrentInstance可以替代this)

推荐:使用useRoute 函数和useRouter函数替代this.$route 和 this.$router

<script setup>

    import { useRouter, useRoute } from  'vue-router'

    const route = useRoute()

    const router = useRouter()

    function pushWithQuery(query) {

      router.push({

         name:  'search',

         query: {

          ...route.query,

          },

       })

    }

<script/>

over

推荐原文