一個(gè) Vue3 項(xiàng)目的流水賬

首先這是一個(gè)出于了解 Vue3 語(yǔ)法及相關(guān)生態(tài)而搞的類似于 在簡(jiǎn)書(shū)仿簡(jiǎn)書(shū) 的項(xiàng)目爵卒。

具體而言這個(gè)項(xiàng)目是這 在簡(jiǎn)書(shū)仿簡(jiǎn)書(shū) 的基礎(chǔ)上搞的 Vue3 版本岂座。

Vue2 版本的代碼可以到 這里 查看大刊。

Vue3 版本的代碼可以到 這里 查看。這不給整個(gè)star魄揉。

在很久很久以前鞍盗,對(duì)于 Vue3 的認(rèn)識(shí):

新項(xiàng)目預(yù)覽點(diǎn)這 road.cemcoe.com


下面是無(wú)聊流水賬:

  1. 創(chuàng)建 Vue3 項(xiàng)目

Step 1. 打開(kāi) Vue 的官網(wǎng),看一看最新的腳手架的命令


npm_init_vuelatest.png

Step2. 執(zhí)行命令

npm init vue@latest

不要傻了吧唧地?zé)o腦 vue create跷究,下面是執(zhí)行操作時(shí)終端的輸出:

$ npm init vue@latest

Vue.js - The Progressive JavaScript Framework

√ Project name: ... xbook
√ Add TypeScript? ... No / Yes
√ Add JSX Support? ... No / Yes
√ Add Vue Router for Single Page Application development? ... No / Yes
√ Add Pinia for state management? ... No / Yes
√ Add Vitest for Unit Testing? ... No / Yes
√ Add an End-to-End Testing Solution? ? No
√ Add ESLint for code quality? ... No / Yes

Scaffolding project in C:\Users\cemcoe\workplace\demo\xbook...

Done. Now run:

  cd xbook
  npm install
  npm run dev


好耶姓迅,這里出現(xiàn)了一位新朋友,名為 Pinia,這貨是來(lái)狀態(tài)管理的丁存,有一說(shuō)一肩杈,用了它之后,我是一點(diǎn)也不想用 VueX 了解寝。

Step3. 跟著官網(wǎng)或者終端的提示把依賴裝一裝扩然,執(zhí)行一下啟動(dòng)命令,瞧一瞧頁(yè)面聋伦。

cd xbook
npm install
npm run dev

毫無(wú)意外地會(huì)看到這個(gè)樣子:


init.png

Step4. 管理一下項(xiàng)目

當(dāng)然夫偶,最好把項(xiàng)目用 git 給管理起來(lái),在配置好 git config 的前提下把項(xiàng)目給 init 一下

git init
  1. 瞧一眼初始化的目錄結(jié)構(gòu)

跟 Vue2 差別不是很大觉增,比較起眼的就是 vite 了兵拢,現(xiàn)如今是開(kāi)發(fā)時(shí) Vite, 打包時(shí) rollup

vite.png
  1. 刪除(替換)一下不必要的文件
  • public/favicon.ico 換成自己的
  • src/assets 刪除里面的文件
  • src/componets 清空里邊的文件
  1. 觀摩一下 APP.vue

簡(jiǎn)化一下 APP.vue

<script setup></script>

<template>
  <div class="app">
    <h2>app</h2>
  </div>
</template>

<style scoped></style>

觀摩一下 APP.vue,把 script 標(biāo)簽放在了前面逾礁,添加了 setup 語(yǔ)法糖刻肄。

  1. 再次運(yùn)行看一下有沒(méi)有錯(cuò)誤
npm run dev

大概率會(huì)出現(xiàn)諸如文件不存在的錯(cuò)誤硝拧,按照提示改一改就好句葵。

  1. 初始化 css

這里用到了 normalize.css恼除,按照官網(wǎng)一把梭安裝導(dǎo)入完事。

  1. 整理項(xiàng)目目錄結(jié)構(gòu)

