10、Vue 3 Pinia 使用实录:Pinia & bootstrap 5导航栏
嗨,我是温新
本次使用新的项目进行演示。
创建项目
1、创建项目
$ pnpm create vue@latest vue3-pinia-nav
.../share/pnpm/store/v3/tmp/dlx-33872 | +1 +
.../share/pnpm/store/v3/tmp/dlx-33872 | Progress: resolved 1, reused 1, downloaded 0, added 1, done
Vue.js - The Progressive JavaScript Framework
✔ 是否使用 TypeScript 语法? … 否 / 是
✔ 是否启用 JSX 支持? … 否 / 是
✔ 是否引入 Vue Router 进行单页面应用开发? … 否 / 是
✔ 是否引入 Pinia 用于状态管理? … 否 / 是
✔ 是否引入 Vitest 用于单元测试? … 否 / 是
✔ 是否要引入一款端到端(End to End)测试工具? › 不需要
✔ 是否引入 ESLint 用于代码质量检测? … 否 / 是
✔ 是否引入 Vue DevTools 7 扩展用于调试? (试验阶段) … 否 / 是
正在初始化项目 /home/web/vue/2024/vue3-pinia-nav...
项目初始化完成,可执行以下命令:
cd vue3-pinia-nav
pnpm install
pnpm dev
$ cd vue3-pinia-nav/
$ pnpm install
$ pnpm i bootstrap sass
2、删除文件
$ rm -rf src/assets/main.css
$ rm -rf src/views/*.vue
$ rm -rf src/components/*
- 清空
src/router/index.ts
中的内容
src/main.ts
import 'bootstrap/scss/bootstrap.scss'
import 'bootstrap/dist/js/bootstrap.min.js'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
src/App.vue
<template>
<h1>王美丽</h1>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
3、启动项目
$ pnpm dev
浏览器中访问 http://localhost:5173/
,通过效果来看,bootstrap 样式已经生效。
定义数据仓库
src/stores/user.ts
import { defineStore } from "pinia";
import { ref } from "vue";
const useUserStore = defineStore('user', () => {
const username = ref('王美丽')
const isLogin = ref(false)
const updateUserinfo = (uname:string, ulogin:boolean) => {
username.value = uname
isLogin.value = ulogin
}
return {
username,
isLogin,
updateUserinfo
}
})
export default useUserStore
创建导航模板
1、创建导航栏组件
src/components/Nav.vue
<template>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
<router-link to="/home" class="navbar-brand">自如初</router-link>
<div class="collapse navbar-collapse" id="navbarScroll">
<ul class="navbar-nav me-auto my-2 my-lg-0 navbar-nav-scroll" style="--bs-scroll-height: 100px;">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">PHP</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Linux</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
分类
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Go</a></li>
<li><a class="dropdown-item" href="#">Gin</a></li>
</ul>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item">
<router-link to="/login" class="nav-link active">登录</router-link>
</li>
<li class="nav-item">
<router-link to="/reg" class="nav-link">注册</router-link>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script setup lang="ts">
</script>
2、引入导航
src/App.vue
<template>
<Nav/>
</template>
<script setup lang="ts">
import Nav from "@/components/Nav.vue"
</script>
<style scoped>
</style>
逻辑处理
1、控制登录按钮显示
src/components/Nav.vue
<template>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
...
<ul class="navbar-nav">
<li class="nav-item" v-if="showLoginButton">
<router-link to="/login" class="nav-link active">登录</router-link>
</li>
...
</ul>
</div>
</div>
</nav>
</template>
<script setup lang="ts">
// 是否显示登录按钮
defineProps({
showLoginButton:Boolean
})
</script>
此时,不显示 登录
按钮
2、创建试图
首页视图:src/views/HomeView.vue
<template>
<h1>首页</h1>
<Nav/>
</template>
<script setup lang="ts">
import Nav from '@/components/Nav.vue';
</script>
登录视图:src/views/LoginView.vue
<template>
<h1>登录</h1>
<Nav/>
</template>
<script setup lang="ts">
import Nav from '@/components/Nav.vue';
</script>
App 渲染视图:src/App.vue
<template>
<RouterView/>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
3、创建路由
src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history:createWebHistory(),
routes:[
{
path:"/",
redirect:"/home"
},
{
path:"/home",
name:"/home",
component: () => import("@/views/HomeView.vue")
},
{
path:"/login",
name:"/login",
component: () => import("@/views/LoginView.vue")
}
]
})
export default router
4、挂在路由
src/main.ts
...
import router from './router'
const app = createApp(App)
app.use(router)
app.use(createPinia())
app.mount('#app')
5、实现登录按钮显示
src/views/HomeView.vue
<template>
<h1>首页</h1>
<!-- 绑定属性 -->
<Nav :show-login-button="true"/>
</template>
<script setup lang="ts">
import Nav from '@/components/Nav.vue';
</script>
- 访问
home
路由,可以看到导航栏显示了登录
按钮 - 访问
login
路由,登录
按钮消失
使用 Pinia
1、判断用户是否登录
src/components/Nav.vue
<template>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
<router-link to="/home" class="navbar-brand">自如初</router-link>
<div class="collapse navbar-collapse" id="navbarScroll">
...
<ul class="navbar-nav">
<li class="nav-item" v-if="showLoginButton">
<!-- 用户已登录,则显示用户名 -->
<router-link to="/login" class="nav-link active">
{{ isLogin ? username : '登录' }}
</router-link>
</li>
<li class="nav-item">
<router-link to="/reg" class="nav-link">注册</router-link>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script setup lang="ts">
import { storeToRefs } from 'pinia';
import useUserStore from '@/stores/user';
const useStore = useUserStore()
const {username, isLogin} = storeToRefs(useStore)
// 是否显示登录按钮
defineProps({
showLoginButton:Boolean
})
</script>
2、用户登录
src/views/HomeView.vue
<template>
<h1>首页</h1>
<Nav :show-login-button="true"/>
<button @click="loginHandler" class="btn btn-primary">登录</button>
</template>
<script setup lang="ts">
import Nav from '@/components/Nav.vue';
import useUserStore from '@/stores/user';
const useStore = useUserStore()
const loginHandler = () => {
useStore.updateUserinfo("王小美", true)
}
</script>
请登录后再评论