跳到主要内容

2 篇博文 含有标签「vue」

查看所有标签

· 阅读需 4 分钟
JaguarJack

Piniavue3 新推的状态管理,当然你也可以使用 vuex, 但是不是很建议,因为这个 plugin 就相当于 vuex5 了。

为什么使用它

引用官方文档的内容 PiniaVue 的存储库,它允许您跨组件/页面共享状态。 如果您熟悉 Composition API,您可能会认为您已经可以通过一个简单的 export const state = reactive({}). 这对于单页应用程序来说是正确的,但如果它是服务器端呈现的,会使您的应用程序暴露于安全漏洞。 但即使在小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处:

  • dev-tools 支持
    • 跟踪动作、突变的时间线
    • Store 出现在使用它们的组件中
    • time travel 和 更容易的调试
  • 热模块更换
    • 在不重新加载页面的情况下修改您的 Store
    • 在开发时保持任何现有状态
  • 插件:使用插件扩展 Pinia 功能
  • JS 用户提供适当的 TypeScript 支持或 autocompletion
  • 服务器端渲染支持

安装

yarn add pinia
# 或者使用 npm
npm install pinia

使用

找到 utils/catchadmin.ts, 全局引入

import { createPinia } from 'pinia'

protected usePinia () : CatchAdmin {
this.app.use(createPinia())

return this
}

创建 store 文件夹

mkdir src/store

// then

touch index.ts

// 保留主入口

创建模块

cd src/store && mkdir modules

创建 app Store

cd modules && mkdir app

// then

touch index.ts

内容如下

import { defineStore } from 'pinia'

const initSize = 'small'

const initLocale = 'zh'

/**
* app
*/
type app = {
size: 'small' | 'medium' | 'large',

isExpand: boolean,

locale: 'zh' | 'en',

isMobile: boolean
}

export const useAppStore = defineStore('app', {
state: () : app => ({
size: initSize,
isExpand: true,
locale: initLocale,
isMobile: false
}),

actions: {
changeSize (size: 'small' | 'medium' | 'large') {
this.size = size
},

changeLocale (locale: 'zh' | 'en') {
this.locale = locale
},

changeExpaned () {
this.isExpand = !this.isExpand
}
}
})

这里还是用的 optional api,本人体验了下 composition api 写法,似乎很麻烦,然后参考了下相关的项目的写法,都是使用的 optional api 写法。

为什么要使用

在项目中有一些状态需要在组件之间流转,例如,目前在写这个 blog 文章的时候,项目遇到的菜单「展开关闭」这个状态值,这个值需要在 header 组件,Slide 组件及其子组件之间不停的流转,就很麻烦,不仅需要 props 还需要 emit 这样的操作无疑增加了代码的复杂度以及维护的难度,使用状态管理之后,因为状态管理是响应式的,所以可以通过一个接口,就可以对状态进行操作,很方便。

找到 layout/componetns/header/index.vue

import { useAppStore } from '@/stores/modules/app'

const store = useAppStore()

const { changeExpaned } = store

就可以直接在组件中使用了 changeExpaned 方法,对应的状态也可以改变

· 阅读需 2 分钟
JaguarJack

原因

为什么要使用第三方的图标?因为 ElementPlusicon 实在是太少了,不够用。hreIcons 感觉还可以,并且可以很好的和 tailwindcss 集合,图标数量也有 230+ ,感觉能满足后台需求。所以整个项目为了 icon 统一,就去除了 ElementPlus Icon 了,统一使用 heroIcons

安装

yarn add @heroicons/vue  

使用

为了统一使用,并且为了之后的动态 icon 做铺垫,所以这里需要二次封装下。创建 src/icon/index.vue 组件。

<template>
<component :is="icon" class="ct-w-5 ct-h-5"/>
</template>

<script>
import { defineComponent } from 'vue'
import * as heroIcons from '@heroicons/vue/outline'
export default defineComponent({
name: 'icon',
props: {
name: {
type: String,
required: true
}
},
setup (props, ctx) {
let name = ''

props.name.split('-').forEach(v => {
name += v[0].toUpperCase() + v.substr(1)
})

const icon = heroIcons[name + 'Icon']

return {
icon
}
}
})
</script>

创建完成之后,为了可以全局使用,需要注册在 vue 中注册下,还是找到后台的入口 utils/catchadmin.ts

import icon from '@/components/icon/index.vue'


// 找到 registerComponents 方法,注册
protected registerComponent () : CatchAdmin {
this.app.component('icon', icon)

return this
}

注册完成之后,就可以全局使用了,例如这样

<Icon name="logout"/>

当然这个使用是有一个小小弊端,修改之后无法立即刷新图标,但是这个应该不是什么大问题,因为图标是静态的。 当然如果你不喜欢这样,也可以直接在页面中引入 heroIcons

<template>
<div>
<BeakerIcon class="h-5 w-5 text-blue-500"/>
<p>...</p>
</div>
</template>

<script>
import { BeakerIcon } from '@heroicons/vue/solid'

export default {
components: { BeakerIcon }
}
</script>