主要還是和 Vue2 的保持一致

  • assets 靜態(tài)文件植捎,imgs css
  • components 組件目錄
  • hooks 封裝的 hooks
  • router 路由相關(guān)
  • service/modules 分模塊管理請(qǐng)求
  • service/request 封裝的請(qǐng)求函數(shù)
  • store/modules 分模塊管理狀態(tài)
  • utils 工具函數(shù)
  • views 視圖組件
  1. 選用一個(gè)得力的組件庫(kù)

這是一個(gè)移動(dòng)端的項(xiàng)目衙解,沒(méi)得選就是 Vant 了,打開(kāi)官網(wǎng)焰枢,自己寫(xiě)著玩當(dāng)然是選用最新版的啦蚓峦。

vant.png
npm i vant

執(zhí)行之后你會(huì)發(fā)現(xiàn),額济锄,不對(duì)勁暑椰,這版本不是 4 呀。

vant-version.png

去官網(wǎng)確定一下命令荐绝,你發(fā)現(xiàn)一汽,額,我搞得是對(duì)的呀低滩。

vant-install-version4.png

這個(gè)時(shí)候想裝上 vant@4 咋搞召夹。

明顯的是這玩意還沒(méi)把默認(rèn)版本個(gè)升到 4,但是文檔 4 對(duì)應(yīng)的安裝命令沒(méi)改就很難受恕沫,這里就需要自己去找一找了监憎。

  1. 安裝非正式版的 Vant4

既然官方文檔還沒(méi)更新,那就到 npm 上去看一下版本號(hào)婶溯,自己裝一下鲸阔。

vant-version4.png
npm i vant@4.0.0-rc.6

等安裝完成后再打開(kāi) package.json 瞧一下 vant 的版本偷霉,欸,不錯(cuò)褐筛,用上了 vant 的新 rc 版本类少。

"dependencies": {
  "pinia": "^2.0.23",
  "vant": "^4.0.0-rc.6",
  "vue": "^3.2.41",
  "vue-router": "^4.1.5"
},

切記不要裝 alpha 版本,除非渔扎,你真的想踩坑瞒滴,你可能會(huì)遇到組件名并沒(méi)有導(dǎo)出的狀況,你問(wèn)我怎么知道的赞警?

當(dāng)然是我試了 alpha 版本,然后組件都導(dǎo)不進(jìn)虏两。切記愧旦,新也要適度。

  1. 配置組件庫(kù)

回到 Vant 的文檔中定罢,按需導(dǎo)入配一下笤虫,沒(méi)什么東西,照著文檔配就完事了祖凫。

import-on-demand.png

配置好之后最好自己測(cè)試一下琼蚯。

別忘了文檔中的第四步,函數(shù)組件的樣式記得手動(dòng)導(dǎo)入一下惠况。

// https://vant-ui.github.io/vant/v4/#/en-US/quickstart#4.-style-of-function-components
Some components of Vant are provided as function, including Toast, Dialog, Notify and ImagePreview. When using function components, unplugin-vue-components can not auto import the component style, so we need to import style manually.
  1. 生成主要的路由 views

到 src/views 目錄下創(chuàng)建如下文件遭庶,并填充基本結(jié)構(gòu)

  • home/home.vue
  • following/following.vue
  • profile/profile.vue
  1. 為主要的路由 views 配置路由

打開(kāi) router/index.js,照葫蘆畫(huà)瓢稠屠,搞就完事了峦睡。

我更喜歡把 tabbar 相關(guān)的路由放在一個(gè)單獨(dú)的文件中,比如 router/tabbar-routes.js权埠。

這么做的目的在于榨了,對(duì)于 tabbar 數(shù)據(jù)進(jìn)行統(tǒng)一的管理,同時(shí) meta 中會(huì)存儲(chǔ)圖片等信息攘蔽。

// 其中一個(gè)路由對(duì)象
{
  path: "/",
  component: () => import("@/views/home/home.vue"),
  meta: {
    text: "首頁(yè)",
    image: "tabbar/home.svg",
    imageActive: "tabbar/home_active.svg",
  },
},
  1. 配置 tabbar

