vue2、vue3和react

46 阅读1分钟

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