Vue3 <script setup> 组合式组件的开发使用(附demo)

一、简述

因为 <script setup> 在vue3.2.0才正式转正使用,所以我现在的版本是3.3.4。

<script setup>优缺点及用法可参考Vue3 <script setup lang=“ts“> 使用指南-CSDN博客 。

下面我主要说的是<script setup>组件的开发及使用。

二、<script setup>组件的开发

用过vue的都知道,vue2  TypeScript 使用的是选项式API,vue3开发出了组合式API。vue3两个开发类型都可以使用。可参考官方文档:《TS与组合式API》 、《TS与选项式API》。

下面使用网站的导航组件为例,说明<script setup>组件的开发。

组件中使用 <script setup lang="ts">  ts 的声明可以直接使用TS中的函数,不需要引入。

需要引入的参数定义 需要使用 defineProps 定义:

<script setup lang="ts">

const props = defineProps({
  isLogin:boolean, //是否登录
  isActivity:string, //菜单选中
})


</script>

因为某些参数不必传值时, 需要默认值,则使用 withDefaults 函数 :

const props = withDefaults(
defineProps<{
    isLogin:boolean, //是否登录
    isActivity:string, //菜单选中
}>(),
{isLogin:false,isActivity:"1"} //设置默认值
);

最后使用 defineEmits 标注绑定事件

const emit = defineEmits(['goPage','goLogin']); // 要声明接收到了事件

//去到其它页面
const goPage = (obj) => {
    //调用父组件的方法并传值
    emit("goPage", obj);
};
//登录 注册 登出
const goLogin=(index)=>{
    emit("goLogin",index);
};

 三、效果

 

 四、源码

1、组件:

 

<template>
     <div class="nav-box">
        <div class="nav-logo">
            <img src="@/assets/logo.png" title="百语创投logo" alt="百语创投logo" />
        </div>
        <div class="nav-title">
            <div :class="['nt-label',isActivity == item.id?'nt-label-ac':'']" v-for="(item,index) in state.navArr" :key="index"  @click="goPage(item)">{{ item.name }}</div>
        </div>
        <div class="login-box" v-if="!isLogin">
            <div class="lb-register" @click="goLogin(1)">注册</div>
            <div class="lb-login" @click="goLogin(2)">登录</div>
        </div>
        <div class="login-box" v-else>
            <div class="lb-login" @click="goLogin(3)">我的主页</div>
            <div class="lb-register" @click="goLogin(4)">退出登录</div>
        </div>
    </div>
</template>
<script setup lang="ts">
import { ref, reactive, h, onMounted, toRefs } from "vue";

const props = withDefaults(
    defineProps<{
    isLogin:boolean, //是否登录
    isActivity:string, //菜单选中
}>(),
{isLogin:false,isActivity:"1"} //设置参数默认值
);

const emit = defineEmits(['goPage','goLogin']); // 要声明接收到了事件

const state = reactive({
    navArr:[
        {id:"1",name:'首页',path:'/'},
        {id:"2",name:'创客活动',path:'/project/activity'},
        {id:"3",name:'创客项目',path:'/project/list'},
        {id:"4",name:'项目申请',path:'/project/apply'},
    ],
});

//去到其它页面
const goPage = (obj) => {
    //调用父组件的方法并传值
    emit("goPage", obj);
};
//登录 注册 登出
const goLogin=(index)=>{
    emit("goLogin",index);
};

</script>
  
2、使用 
<template>
    <navTitle :is-login="state.isLogin" :is-activity="state.isActivityNav" @go-page="goPage" @go-login="goLogin"></navTitle>
    <div class="content-box">项目申请</div>
    <div>请提交项目申请</div>
</template>
<script setup>
import { onMounted, onUnmounted, reactive, getCurrentInstance, nextTick, defineComponent } from "vue";
import { useRouter } from 'vue-router';

const currentInstance = getCurrentInstance(); //获取main.js中挂载的实例
const { socket, api, base } = currentInstance.appContext.config.globalProperties;
const router = useRouter();

//接入组件
import navTitle from "../../components/nav/nav.vue";

const state = reactive({
    msg: '你好',
    userInfo: {},
    isLogin: true,
    isActivityNav:"4",
});

onMounted(() => {
    var user = localStorage.getItem('userInfo'); //获取缓存中的用户信息
    if (user) {
        state.isLogin = true;
    }
});

//导航标题 操作 跳转
const goPage = (value) => {
    router.push({
        path:  value.path,
        query: {}
    });

};

//小标题操作跳转
const goLogin = (value) => {
    const type = value;
    if (type == 1) { //注册
        router.push({
            path: '/register',
            query: {}
        });
    } else if (type == 2) {  //登录
        router.push({
            path: '/login',
            query: {}
        });
    } else if (type == 3) {  //个人中心
        router.push({
            path: '/user/center',
            query: {}
        });
    } else { //退出登录
        localStorage.clear();
        state.isLogin = false;
    }
};


</script>
<style scoped>
</style>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值