Pinia 状态管理器 菠萝:Setup Store风格

Pinia介绍:

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。

Pinia 大小只有 1kb 左右,超轻量级,你甚至可能忘记它的存在!

相比 Vuex,Pinia 的优点:

  • 更贴合 Vue 3 的 Composition API 风格,学习成本更低
  • 不需要像Vuex中要区分 Mutation 和 Action,Pinia统一使用 Actions 操作状态
  • 支持 TypeScript,可以充分利用 TS 的静态类型系统
  • 模块化管理 States, 每个模块是一个 Store
  • 直观的 Devtools,可以看到每个 State 的变化

安装:

npm install pinia

# 或者

yarn add pinia

案列:

/src/router/index.js 路由器

import { createRouter, createWebHashHistory,createWebHistory } from "vue-router"; //导入vue-router路由模块,createWebHashHistor函数
//import Home from "../views/Home.vue" //异步加载的组件,这里不需要
//import List from "../views/List.vue" //异步加载的组件,这里不需要进行导入,所以要注释掉

const routes = [
    {
        path: "/",  //路径:        
        redirect: {
            name: "ListA" //重定向到路由名称为mylist的路由中,这样当浏览器输入的是:http://localhost:5173/ 则会重定向跳转到 http://localhost:5173/list
        }
    },
    {
        path: "/lista",  //路径
        //当路由被触发时,该组件才会被异步加载,举列:打开页面就不会加载所有的组件,而是根据当前页面需要的组件进行异步加载
        //这样可以减少初始加载时间,提升用户体验,同时也节省了不必要的资源消耗。
        name:"ListA",
        component: () => import("../views/ListA.vue")

    },
    {
        path: "/listb",  //路径
        //当路由被触发时,该组件才会被异步加载,举列:打开页面就不会加载所有的组件,而是根据当前页面需要的组件进行异步加载
        //这样可以减少初始加载时间,提升用户体验,同时也节省了不必要的资源消耗。
        name:"ListB",
        component: () => import("../views/ListB.vue")

    }  
]

//创建路由对象
const router = createRouter({
    //history:createWebHashHistory()   这种方式是按照hash路由模式来路由导航,这种路由模式的url地址会存在 /#/ 样式是:http://localhost:5173/#/list
    history: createWebHistory(),     //这种方式基于浏览器 history API 的路由模式,url的样式是:http://localhost:5173/list
    routes, //routes:routes的缩写

})

export default router //导出router路由对象//导出router路由对象

Pinia状态管理器:模块

/src/store/useListAStore.js  ListA.vue组件“单独”使用的状态管理器模块

这里的“单独”的意思是:此模块一般情况下用在ListA.vue组件中,但是其他组件需要此模块的数据共享也可以引入使用的。比如我们的App.vue也用了useListAStore.js这个模块中的数据

/*
    js文件的命名建议:use+组件名称+Store  举列:用于ListA组件的store 我的取名就是 useListAStore.js
*/
 
import { defineStore } from 'pinia'
import axios from 'axios'
import { ref, onMounted, computed } from 'vue'
 
// Setup Store风格案列演示:如下
 
//第一个参数是唯一的storeId,注意别与其它模块的storeId重名(其实这个storeId我们开发人员一般用不到)
//第二个参数是一个匿名函数
const useListAStore = defineStore("ListAStoreId", () => {
    // Setup Store风格写法:在defineStore第二个参数中用ref包装的对象,就是 Option Store风格中的 state
    const obj = ref({
        name: 'Eduardo',
        age: 20,
        email: '[email protected]',
        datalist: [],
    });
 
    // Setup Store风格写法:在defineStore的第二个参数中 申明的函数,就是 Option Store风格中的 actions
    const getDataList = async () => {
        const result = await axios({
            url: "https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=7069698",
            headers: {
                'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16992764191480200349024257"}',
                'X-Host': 'mall.film-ticket.film.list'
            }
        })
        obj.value.datalist = result.data.data.films
 
    }
    const changeName = (newname) => {
        obj.value.name = newname;
    }
 
    // Setup Store风格写法:在defineStore的第二个参数中 计算属性computed,就是 Option Store风格中的 getters
    const filterDataList = computed(() => {
        //返回的是匿名函数
        return (keyword) => {
            return obj.value.datalist.filter(item => item.name.includes(keyword))
        }
    })

    //注意:此处需要根据业务需要:返回你的数据对象,函数,计算属性
    return {
        obj,
        getDataList,
        changeName,
        filterDataList
    }
})
 
export default useListAStore //导出
 

/src/store/useListBStore.js    ListB.vue组件“单独”使用的状态管理器模块

这里的“单独”的意思是:此模块一般情况下用在ListB.vue组件中,但是其它组件需要此模块的数据共享也可以引入使用的

/*
    js文件的命名建议:use+组件名称+Store  举列:用于ListA组件的store 我的取名就是 useListAStore.js
*/

import { defineStore } from 'pinia'
import axios from 'axios'
import { computed, ref } from 'vue'

// Setup Store风格案列演示

//第一个参数是唯一的storeId,注意别与其它模块的storeId重名(其实这个storeId我们开发人员一般用不到)
//第二个参数是一个匿名函数
const useListBStore = defineStore("ListBStoreId", () => {

    // Setup Store风格写法:在defineStore第二个参数中用ref包装的对象,就是 Option Store风格中的 state
    const name = ref("张三");
    const datalist = ref([]);

    // Setup Store风格写法:在defineStore的第二个参数中 申明的函数,就是 Option Store风格中的 actions
    const getDataList = async () => {
        const result = await axios({
            url: "https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3777796",
            headers: {
                'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16992764191480200349024257","bc":"110100"}',
                'X-Host': 'mall.film-ticket.cinema.list'
            }
        });
        datalist.value = result.data.data.cinemas;
    };

    // Setup Store风格写法:在defineStore的第二个参数中 计算属性computed,就是 Option Store风格中的 getters
    const filterDataList = computed(() => {
        return (type) => {
            return datalist.value.filter(item => item.eTicketFlag == type)
        }
    })

    // 注意:此处需要根据业务需要:返回你的数据对象,函数,计算属性
    return {
        name,
        datalist,
        getDataList,
        filterDataList,
    }
})

export default useListBStore //导出

注册:路由器 和 状态管理器

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'


import router from "../src/router/index.js" //导入状态管理器js 
import store from "../src/store/index.js" //导入状态管理器js 

import { createPinia } from 'pinia' //导入状态管理器js 
const pinia = createPinia();

//在Pinia中的Setup Store风格中 不支持$reset() 状态重置。所以我们可以写一个扩展方法,可以实现Option Store风格中的store.$reset功能
pinia.use(({ store }) => {
    const initialState = JSON.parse(JSON.stringify(store.$state));
    store.$reset = () => {
        store.$patch(initialState);
    }
})

var app = createApp(App)
app.use(router);
app.use(pinia); //注册pinia状态管理器 菠萝

app.use(store)  //注册vuex插件:状态管理器

app.mount("#app")

使用:

ListA.vue组件:电影列表



ListB.vue组件:影院列表


App.vue根组件



效果图

Pinia 状态管理器 菠萝:Setup Store风格_第1张图片

Pinia 状态管理器 菠萝:Setup Store风格_第2张图片

你可能感兴趣的:(Vue,vue.js,javascript,前端)