到 components 下創(chuàng)建 tab-bar/tab-bar.vue
這是就體現(xiàn)了將 router/tabbar-routes.js 抽離并導(dǎo)出的好處了龙屉。

直接把路由信息導(dǎo)入

import { tabbarRoutes } from "@/router/tabbar-routes";

就很棒,不用再搞一份數(shù)據(jù)了满俗,到 meta 中去拿就好了转捕。

剩下的步驟就很簡(jiǎn)單了,就是使用組件庫(kù)漫雷,具體看 vant 的文檔就行了瓜富。

中場(chǎng)休息

現(xiàn)在的大致進(jìn)度應(yīng)是,應(yīng)用底部有一個(gè) tabbar降盹,點(diǎn)擊會(huì)切換對(duì)應(yīng)的圖片以及顏色且相關(guān)的路由也會(huì)一并切換与柑。


  1. 發(fā)送網(wǎng)絡(luò)請(qǐng)求

別的都不說(shuō)谤辜,先把數(shù)據(jù)拿到,可供選擇的方案

  • fetch
  • axios

先發(fā)一個(gè)請(qǐng)求試一試

<script setup>
fetch("https://api.cemcoe.com/v1/posts?page=1&per_page=10", {})
  .then((res) => res.json())
  .then((res) => {
    const { status, data } = res;
    if (status === 200) {
      console.log(data.post);
    }
  });
</script>

再將結(jié)果保存到變量中价捧,以便渲染到頁(yè)面上去丑念。

簡(jiǎn)單定義一個(gè)數(shù)組,將拿到的數(shù)據(jù)給 push 上去结蟋。

<script setup>
let postList = [];
fetch("https://api.cemcoe.com/v1/posts?page=1&per_page=10", {})
  .then((res) => res.json())
  .then((res) => {
    const { status, data } = res;
    if (status === 200) {
      console.log(data.post);
      // postList = data.post;

      postList.push(...data.post);
    }
  });
</script>

嘗試將 postList 渲染到頁(yè)面上脯倚,模板部分和 Vue2 沒(méi)差,這里就不展示了嵌屎。

不出意外 postList 新數(shù)據(jù)是不會(huì)展示到頁(yè)面上的推正。

那簡(jiǎn)單呀,上 ref宝惰,于是又有了下面的代碼:

<script setup>
import { ref } from "vue";
let postList = ref([]);
fetch("https://api.cemcoe.com/v1/posts?page=1&per_page=10", {})
  .then((res) => res.json())
  .then((res) => {
    const { status, data } = res;
    if (status === 200) {
      console.log(data.post);
      // postList = data.post;

      postList.push(...data.post);
    }
  });
</script>

小腦袋瓜轉(zhuǎn)的真快植榕,可還是不行,額尼夺,這里少了一個(gè) value尊残。

于是又又有了下面的代碼:

<script setup>
import { ref } from "vue";
let postList = ref([]);
fetch("https://api.cemcoe.com/v1/posts?page=1&per_page=10", {})
  .then((res) => res.json())
  .then((res) => {
    const { status, data } = res;
    if (status === 200) {
      postList.value.push(...data.post);
    }
  });
</script>

這時(shí)的代碼大抵是可用來(lái),頁(yè)面上展示了列表了( ?? ω ?? )y

  1. ref 是個(gè)什么東東

啥也不說(shuō)淤堵,無(wú)腦打開(kāi)官方文檔瞧一瞧寝衫,直奔 API

ref.png
// 從文檔上cv來(lái)的
function ref<T>(value: T): Ref<UnwrapRef<T>>;

interface Ref<T> {
  value: T;
}

臨時(shí)抱一下 TypeScript 的腳。

function ref<T>(value: T): Ref<UnwrapRef<T>>;

哇拐邪,有點(diǎn)復(fù)雜的兄弟慰毅。簡(jiǎn)化一下先,比如將尖括號(hào)去掉庙睡,基本的類型注解還是瞧的懂的吧事富。

function ref(value): Ref;

TypeScript 的一大好處就是代碼即文檔,上面代碼的意思是:

