vuex和pinia

master
barney 2 years ago
parent 6e0f4107f1
commit a36de53202
  1. 3
      .gitignore
  2. 3
      Vite-Vue-tutorial/package.json
  3. 4
      Vite-Vue-tutorial/src/.prettierrc
  4. 4
      Vite-Vue-tutorial/src/hooks/useCategories.js
  5. 12
      Vite-Vue-tutorial/src/hooks/useProducts.js
  6. 2
      Vite-Vue-tutorial/src/services/banners.js
  7. 2
      Vite-Vue-tutorial/src/services/categories.js
  8. 8
      Vite-Vue-tutorial/src/services/products.js
  9. 36
      Vite-Vue-tutorial/src/utils/request.js
  10. 9
      Vite-Vue-tutorial/src/utils/tools.js
  11. 6
      Vite-Vue-tutorial/src/views/Detail.vue
  12. 10
      Vite-Vue-tutorial/src/views/Home.vue
  13. 24
      pinia-pre/.gitignore
  14. 3
      pinia-pre/.vscode/extensions.json
  15. 16
      pinia-pre/README.md
  16. 13
      pinia-pre/index.html
  17. 1492
      pinia-pre/package-lock.json
  18. 21
      pinia-pre/package.json
  19. 1
      pinia-pre/public/vite.svg
  20. 40
      pinia-pre/src/App.vue
  21. 1
      pinia-pre/src/assets/vue.svg
  22. 12
      pinia-pre/src/components/HelloWorld.vue
  23. 8
      pinia-pre/src/main.ts
  24. 47
      pinia-pre/src/stores/counter.ts
  25. 0
      pinia-pre/src/style.css
  26. 7
      pinia-pre/src/vite-env.d.ts
  27. 18
      pinia-pre/tsconfig.json
  28. 9
      pinia-pre/tsconfig.node.json
  29. 7
      pinia-pre/vite.config.ts
  30. 4
      vite-ts-project/src/views/List.vue
  31. 6
      vite-ts-project/src/views/Login.vue
  32. 24
      vuex-app/.gitignore
  33. 3
      vuex-app/.vscode/extensions.json
  34. 7
      vuex-app/README.md
  35. 13
      vuex-app/index.html
  36. 1355
      vuex-app/package-lock.json
  37. 21
      vuex-app/package.json
  38. 1
      vuex-app/public/vite.svg
  39. 26
      vuex-app/src/App.vue
  40. 1
      vuex-app/src/assets/vue.svg
  41. 5
      vuex-app/src/components/HelloWorld.vue
  42. 7
      vuex-app/src/main.js
  43. 20
      vuex-app/src/store/index.js
  44. 90
      vuex-app/src/style.css
  45. 7
      vuex-app/vite.config.js

3
.gitignore vendored

@ -1,3 +1,6 @@
# vscode-workspace
*.code-workspace
# Logs
logs
*.log

