VUE3的 单文件组件 <script setup>理解与实际上手案例

发布于:2022-11-01 ⋅ 阅读:(756) ⋅ 点赞:(0)

第一次使用VUE3时,项目中使用的时兼容VUE2引入setup函数的写法,上手很快也容易理解。
直到发现element plus官方的源码展示都用了全新的单文件组件写法,意识到这个才是主流。
这篇文章记录下学习过程。

理解:

类似VUE2写法与最原始HTML脚本的结合,将Vue2的写法export default {}的代码整体暴露出去 变成 手动调用API进行封装;

<script setup>是在单文件组件 (SFC) 中使用组合式 API的编译时语法糖。相比于普通的<script>语法,它具有更多优势
1.更简洁的代码
2.能够使用纯 Typescript 声明 props 和 抛出事件,<script setup lang="ts">
3.更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
4.更好的 IDE 类型推导性能 (减少了语言服务器从代码中抽取类型的工作)。

<script setup>内的代码会被编译成组件 setup() 函数的内容。这意味着与普通的<script> 只在组件被首次引入的时候执行一次不同,script setup>中的代码会在每次组件实例被创建的时候执行。

HTML脚本

<p id="two">JavaScript 可以触发事件。</p>
<button type="button" onclick="twoFun()">点我</button>
<script>
    function twoFun()
    {
        document.getElementById("two").innerHTML="Hello JavaScript!";
    }
</script>

VUE2单文件组件

<template>
  <div>
	...
  </div>
</template>
<script>
import { AAAA } from '@/api/model'
export default {
  name: '',
  data() {return {}},
  watch: {},
  mounted() {},
  methods: {},
  ...
}
</script>

VUE3单文件组件

<script setup>
import { AAAA } from '@/api/model'
import { ref,reactive } from "vue";
const props = defineProps({
  detailData: Object
});
const showModel = ref(1)
const evaluate = reactive({A:'a'})
function myEvaluate() {
    showModel.value = 3
}
</script>
<template>
  <div>
	...
  </div>
</template>

案例

  • 当使用 <script setup> 的时候,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 导入的内容) 都能在模板中直接使用
  • 与早期语法setup()函数导入类似,可以使用ref,reactive 响应式API来创建与模板双向绑定的数据。
  • 引入子组件时,无需像VUE2语法那样需要在components: {},函数中申明。
  • 使用 defineProps() 来引入父组件绑定的数据,类似VUE2的 props 对象。
    使用 defineEmits() 来引入父组件绑定的数据,类似VUE2的 this.$emit('父组件方法名', 参数组)写法
    都是只能在 <script setup> 中使用的编译器宏。他们不需要导入
<script setup>
import DemandList from "@/components/DemandList.vue";//子组件
import { ref,reactive } from "vue";//响应式API
import {submitFeedbacEvaluate} from "@/http/index.js";//引入函数
const props = defineProps({
  detailData: Object//父组件绑定数据
});
const emit = defineEmits(["closeDrawer"]);// 传递父组建内容
const showModel = ref(1)  //创建响应式基本类型数据
const evaluate = reactive({ feedbackId:'',opinion:''})  //创建响应式引用类型数据

function toEvaluate() {
    if(props.detailData.feedbackEvaluateList.length>=5){
        ElNotification({
            title: "Error",
            message: "最多支持评价5次!",
            type: "error",
        });
        return;
    }
    showModel.value = 2
}
function myEvaluate() {showModel.value = 3}
function returnDetail() {showModel.value = 1}
function submitEvaluate() {
    evaluate.feedbackId = props.detailData.id //在模板中直接使用顶层暴露的数据与函数
    for(let key in evaluate){
        if(evaluate[key]==''){
            ElNotification({
                title: "Error",
                message: "必填内容未填写!",
                type: "error",
            });
            return;
        }
    }
    submitFeedbacEvaluate(evaluate).then((res) => {
        if(res.errCode=='00'){
            ElNotification({
                title: "Success",
                message: res.data,
                type: "success",
            });
            returnDetail();
      		handleClose();
        }
    });
}
function handleClose() {
  emit("closeDrawer");
}

</script>

<template>
  <div class="detail">
    <!-- 直接使用引入组件 直接使用顶层声明的函数与变量-->
  	<demand-list :id="detailData.id" v-if="detailData.id"/>
    <el-button @click="toEvaluate" type="primary"  v-if="detailData.feedbackEvaluateList.length==0">去评价</el-button>
    <el-button @click="myEvaluate" type="primary"  v-else>我的评价</el-button>
    <el-button @click="returnDetail" type="primary" >返回</el-button>
    <el-input clearable show-word-limit v-model="evaluate.opinion" :rows="3" type="textarea" maxlength="500"/>
    <el-button @click="submitEvaluate" type="primary">提交</el-button>
  </div>
</template>

待补全

  • 如何写promise函数
    在这里插入图片描述

  • <script setup lang="ts">写法
    在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到