1. 创建项目
- vue2
vue create my-vue2-project
- vue3
vue create my-vue3-project
(webpack)npm init vue@latest
(vite)
- react
npx create-react-app react18_ts_music --template typescript
2. router
-
vue2
npm install vue-router
(vue2 - vue-router3)
// ------ router/index.js ------ 定义路由 import VueRouter from "vue-router" const router = new VueRouter({ mode: "history", routes: [ { path: "/", redirect: "/home" }, { path: "/home", name: "Home", component: () => import("@/views/home") } ] }) export default router
// ------ main.js ------ 挂载路由 import Vue from "vue" import App from "./App.vue" import router from "./router" new Vue( router, render: h => h(App) ).$mount("#App")
<!-- App.vue 占位 --> <template> <div id="App"> <router-view></router-view> </div> </template>
-
vue3
npm install vue-router
(vue3 - vue-router4)
// ------ router/index.js ------ 定义路由 import { createRouter, createWebHistory } from "vue-router" const router = createRouter({ history: createWebHistory(), routes: [ { path: "/", redirect: "/home" }, { path: "/home", name: "Home", component: () => import("@/views/home") } ] }) export default router
// ------ main.js ------ 挂载路由 import { createApp } from "vue" import App from "./App.vue" import router from "./router" const app = createApp(App) app.use(router) app.mount("#app")
<!-- App.vue 占位 --> <template> <div id="App"> <router-view></router-view> </div> </template>
-
react
npm install react-router-dom
// ------ router/index.js ------ 定义路由 import { lazy } from "React" import { Navitage } from "react-router-dom" const Home = lazy(() => import("@/views/home")) const routes = [ { path: "/", element: <Navigate to={"/Home"} /> }, { path: "/home", element: <Home /> } ] export default routes
// ------ index.js ------ 挂在路由 import React from "React" import ReactDOM from "@react/client" import { HashRouter } from "react-router-dom" import App from "./App" const root = ReactDOM.createRoot(document.getElementById("root")) root.render( <HashRouter> <React.Suspense> <App /> </React.Suspense> </HashRouter> )
// ------ App.jsx ------ 占位 import { useRoutes } from "react-router-dom" import routes from "@/router" function App() { return ( <div className="App"> { useRoutes(routes) } </div> ) } export default App
3. store - vuex
-
vue2
npm install vuex@3 --save
(vue2 - vuex3)
// ------ store/index.js ----- import Vuex from "vuex" import product from "./product" import Vue from "vue" Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 1 }, mutation: {}, action: {}, modules: { product } }) export default store
// ------ store/product.js ------ export default { namespaced: true, state: { list: [1, 2, 3, 4, 5] }, mutations: { addList(state, payload) { state.list.push(payload) } }, actions: { addList2(context, payload) { context.commit("addList", payload) } } }
// ------ main.js ------ import Vue from "vue" import App from "./App.vue" import store from "./store/index" new Vue({ render: h => h(App), store }).$mount("#app")
<template> <!-- 方式一 --> <div>count: {{ $store.state.count }}</div> <!-- 方式二 --> <div>count: {{ count }}</div> </template> <script> import { mapState } from "vuex" import { mapMutations } from "vuex" import { mapActions } from "vuex" export default { name: "helloword", data() { return { value: "" } }, computed: { ...mapState( ["count"] ), // 导入别的模块中的数据 ...mapState( "product", ["list"]) } methods: { ...mapMutations( "product", ["addList"] ), ...mapActions( "product", ["addList2"] ), addList() { this.addList(this.value) }, addList2() { this.addList2(this.value) }, addList3() { this.$store.commit("product/addList", this.value) } } } </script>
-
vue3
npm install vuex@next --save
(vue3 - vuex4)
// ------ store/index.js ------ import { createStore } from "vuex" const store = createStore({ state() { return { name: "why" } }, mutations: { changeName(state, name) { state.name = name } }, actions: { asyncChangeName({ commit }, name) { // 模拟异步, 等 2s 后再进行提交, 在实际中可以结合 Promise 进行状态管理, 如用户登录处理 setTimeout(() => { commit('changeName', name) }, 2000); } } }) export default store
// ------ main.js ------ import { createApp } from "vue" import App from "./App.vue" import store from "./store" const app = createApp(App) app.use(store) app.mount("#app")
<template> <div> <p>name: {{ $store.state.name }}</p> <p>name2: {{ name }}</p> </div> </template> <script setup> import { computed } from "vue" import { useStore } from "vuex" const store = useStore() const name = computed(() => store.state.name) const handleCommitClick = (name) => store.commit("changeName", name) const handleDispatchClick = (name) => store.dispatch("asyncChangeName", name) </script>
4. store - pinia
-
npm install pinia
// ------ main.js ------ import { createApp } from "vue" import App from "./App.vue" import store from "./store" const app = createApp(App) app.use(store).mount("#app")
// ------ store/index.js ------ import { createPinia } from "pinia" const store = createPinia() export default store
// ------ store/user.js ------ import { defineStore } from "pinia" const userStore = definestore("user", { state: () => { return { count: 1, name: "why" } }, getters: { doubleCount: (state) => { return state.count * 2 } }, actions: { increment() { this.count ++ } } }) export default userStore
<template> <div> <p>count: {{ store.count }}</p> <p>count: {{ name }}</p> </div> </template> <script setup> import userStore from "@/store/user" import { storeToRefs } from "pinia" const store = userStore() // 利用storeToRefs将state中的数据变为响应式 const { count, name } = storeToRefs(store) // 单个修改 const setName = () => { store.name = "999" } // 批量修改 const patchStore = () => { store.$patch((state) => { state.count ++; state.name = "hahaha" }) } // 触发actions里的方法 const increment = () => { store.saveName() } // 数据重置 const resetStore = () => { store.$reset() } </script>
4. store - redux
5. 打包工具
- webpack
- vite