有個(gè)名為 ref 的函數(shù)乘陪,你給它一個(gè) value统台,它給你一個(gè)返回值,這個(gè)返回值的類型是 Ref

那么 Ref 有是個(gè)什么鬼啡邑,不要著急贱勃,看下一段代碼咯

interface Ref<T> {
  value: T;
}

interface 是定義 interface 的關(guān)鍵字(好像什么都沒(méi)說(shuō)),不重要谤逼,重要是可以用來(lái)干什么贵扰?
這里還有一個(gè) T 也是比較特殊的,這玩意和尖括號(hào)一起可以稱為泛型流部,名字很頂呀戚绕,簡(jiǎn)單來(lái)說(shuō)就是類型變量,可以在使用時(shí)聲明具體的類型枝冀。

下面寫(xiě)幾個(gè)符合條件的變量:

interface Ref<T> {
  value: T;
}

const ref1: Ref<number> = {
  value: 1,
};

const ref2: Ref<string> = {
  value: "hello",
};

很清楚明白舞丛,interface 約束了一個(gè)對(duì)象耘子,而泛型 T 又約束了 value 的類型。

下面再來(lái)匯總一下代碼

// 從文檔上cv來(lái)的
function ref<T>(value: T): Ref<UnwrapRef<T>>;

interface Ref<T> {
  value: T;
}

翻譯一下:

ref 是一個(gè)函數(shù)
函數(shù)的形參 value 在使用時(shí)指定類型T
函數(shù)的返回值為一個(gè)由 Ref interface 約束的對(duì)象
返回值對(duì)象有一個(gè) key 名為value
而 value 的值則是由另一個(gè) UnwrapRef 以及T決定球切。

那么這個(gè) UnwrapRef 又是啥谷誓?文檔上我沒(méi)找到,瞧一眼源碼:

// ref.ts

export type UnwrapRef<T> = T extends ShallowRef<infer V>
  ? V
  : T extends Ref<infer V>
  ? UnwrapRefSimple<V>
  : UnwrapRefSimple<T>;

這里又多了一些類型吨凑,有空再接著捋下去捍歪。

  1. 抽一下請(qǐng)求函數(shù)
<script setup>
import { ref } from "vue";
let postList = ref([]);
fetch("https://api.cemcoe.com/v1/posts?page=1&per_page=10", {})
  .then((res) => res.json())
  .then((res) => {
    const { status, data } = res;
    if (status === 200) {
      postList.value.push(...data.post);
    }
  });
</script>

上面的代碼肯定是可以實(shí)現(xiàn)功能的,但肯定是不能這么寫(xiě)的鸵钝。至少也要把請(qǐng)求地址給搞出去的糙臼。

先簡(jiǎn)單搞搞,搞成一個(gè)請(qǐng)求函數(shù):

<script setup>
import { ref } from "vue";
let postList = ref([]);

const http = (url, options = {}) => {
  const BASE_URL = "https://api.cemcoe.com/v1";
  // 1. 拼湊完整的請(qǐng)求地址
  const resource = BASE_URL + url;
  // 2. 整合options
  options = {
    method: "GET", // 默認(rèn)是GET請(qǐng)求
    headers: {},
    mode: "cors",
    credentials: "omit",
    cache: "default",
    ...options,
  };


  fetch(resource, options)
    .then((res) => res.json())
    .then((res) => {
      const { status, data } = res;
      if (status === 200) {
        postList.value.push(...data.post);
      }
    });
};

http("/posts?page=1&per_page=10");
</script>

上面的代碼泥恩商,還有一個(gè)問(wèn)題弓摘,那就是最終的請(qǐng)求結(jié)果需要到調(diào)用方,按照單一職責(zé)的原則痕届,數(shù)據(jù)請(qǐng)求函數(shù)中也不應(yīng)該對(duì)外部作用域的變量進(jìn)行修改,ok末患,接著改研叫。

<script setup>
import { ref } from "vue";
let postList = ref([]);

