10、Vue 3 Pinia 使用实录:Pinia & bootstrap 5导航栏

作者: 温新

图书: 【Vue 3 Pinia 使用实录】

阅读: 301

时间: 2024-11-10 17:09:59

嗨,我是温新

本次使用新的项目进行演示。

创建项目

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>
请登录后再评论