@ -6,7 +6,8 @@
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
"preview": "vite preview",
"format": "prettier --write ./**/*.{html,vue,ts,js,json}"
},
"dependencies": {
"axios": "^0.27.2",

@ -1,4 +1,6 @@
{
"singleQuote": false,
"semi": true
"semi": true,
"tabWidth": 4,
"useTabs": true
}

@ -8,10 +8,10 @@ import { ref } from "vue";
export const useCategories = () => {
const categories = ref([]);
loadCategoriesAPI().then(res => {
loadCategoriesAPI().then((res) => {
categories.value = res.data;
});
return {
categories,
}
};
};

@ -1,4 +1,4 @@
import { loadProductAPI } from '../services/products';
import { loadProductAPI } from "../services/products";
import { ref } from "vue";
/**
@ -7,8 +7,7 @@ import { ref } from "vue";
* @returns
*/
export const useProducts = (categoryId='') => {
export const useProducts = (categoryId = "") => {
const page = ref(1); // 当前页码
const loading = ref(false); // 是否在加载中
const finished = ref(false); // 是否加载完成
@ -20,7 +19,7 @@ export const useProducts = (categoryId='') => {
* @param {*} needReset 是否需要重置products
* @param {*} categoryId 分类id
*/
const onLoad = (needReset=false,categoryId='') => {
const onLoad = (needReset = false, categoryId = "") => {
if (needReset) {
// 重置一些参数
finished.value = false;
@ -28,7 +27,7 @@ export const useProducts = (categoryId='') => {
page.value = 1;
}
// 分类id不为空才需要修改
if (categoryId !=='' ) {
if (categoryId !== "") {
currentCategoryId.value = categoryId;
}
loading.value = true; // 开始加载
@ -48,6 +47,5 @@ export const useProducts = (categoryId='') => {
products,
currentCategoryId,
onLoad,
}
};
};

@ -4,4 +4,4 @@ import { get } from "../utils/request";
* 获取轮播图
* @returns
*/
export const loadBannersAPI = () => get('/api/v1/banners');
export const loadBannersAPI = () => get("/api/v1/banners");

@ -4,4 +4,4 @@ import { get } from "../utils/request";
* 返回所有商品分类
* @returns
*/
export const loadCategoriesAPI = () => get('api/v1/product_categories');
export const loadCategoriesAPI = () => get("api/v1/product_categories");

@ -1,5 +1,4 @@
import { get } from '../utils/request'
import { get } from "../utils/request";
/**
* 获取商品信息
@ -7,7 +6,8 @@ import { get } from '../utils/request'
* @param {*} category 分类为空表示不分类
* @returns
*/
export const loadProductAPI = (page = 1, category = '') => get('/api/v1/products/', {
export const loadProductAPI = (page = 1, category = "") =>
get("/api/v1/products/", {
page,
category,
// per, 每页最多多少数据
@ -18,4 +18,4 @@ export const loadProductAPI = (page = 1, category = '') => get('/api/v1/products
* @param {*} id 商品id
* @returns
*/
export const loadProductByIdAPI = id => get('/api/v1/products/'+ id);
export const loadProductByIdAPI = (id) => get("/api/v1/products/" + id);

@ -1,13 +1,13 @@
import axios from "axios"
import NProgress from "nprogress"
import "nprogress/nprogress.css"
import axios from "axios";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
export const serverUrl = "http://localhost:1337"
export const serverUrl = "http://localhost:1337";
const instance = axios.create({
baseURL: serverUrl, // baseURL会在发送请求的时候拼接在url参数的前面
timeout: 5000, // 设置超时时间
})
});
/**
* get 请求
@ -19,7 +19,7 @@ const instance = axios.create({
export const get = (url, params) =>
instance.get(url, {
params: params, // url传递的参数
})
});
/**
* post 请求
@ -28,7 +28,7 @@ export const get = (url, params) =>
* @returns
*/
// axios.post(url, data, config)请求第三个参数表示配置信息(包括请求数据、请求头等)
export const post = (url, data) => instance.post(url, data)
export const post = (url, data) => instance.post(url, data);
/**
* put 请求
@ -36,14 +36,14 @@ export const post = (url, data) => instance.post(url, data)
* @param {*} data 数据
* @returns
*/
export const put = (url, data) => instance.put(url, data)
export const put = (url, data) => instance.put(url, data);
/**
* delete 请求
* @param {*} url 请求地址
* @returns
*/
export const del = (url) => instance.delete(url)
export const del = (url) => instance.delete(url);
// Add a request interceptor (全局请求拦截)
instance.interceptors.request.use(
@ -51,14 +51,14 @@ instance.interceptors.request.use(
// console.group("全局请求拦截");
// console.log(config);
// console.groupEnd();
NProgress.start() // 启动进度条
NProgress.start(); // 启动进度条
// 这里还可以设置token
return config
return config;
},
function (error) {
return Promise.reject(error)
return Promise.reject(error);
}
)
);
// Add a response interceptor (全局响应拦截)
instance.interceptors.response.use(
@ -66,11 +66,11 @@ instance.interceptors.response.use(
// console.group("全局响应拦截");
// console.log(response);
// console.groupEnd();
NProgress.done() // 关闭进度条
return response.data
NProgress.done(); // 关闭进度条
return response.data;
},
function (error) {
NProgress.done() // 关闭进度条
return Promise.reject(error)
NProgress.done(); // 关闭进度条
return Promise.reject(error);
}
)
);

@ -1,18 +1,17 @@
import { serverUrl } from "./request";
export const extName = str => `${str}`;
export const extName = (str) => `${str}`;
/**
* 处理返回数据中的url字段
* @param {*} url 请求返回的图片url
*/
export const dalImageUrl = url => {
export const dalImageUrl = (url) => {
if (url) {
if (url.startsWith('http')) {
if (url.startsWith("http")) {
return url;
}
return serverUrl + url;
}
return "https://hugo.bnblogs.cc/images/img/20220215001349.png";
}
};

@ -13,7 +13,11 @@
<action-bar-icon icon="chat-o" text="客服" @click="onClickIcon" />
<action-bar-icon icon="cart-o" text="购物车" @click="onClickIcon" />
<action-bar-icon icon="shop-o" text="店铺" @click="onClickIcon" />
<action-bar-button type="danger" text="立即购买" @click="onClickButton" />
<action-bar-button
type="danger"
text="立即购买"
@click="onClickButton"
/>
</action-bar>
</div>
</template>

@ -54,14 +54,14 @@ const { categories } = useCategories();
//
const router = useRouter();
const toDetail = id => {
const toDetail = (id) => {
router.push({
name: 'Detail',
name: "Detail",
query: {
id,
}
})
}
},
});
};
</script>
<style scoped></style>

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}

@ -0,0 +1,16 @@
# Vue 3 + TypeScript + Vite
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)
## Type Support For `.vue` Imports in TS
Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's Take Over mode by following these steps:
1. Run `Extensions: Show Built-in Extensions` from VS Code's command palette, look for `TypeScript and JavaScript Language Features`, then right click and select `Disable (Workspace)`. By default, Take Over mode will enable itself if the default TypeScript extension is disabled.
2. Reload the VS Code window by running `Developer: Reload Window` from the command palette.
You can learn more about Take Over mode [here](https://github.com/johnsoncodehk/volar/discussions/471).

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,21 @@
{
"name": "pinia-pre",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
"dependencies": {
"pinia": "^2.0.22",
"vue": "^3.2.37"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.1.0",
"typescript": "^4.6.4",
"vite": "^3.1.0",
"vue-tsc": "^0.40.4"
}
}

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,40 @@
<template>
<h1>Hello</h1>
<hr />
<button @click="onHandleSub">-</button>
<span>{{ count }}</span>
<button @click="onHandlePlus">+</button>
<div class="padding-10"></div>
<button @click="onHandleAsyncPlus">异步+</button>
<HW />
</template>
<script setup lang="ts">
import { storeToRefs } from "pinia";
import useCounterStore from "./stores/counter";
import HW from "./components/HelloWorld.vue";
const store = useCounterStore();
const { count } = storeToRefs(store);
const onHandlePlus = () => {
store.plus();
};
const onHandleSub = () => {
store.sub();
};
const onHandleAsyncPlus = () => {
store.asyncPlus();
};
</script>
<style scoped>
span {
font-size: 20px;
padding: 0 15px;
}
.padding-10 {
padding-top: 10px;
}
</style>

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

After

Width:  |  Height:  |  Size: 496 B

@ -0,0 +1,12 @@
<script setup lang="ts">
import { storeToRefs } from "pinia";
import useCounterStore from "../stores/counter";
const store = useCounterStore();
const {count} = storeToRefs(store);
</script>
<template>
<h3>这是Hello World组件数据: {{ count }}</h3>
</template>
<style scoped></style>

@ -0,0 +1,8 @@
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia();
createApp(App).use(pinia).mount('#app')

@ -0,0 +1,47 @@
import { defineStore } from "pinia";
import { ref } from 'vue'
// 选项式api的写法
// export default defineStore('counter',{
// // 定义数据
// state: () => {
// return {
// count: 1,
// title: '标题',
// }
// },
// // 数据操作
// actions: {
// plus() {
// this.count++;
// },
// sub() {
// this.count--;
// },
// asyncPlus() {
// setTimeout(() => {
// this.count++;
// }, 1000);
// }
// }
// })
// 组合式api写法
export default defineStore('counter', () => {
const count = ref(0);
const plus = () => {
count.value ++;
};
const sub = () => {
count.value --;
};
const asyncPlus = () => {
setTimeout(() => {
count.value++;
}, 1000);
};
return {
count,plus,sub,asyncPlus,
}
});

@ -0,0 +1,7 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}

@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"skipLibCheck": true
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}

@ -0,0 +1,9 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()]
})