const http = (url, options = {}) => {
  const BASE_URL = "https://api.cemcoe.com/v1";
  // 1. 拼湊完整的請(qǐng)求地址
  const resource = BASE_URL + url;
  // 2. 整合options
  options = {
    method: "GET", // 默認(rèn)是GET請(qǐng)求
    headers: {},
    mode: "cors",
    credentials: "omit",
    cache: "default",
    ...options,
  };

  return new Promise((resolve, reject) => {
    fetch(resource, options)
      .then((res) => {
        return res.json();
      })

      .then((res) => {
        resolve(res);
      });
  });
};

http("/posts?page=1&per_page=10").then((res) => {
  const { status, data } = res;
  if (status === 200) {
    postList.value.push(...data.post);
  }
});
</script>

這么改吧改吧已經(jīng)有了一些可用的樣子了,下面要做的就是請(qǐng)求攔截和響應(yīng)攔截以及一些錯(cuò)誤處理璧针,這里就不展開(kāi)了嚷炉,畢竟,每個(gè)公司的接口規(guī)范也不盡相同探橱。

  1. 各回各家

上面的代碼呢最好是分到不同的文件里申屹。怎么起名看著來(lái)。

div.png

圖中白色的抽離下面說(shuō)隧膏,先將其忽略哗讥。

看看一下現(xiàn)在的數(shù)據(jù)流向

用戶訪問(wèn) Home 頁(yè)面,Home 頁(yè)面執(zhí)行請(qǐng)求函數(shù)胞枕,而請(qǐng)求函數(shù)定義在 service/modules/home.js杆煞,而該文件會(huì)引用封裝的請(qǐng)求函數(shù) http(名字無(wú)所謂,愛(ài)叫啥叫啥)腐泻,而該請(qǐng)求函數(shù)則是對(duì) fetch 的封裝决乎,當(dāng)然了,不用 fetch派桩,用 axios 也可以构诚。

用張圖來(lái)表示一下:

data.png

這個(gè)搞的好處是什么呢?

想一下其實(shí)網(wǎng)絡(luò)請(qǐng)求是和 Vue 這個(gè)框架無(wú)關(guān)的铆惑,按照上面的方式范嘱,如果要將原先的項(xiàng)目升級(jí)到 Vue3 的話送膳,或者換成 React,其實(shí)只有第一部分需要改彤侍。而后面的兩部分是不用動(dòng)的肠缨。

而如果把第一部分和第二部分代碼放到 views 文件中,那改起來(lái)可就麻煩了盏阶。

  1. 太大了晒奕,來(lái)點(diǎn)組件化

隨著代碼不斷堆下去,Home.vue 文件會(huì)越來(lái)越大名斟。

不可避免地要使用一下組件化脑慧。

組件化有哪些知識(shí)泥?

實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)砰盐。

定義 PostList 組件闷袒,接收拿到的數(shù)據(jù),渲染列表岩梳。

這里就涉及到了組件間的數(shù)據(jù)傳遞囊骤。

當(dāng)然可以使用 props 來(lái)進(jìn)行,比如:

// Home.vue
<PostList :postList="postList">
// PostList.vue
const props = defineProps({
  postList: {
    type: Array,
    // 對(duì)象或者數(shù)組應(yīng)當(dāng)用工廠函數(shù)返回冀值。
    // 工廠函數(shù)會(huì)收到組件所接收的原始 props
    // 作為參數(shù)
    default(rawProps) {
      return [];
    },
  },
});

組件化以后的 Home.vue 文件也物,其實(shí)還是有點(diǎn)邏輯多的。

// Home.vue

// 網(wǎng)絡(luò)請(qǐng)求拿值的邏輯
// 網(wǎng)絡(luò)請(qǐng)求拿值的邏輯
// 網(wǎng)絡(luò)請(qǐng)求拿值的邏輯
// 網(wǎng)絡(luò)請(qǐng)求拿值的邏輯
// 網(wǎng)絡(luò)請(qǐng)求拿值的邏輯
// 網(wǎng)絡(luò)請(qǐng)求拿值的邏輯



