vue3 setup 使用教程

vue3 中新增了 setup,它的出现是为了解决组件内容庞大后,理解和维护组件变得困难的问题。即 vue 中 data、computed、methods、watch 等内容非常多以后,同一业务逻辑的 data 中的数据和 methods 中的方法在 vue 文件中“相隔甚远”,看代码时,经常需要根据 data 中的数据去搜索找到对应的 methods 方法,上下跳跃查看代码,非常不方便。而在 setup 中,则可以把 data 中的数据和 methods 方法写在相临的位置,方便查看和维护。本文详细介绍 setup 的用法

目录

1、简单使用

2、修改 setup 中的变量值

3、setup 形式下的父子组件通信

3.1、父传子

3.2、子传父

3.2.1、子组件调用父组件方法

3.2.2、子组件向父组件传递数据

 4、setup 中使用生命周期函数


1、简单使用

先简单写一下看看效果

笔者这里使用新建的 vue3 项目,直接在 App.vue 上进行修改

<template>
  <div>{{name}}</div>
</template>

<script>
export default {
  setup() {
    return {
      name: "泪眼问花花不语,乱红飞过秋千去"
    }
  }
}
</script>

原来写在 data 中的 name,在 setup 中需要 return 返回

运行效果

2、修改 setup 中的变量值

先看下面代码,再说在 setup 中如何修改

<template>
  <div>
    {{name}}
    <button @click="change">修改</button>
  </div>
</template>

<script>
export default {
  setup() {
    let name = "泪眼问花花不语,乱红飞过秋千去"
    function change() {
      name = "人生自是有情痴,此恨不关风与月"
    }
    return {
      name,
      change
    }
  }
}
</script>

按照常规逻辑,修改 setup 中的 name,会自然地写出上面的代码

但是这段代码是不能完成 name 值的修改的,看运行效果

为什么 name 值没有改变呢?因为上面代码中 name 是非响应式的

如果想要修改 name 值,就需要把它改成响应式的,代码如下

<template>
  <div>
    {{name}}
    <button @click="change">修改</button>
  </div>
</template>

<script>
import { ref } from 'vue'
export default {
  setup() {
    let name = ref("泪眼问花花不语,乱红飞过秋千去")
    function change() {
      name.value = "人生自是有情痴,此恨不关风与月"
    }
    return {
      name,
      change
    }
  }
}
</script>

使用 ref 对 name 进行包装

修改时使用 变量名.value 的语法

运行效果

除了使用 ref 外还可以使用 reactive ,二者都可以将原始数据类型转换成一个带有响应式特性的数据类型

ref 和 reactive 有什么区别,ref 一般处理基本类型;reactive 处理复杂的数据类型

reactive 使用代码

<template>
  <div>
    {{nameObj.name}}
    <button @click="change">修改</button>
  </div>
</template>

<script>
import {reactive} from 'vue'
export default {
  setup() {
    let nameObj = reactive({name: '今年花胜去年红。可惜明年花更好,知与谁同'})
    function change() {
      nameObj.name = "离愁渐远渐无穷,迢迢不断如春水"
    }
    return {
      nameObj,
      change
    }
  }
}
</script>

运行效果

3、setup 形式下的父子组件通信

代码写成 setup 形式,如何实现父子组件通信,下面介绍

3.1、父传子

在 components 目录下新建 Article.vue 作为子组件

Article.vue 内容

<template>
  <div>
    {{msg}}
    {{info}}
  </div>
</template>

<script>
export default {
  props:['msg'],
  setup(props) {
    console.log(props.msg)

    return {
      info:props.msg
    }
  }
}
</script>

在 setup 方法内使用 props 来接收父组件传过来的数据

App.vue 为父组件

在 App.vue 中引入 Article.vue

<template>
  <div>
    <Article :msg="name"></Article>
  </div>
</template>

<script>
import Article from '@/components/Article.vue' 
export default {
  components: {
    Article
  },
  setup() {
    return {
      name: '渐行渐远渐无书,水阔鱼沉何处问'
    }
  }
}
</script>

运行效果

3.2、子传父

3.2.1、子组件调用父组件方法

Article.vue 内容

<template>
  <div>
    {{msg}}
    <button @click="sendToParent">子组件向父组件传递数据</button>
  </div>
</template>

<script>
export default {
  props:['msg'],
  setup(props, content) {
    console.log(props.msg)
    function sendToParent() {
      content.emit('change')
    }
    return {
      sendToParent
    }
  }
}
</script>