@ -2,13 +2,13 @@
<h1>列表</h1>
<hr />
<div class="list">
<router-link
:to="{ name: 'Detail', query: { id: item.id } }"
v-for="item in courses"
:key="item.id"
><li>{{ item.name }}</li></router-link
>
<li>{{ item.name }}</li>
</router-link>
</div>
</template>

@ -4,13 +4,13 @@
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router';
import { useRouter } from "vue-router";
const { replace } = useRouter();
const login = () => {
localStorage.setItem("token", "1111");
replace({
name: 'User',
})
name: "User",
});
};
</script>

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}

@ -0,0 +1,7 @@
# Vue 3 + Vite
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended IDE Setup
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar)

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,21 @@
{
"name": "vuex-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"router": "^1.3.7",
"vue": "^3.2.37",
"vue-router": "^4.1.5",
"vuex": "^4.0.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.1.0",
"vite": "^3.1.0"
}
}

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,26 @@
<script setup>
import { useStore } from "vuex";
const store = useStore();
const handlePlus = () => {
store.commit("increment");
};
const handleSub = () => {
store.commit("subtraction");
};
</script>
<template>
<h3>{{ store.state.title }}</h3>
<button @click="handleSub">-</button>
<span>{{ store.state.count }}</span>
<button @click="handlePlus">+</button>
</template>
<style scoped>
span {
font-size: 20px;
padding: 0 10px;
font-weight: 600;
}
</style>

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

After

Width:  |  Height:  |  Size: 496 B

@ -0,0 +1,5 @@
<script setup></script>
<template></template>
<style scoped></style>

@ -0,0 +1,7 @@
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
import store from "./store";
createApp(App).use(store).mount("#app");

@ -0,0 +1,20 @@
import { createStore } from "vuex";
const store = createStore({
state() {
return {
count: 0,
title: "修改count值",
};
},
mutations: {
increment(state) {
state.count++;
},
subtraction(state) {
state.count--;
},
},
});
export default store;

@ -0,0 +1,90 @@
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
.card {
padding: 2em;
}
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()]
})
Loading…
Cancel
Save