<PostList :postList="postList">
<PostList :postList="postList">
<PostList :postList="postList">
<PostList :postList="postList">
<PostList :postList="postList">
<PostList :postList="postList">
<PostList :postList="postList">

我不是閑得慌列疗,把東西復(fù)制幾下滑蚯。

這里假設(shè)每一個(gè) PostList 組件是不同的,網(wǎng)絡(luò)請(qǐng)求邏輯也是不同的抵栈,而且 props 可能不止一個(gè)告材,可能還有事件的傳遞。

網(wǎng)絡(luò)請(qǐng)求還不是簡(jiǎn)單的操作古劲,一般都相對(duì)復(fù)雜斥赋,這么多的邏輯放在 Home.vue 文件中也不是很好。

  1. 結(jié)構(gòu)行為和樣式分離产艾?

前端有個(gè)東西灿渴,叫做結(jié)構(gòu)行為樣式相分離。

Vue 表面上還是這種分離的寫(xiě)法胰舆,三大塊分著寫(xiě)骚露。

React 干脆就把這仨貨攪和在一起。

這些框架把 DOM 操作給隱藏缚窿,將命令式編程變成了聲明式編程棘幸。

聲明式編程核心是什么?

當(dāng)然就以聲明為核心咯倦零,而聲明误续,它其實(shí)可以有另外一個(gè)名字吨悍,叫做狀態(tài)。

于是這種分離的思想大抵還是在的吧蹋嵌,自由過(guò)主角不再是 HTML CSS JS育瓜。

。栽烂。躏仇。

俺也不知。

  1. 上狀態(tài)

既然 Home.vue 文件中有太多的狀態(tài)腺办,那不妨將狀態(tài)都交給一個(gè)專門(mén)管理狀態(tài)的伙計(jì)吧焰手。

這個(gè)伙計(jì)現(xiàn)在是 Pinia,一個(gè)新歡怀喉。

Pinia 在使用上要比 Vuex 簡(jiǎn)單多了书妻,Vuex 的分模塊太難用了。

而在 Pinia 上躬拢,可以創(chuàng)建多個(gè) store躲履,但單例 store 好還是這種好泥?

我目前還沒(méi)有太多的體會(huì)聊闯。

ok崇呵,下面將 Home.vue 中的狀態(tài)給搞到 store 了。

不多說(shuō)馅袁,打開(kāi) Pinia 的官網(wǎng),瞧一眼荒辕。

// 從官網(wǎng)cv來(lái)的汗销。
export const useCounterStore = defineStore("counter", () => {
  const count = ref(0);
  function increment() {
    count.value++;
  }

  return { count, increment };
});

你說(shuō)這有啥學(xué)的?有點(diǎn) React 那味道了抵窒。沒(méi)有引入多余的概念弛针,什么 state,什么 mutation李皇,什么 getter削茁,什么不能直接改值?

Vue 好用是好用掉房,但引如了太多的概念茧跋,而這里最突出的就是指令,你不知道那個(gè)指令卓囚,那不好意思瘾杭,你就不知道如何實(shí)現(xiàn)某類功能。

而 Pinia 可太爽了哪亿,沒(méi)有引入多余的概念粥烁,全都是以往的概念贤笆。

當(dāng)然了,如果你(比如我)還是想用類似 Vuex 的語(yǔ)法讨阻,Pinia 也是支持的芥永。

// store home.js
import { defineStore } from "pinia";
import { getHomePostList } from "@/service/modules/home";

export const useHomeStore = defineStore("homeStore", {
  state: () => {
    return {
      recommendPostList: [],
      page: 1,
      per_page: 10,
    };
  },
  actions: {
    async fetchHomePostList() {
      const res = await getHomePostList(this.page, this.per_page);
      this.recommendPostList.push(...res.data.post);
      this.page++;
    },
  },
});

這里一些人可能會(huì)有種看法埋涧,那就是狀態(tài)管理,只管理全局狀態(tài)飞袋。頁(yè)面狀態(tài)就交給頁(yè)面好了。