使用 setup 方法中 content 参数中的 emit

App.vue 内容

<template>
  <div>
    <Article :msg="name" @change="changeName"></Article>
  </div>
</template>

<script>
import Article from '@/components/Article.vue' 
export default {
  components: {
    Article
  },
  setup() {
    function changeName() {
      alert('父组件事件被调用')
    }
    return {
      name: '渐行渐远渐无书,水阔鱼沉何处问',
      changeName
    }
  }
}
</script>

运行效果

3.2.2、子组件向父组件传递数据

子组件向父组件传递数据,父组件修改数据

Article.vue 内容

<template>
  <div>
    {{msg}}
    <button @click="sendToParent">子组件向父组件传递数据</button>
  </div>
</template>

<script>
export default {
  props:['msg'],
  setup(props, content) {
    console.log(props.msg)

    let newName = '群芳过后西湖好,狼籍残红。飞絮濛濛。垂柳阑干尽日风'
    function sendToParent() {
      content.emit('change', newName)
    }
    return {
      sendToParent
    }
  }
}
</script>

App.vue 内容

<template>
  <div>
    <Article :msg="name" @change="changeName"></Article>
  </div>
</template>

<script>
import Article from '@/components/Article.vue' 
import {ref} from 'vue'
export default {
  components: {
    Article
  },
  setup() {
    let name = ref('渐行渐远渐无书,水阔鱼沉何处问')
    function changeName(msg) {
      name.value = msg
    }
    return {
      name,
      changeName
    }
  }
}
</script>

App.vue 中的 name 要修改,所以使用 ref 包装

运行效果

 4、setup 中使用生命周期函数

在 setup 里,生命周期钩子前面加上 “on” 来访问组件的生命周期钩子

setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们

setup 内部调用生命周期钩子

代码示例

<template>
  <div></div>
</template>

<script>
import { onBeforeMount, onMounted } from "vue"
export default {
  setup() {
    onBeforeMount(()=>{
      console.log('onBeforeMount')
    })
    onMounted(()=>{
      console.log('mouted')
    })
    return {}
  }
}
</script>

运行效果

至此完

### Vue3 Setup 语法教程 #### 使用 `setup` 方法定义响应式数据和方法 在 Vue3 中,`<script setup>` 是一种新的编写组合 API 的方式。这种方式简化了组件逻辑的书写,并且使得模板可以直接访问脚本中的所有顶层绑定。 当使用 `<script setup>` 定义组件时,在其中声明的所有变量、函数以及导入的内容都会自动暴露给模板而不需要显式的返回它们[^1]。 ```html <!-- 子组件示例 --> <template> <div>我是子组件 {{ msg }}</div> </template> <script setup> import { ref } from &#39;vue&#39; const msg = ref(&#39;hello&#39;) </script> ``` 此代码片段展示了如何利用 `<script setup>` 创建一个简单的子组件。这里创建了一个名为 `msg` 的响应式引用并初始化为字符串 `&#39;hello&#39;`。由于采用了 `setup` 语法规则,因此不必通过 `return` 显式地导出任何东西就能让其在模板中可用[^2]。 #### 组合API与Setup配合使用 除了基本的数据绑定外,还可以借助 Composition API 来实现更复杂的业务逻辑处理。例如可以引入生命周期钩子、计算属性等功能: ```javascript // 寿命周期挂钩的例子 <script setup> import { onMounted, ref } from &#39;vue&#39; let count = ref(0) onMounted(() => { console.log(`The initial count is ${count.value}.`) }) </script> ``` 上述例子说明了怎样结合寿命周期钩子(如 `onMounted`)来执行特定时刻的操作。这有助于开发者更好地管理应用的状态变化过程。 #### 响应式对象解构注意事项 需要注意的是,如果要对由 reactive 或其他类似函数产生的响应式对象进行解构,则应该使用 toRefs() 函数以保持解构后的成员仍然具有反应能力: ```javascript <script setup> import { reactive, toRefs } from &#39;vue&#39; const state = reactive({ foo: 1, bar: 2, }) // 正确做法 - 解构后仍保留响应性 const { foo, bar } = toRefs(state) </script> ``` 这样做的好处是可以确保即使是从复杂状态结构中提取出来的简单字段也能够随着源对象的变化同步更新显示。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟世君子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值