一、简述
因为 <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>