這也是一種做法巧鸭,但其實(shí)現(xiàn)在的 Pinia 支持多個(gè) store,分模塊相對(duì)也比較簡(jiǎn)單纲仍,頁(yè)面中的狀態(tài)交給它也是沒(méi)什么問(wèn)題贸毕。

但頁(yè)面級(jí)別的狀態(tài)交給 Pinia,相較于交給頁(yè)面管理這里其實(shí)是需要多做一件事情的明棍。

那就是。摊腋。。

當(dāng)把狀態(tài)放到頁(yè)面里兴蒸,傳數(shù)據(jù)是有點(diǎn)麻煩视粮,頁(yè)面銷(xiāo)毀,狀態(tài)就沒(méi)了橙凳。這其實(shí)也是有好處的蕾殴。

現(xiàn)在想象一下文章詳情頁(yè)的數(shù)據(jù)交給 Pinia,會(huì)發(fā)生什么岛啸?

用戶點(diǎn)擊文章 A钓觉,看到文章 A,但當(dāng)用戶回到文章列表頁(yè)在點(diǎn)擊文章 B坚踩,此時(shí)頁(yè)面為先展示文章 A 的內(nèi)容议谷,等到文章 B 的數(shù)據(jù)拿到后才會(huì)展示文章 B 的內(nèi)容。

所以,頁(yè)面級(jí)別的狀態(tài)卧晓,交給 Pinia 管理時(shí)芬首,別忘了初始化。

這里其實(shí)就像將狀態(tài)的作用域提了一層逼裆。

究竟采用哪種方式來(lái)管理郁稍,看取舍把。存到頁(yè)面使用以及管理上不是很方便胜宇,但不用擔(dān)心初始化耀怜,當(dāng)然了,全局狀態(tài)交給 Pinia 就不用選擇困難了桐愉。

  1. 更新下數(shù)據(jù)請(qǐng)求的步驟

未完财破,不續(xù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市从诲,隨后出現(xiàn)的幾起案子左痢,更是在濱河造成了極大的恐慌,老刑警劉巖系洛,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俊性,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡描扯,警方通過(guò)查閱死者的電腦和手機(jī)定页,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)典徊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)卒落,“玉大人,你說(shuō)我怎么就攤上這事屎飘∏展海” “怎么了押桃?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵唱凯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我卷雕,道長(zhǎng)漫雕,這世上最難降的妖魔是什么浸间? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任魁蒜,我火速辦了婚禮梅惯,結(jié)果婚禮上铣减,老公的妹妹穿的比我還像新娘葫哗。我一直安慰自己球涛,他們只是感情好亿扁,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布襟己。 她就那樣靜靜地躺著牍陌,像睡著了一般毒涧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上滑频,一...
    開(kāi)封第一講書(shū)人閱讀 48,954評(píng)論 1 283
  • 那天误趴,我揣著相機(jī)與錄音凉当,去河邊找鬼看杭。 笑死楼雹,一個(gè)胖子當(dāng)著我的面吹牛尖阔,可吹牛的內(nèi)容都是我干的介却。 我是一名探鬼主播齿坷,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼永淌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼遂蛀!你這毒婦竟也來(lái)了李滴?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤裕坊,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后周瞎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體声诸,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡彼乌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年灶挟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了毒租。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片墅垮。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡算色,死狀恐怖剃允,靈堂內(nèi)的尸體忽然破棺而出斥废,到底是詐尸還是另有隱情,我是刑警寧澤捧灰,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布毛俏,位于F島的核電站煌寇,受9級(jí)特大地震影響阀溶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜永品,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一鼎姐、第九天 我趴在偏房一處隱蔽的房頂上張望炕桨。 院中可真熱鬧谋作,春花似錦乎芳、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)友扰。三九已至村怪,卻和暖如春甚负,著一層夾襖步出監(jiān)牢的瞬間审残,已是汗流浹背搅轿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工璧坟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人循衰。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓会钝,卻偏偏與公主長(zhǎng)得像迁酸,于是被迫代替她去往敵國(guó)和親奸鬓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子串远,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容