美文网首页
Vue3 | VueCli、node.js安装、nrm切换镜像源

Vue3 | VueCli、node.js安装、nrm切换镜像源

作者: 凌川江雪 | 来源:发表于2021-09-12 20:55 被阅读0次

    完整原文地址见简书

    更多完整Vue笔记目录敬请见《前端 Web 笔记 汇总目录(Updating)》


    本文内容提要

    • VueCli部分
      • 首先需要安装nodejs
      • 安装完node会自动配套npm
      • 使用npm install nrm -g用于调整 镜像源,方便后续下载依赖
      • 这边使用淘宝镜像
      • npm uninstall vue-cli -g 检查并清除 多余的旧版本
      • 使用npm install -g @vue/cli[@版本号]安装 脚手架
      • 使用 脚手架 Vue Cli,从 创建项目 到 运行项目 的过程
      • 退出之后,把刚刚创建的项目拉进VSCode,使用VSCode启动项目
    • 初始项目结构解读
      • 源代码在src下,main.js是入口
      • App.vue文件 简读
      • 关于HelloWorld.vue文件
      • 单文件组件 的含义
    • 基于工程实现TODOList案例 --- 单组件版[App.vue]
    • 基于工程实现TODOList案例 --- 父子组件版[App.vue、ListItem.vue]
    • Vue-Router部分
      • 在代码中使用Router
      • Router的作用 及 简述
      • 首先看一下App.vue根组件怎么写
      • 解析一下这个多出来的 router/index.js 文件
      • view目录下的文件
      • 例程,拓展一个Router页面
      • 补充:Router路由懒加载语法糖 简述 与例程实战
    • VueX部分
      • 首先需要创建项目
      • --- 特性配置:
      • package.json文件
      • VueX简述
      • VueX 框架的引入、数据的定义 以及 在组件中的使用
      • 在Home.vue中 使用这个 VueX提供的 全局数据字段:
      • 如何在任一组件中 修改 VueX的 数据
      • VueX的异步操作 同步操作
      • 带参数地 修改VueX数据
      • VueX修改数据 流程设计的理解
      • 安装、使用axios发送ajax请求
      • 把上例的axios请求 封装到 actions中

    VueCli部分

    首先需要安装nodejs

    参考博客:
    --- Install Node.js
    --- Node.js 安装配置

    安装完node会自动配套npm

    使用npm install nrm -g用于调整 镜像源,方便后续下载依赖

    安装完了注意,
    C:\Users\凌川江雪\AppData\Roaming\npm\nrm -> C:\Users\凌川江雪\AppData\Roaming\npm\node_modules\nrm\cli.js乃是依赖的安装代码路径;

    nrm ls可以切换镜像源:

    其他命令如图,安装后自然可以看到;

    安装后使用时,你可能遇到这个问题:

    D:\OK\nodejsOther>nrm ls
    internal/validators.js:124
       throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
       ^
    
    [TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type >string. Received undefined
     at validateString (internal/validators.js:124:11)
     at Object.join (path.js:375:7)
     at Object.<anonymous> (C:\Users\凌川江雪>\AppData\Roaming\npm\node_modules\nrm\cli.js:17:20)
     at Module._compile (internal/modules/cjs/loader.js:1063:30)
     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
     at Module.load (internal/modules/cjs/loader.js:928:32)
     at Function.Module._load (internal/modules/cjs/loader.js:769:14)
     at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
     at internal/main/run_main_module.js:17:47
    ] {
     code: 'ERR_INVALID_ARG_TYPE'
    }
    

    解决方案参考——nrm报错 [ERR_INVALID_ARG_TYPE] 解决方法

    这边使用淘宝镜像

    npm uninstall vue-cli -g 检查并清除 多余的旧版本

    使用npm install -g @vue/cli[@版本号]安装 脚手架

    脚手架沉淀了许多最佳实践,
    可以借助它快速生成Vue工程,包括 项目目录组织、webpack打包配置等;

    使用 脚手架 Vue Cli,从 创建项目 到 运行项目 的过程

    命令:vue create [项目名]
    vue create demo-pro
    运行创建命令之后,工具会询问创建方式:

    这里先选第三个,手动选择创建项目需要的特性,
    接着,进入选择特性界面: 用空格进行选择,回车进行确定,
    这里选择以上三个特性即可,然后回车: 选择3.x的Vue版本,回车,选择使用ESLint的方式: 这里选择第一个,出错的时候才会触发;
    回车确定;

    这里是选择Lint的校验时机——保存时校验还是commit时校验,
    这里先选择第一个,回车确定;

    这里是选择要把config文件,放一个单独的文件里,还是放一个package.json里,
    这里先选第一个;

    最后问,刚刚这一套特性的选择需不需要保存下来方便后续使用,这里不保存;
    回车后工程开始创建:
    工程创建完成: 进入工程目录,
    使用npm run serve启动工程: 启动中: 启动成功,开始运行: 使用浏览器访问: cmd处ctrl + c两次可以终止运行:

    退出之后,把刚刚创建的项目拉进VSCode,使用VSCode启动项目

    因为我们无需每次都用cmd去启动项目;

    把刚刚创建的项目拉进VSCode,准备使用VSCode启动项目: 在VS Code中,使用Terminal栏启动即可,方便快捷!
    【刚拉进来可能启动不了,报9009之类的错,
    这时候重启一下VSCode就是了;
    如果项目中没有node_modules
    则需先运行npm install安装node_modules依赖!!】 运行成功:

    初始项目结构解读

    注意要在VS code中安装vetur这个插件,
    使得VS可以提供 语法高亮、提示 等效果:

    源代码在src下,main.js是入口

    --- import { createApp } from 'vue'
    指明createApp的来源;
    --- import App from './App.vue'
    指明App实例,来自于当前文件夹下的 App.vue文件;
    --- createApp(App).mount('#app')
    创建实例、挂载实例:

    App.vue文件 简读

    --- <template>标签对的内容,
    其实就等价于之前在组件实例中写的template:键模板;

    --- <script>和<style>标签对自然就是js和样式的“根据地了”;

    --- 其中<script>中的 name指定了根组件实例名,
    component这里引入了一个子组件HelloWorld,
    子组件从import HelloWorld from './components/HelloWorld.vue'
    可以看出其定义的地方,即 components文件夹目录下的HelloWorld.vue

    <template>
      <img alt="Vue logo" src="./assets/logo.png">
      <HelloWorld msg="Welcome to Your Vue.js App"/>
    </template>
    
    <script>
    import HelloWorld from './components/HelloWorld.vue'
    
    export default {
      name: 'App',
      components: {
        HelloWorld
      }
    }
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    

    关于HelloWorld.vue文件

    看了一下结构,其实也没什么特殊的了,
    跟上面App.vue的结构大体都是一样的:

    <template>
      <div class="hello">
        <h1>{{ msg }}</h1>
        <p>
          For a guide and recipes on how to configure / customize this project,<br>
          check out the
          <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
        </p>
        <h3>Installed CLI Plugins</h3>
        <ul>
          <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
          <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
        </ul>
        <h3>Essential Links</h3>
        <ul>
          <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
          <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
          <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
          <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
          <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
        </ul>
        <h3>Ecosystem</h3>
        <ul>
          <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
          <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
          <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
          <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
          <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
        </ul>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HelloWorld',
      props: {
        msg: String
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    h3 {
      margin: 40px 0 0;
    }
    ul {
      list-style-type: none;
      padding: 0;
    }
    li {
      display: inline-block;
      margin: 0 10px;
    }
    a {
      color: #42b983;
    }
    </style>
    
    

    单文件组件 的含义

    顾名思义,即一个组件就代表了一个组件,
    如上的App.vueHelloWorld.vue都是单文件组件;
    单独一个文件内容,就是完整的 HTML(<template>) + CSS(<style>) + JS(<script>)结构了;

    基于工程实现TODOList案例 --- 单组件版[App.vue]

    <template>
      <div>
        <input v-model="inputValue" />
        <button class="button" @click="handleAddItem">提交</button>
      </div>
      <ul>
        <li v-for="(item, index) in list" :key="index">
          {{ item }}
        </li>
      </ul>
    </template>
    
    <script>
    import { reactive, ref
     } from "vue";
    
    export default {
      name: "App",
      setup() {
        const inputValue = ref("");
        const list = reactive([]);
    
        const handleAddItem = () => {
          list.push(inputValue.value);
          inputValue.value = "";
        };
        return { list, inputValue, handleAddItem };
      },
    };
    </script>
    
    <style>
      .button {
        margin-left: 20px;
      }
    </style>
    

    运行效果:

    基于工程实现TODOList案例 --- 父子组件版[App.vue、ListItem.vue]

    首先需要创建一个子组件单文件:


    其代码:
    <template>
      <div class="hello">
        <li>{{ msg }}</li>
      </div>
    </template>
    
    <script>
    export default {
      name: 'ListItem',
      props: {
        msg: String
      }
    }
    </script>
    
    <style>
    </style>
    

    App.vue:
    与上例 主要区别就是在<script>中引入,
    在<template>中修改:

    <template>
      <div>
        <input v-model="inputValue" />
        <button class="button" @click="handleAddItem">提交</button>
      </div>
      <ul>
        <list-item v-for="(item, index) in list" :key="index" :msg="item" />
      </ul>
    </template>
    
    <script>
    import { reactive, ref } from "vue";
    import ListItem from "./components/ListItem.vue";
    
    export default {
      name: "App",
      components: { ListItemListItem },
      setup() {
        const inputValue = ref("");
        const list = reactive([]);
    
        const handleAddItem = () => {
          list.push(inputValue.value);
          inputValue.value = "";
        };
        return { list, inputValue, handleAddItem };
      },
    };
    </script>
    
    <style>
    .button {
      margin-left: 20px;
    }
    </style>
    

    运行效果同上例;

    Vue-Router部分

    创建带router的项目


    选择特性的时候要选上Router: 这里暂时不选history mode,会使用 hash Router,
    适配会简单些: 其他配置:

    在代码中使用Router

    创建好工程项目后,同样把它拉到VScode里面,
    可以看到这里的目录,
    可以看到main.js中,多了一个.use(router)

    Router的作用 及 简述

    作用:根据url的不同,展示不同的内容;

    如下,运行项目,默认urlhttp://localhost:8080/#/,展示主页(Home页):

    编写url——http://localhost:8080/#/about访问,则展示about页:

    首先看一下App.vue根组件怎么写

    <template>
      <div id="nav">
        <router-link to="/">Home</router-link> |
        <router-link to="/about">About</router-link>
      </div>
      <router-view/>
    </template>
    
    <style>
    </style>
    

    --- router-link是定义 跳转路由的标签,
    to属性可以配置url尾部参数【前部 自动补上 网站根地址】,
    标签内容配置显示的内容;
    点击标签内容,即跳转到,to补全url 指向的页面!!
    如果有写<router-view/>,则不跳转,乃显示在<router-view/>中;

    --- <router-view/>则是
    根据router-link以及网页url组成的url路由
    router/index.js 文件中的 路由对象(如下一节的routes)里,
    找到对应的组件路由属性,拿到对应的组件文件路径
    view目录中找到 对应的组件 去显示!

    解析一下这个多出来的 router/index.js 文件

    import { createRouter, createWebHashHistory } from 'vue-router'
    import Home from '../views/Home.vue'
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/about',
        name: 'About',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
      }
    ]
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    
    export default router
    

    --- createRouter是vue-router的一个函数,用于创建和初始化Router;
    同时这里第二个参数 使用了路由参数routes

    --- 注意 定义routes参数这里,
    path定义 路径、name定义 名称、component进行 组件的引入;
    routers里的组件既称之为component
    也称之为view,子组件的单文件都放在view文件夹下;

    view目录下的文件

    -- 可以看到Home.vue这里其实引用一个HelloWorld子组件:

    例程,拓展一个Router页面

    • 首先App.vue添加 router-link:
    • views目录下创建 单文件组件:
    • router/index.js 的Object Array中,定义一个对应的路由元素:

    完事,运行,点击Heheda,效果:

    补充:Router路由懒加载语法糖 简述 与例程实战

    如上例程中,router/index.js 中的这个写法,
    component 这里使用了 import的方式 引入了组件,
    这是一种懒加载、异步加载(如模板注释:lazy-loaded)的方式,
    即当网页跳到这一页的时候,才会加载对应的资源文件,否则不加载;

    而如 Home页的加载方式,
    则是普通的常规加载:

    所以,
    --- 异步加载的方式:
    首页打开会快点,节省不必要的资源占用,
    但是在切换到懒加载页面时,则需要花费一定的额外加载时间;

    --- 同步加载的默认方式:
    则可能 一开始打开首页等页面 会慢一些,
    但是会把其他页面一开始就加载好,切换的时候会快一点;

    --- 具体选择哪种方式,就根据业务需要进行选择;

    ...
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/heheda',
        name: 'Heheda',
        component:  () => import(/* webpackChunkName: "about" */ '../views/Heheda.vue')
      },
      {
        path: '/about',
        name: 'About',
        // route level code-splitting
        // this generates a separate chunk (about.[hash].js) for this route
        // which is lazy-loaded when the route is visited.
        component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
      }
    ]
    ...
    

    试验,运行上个例程,之后打开浏览器测试工具:

    跳到Home页,刷新页面,然后清理记录,再点击about页,
    可以看到这个时候页面才加载about的资源:

    VueX部分

    首先需要创建项目


    --- 特性配置: 老规矩,创建项目之后把项目拉进VScode启动与开发;
    package.json文件

    VueX简述

    VueX 其实就是一个数据管理框架
    它创建了一个全局的、唯一的数据仓库

    当一个前端项目特别大的时候,
    或者类似 几十个页面 同步共享 某部分数据 的场景,
    我们不可能还是用props、provide、inject等语法去传递数据,
    这个时候我们需要一个更加完善的数据管理方案;

    VueX 框架的引入、数据的定义 以及 在组件中的使用

    main.js中use它:

    store /index.js创建仓库,
    这里在state中准备了一个测试数据:
    在Home.vue中 使用这个 VueX提供的 全局数据字段:
    这里借助computed属性,
    通过this.$store.state.myTestString获取到 数据字段:
    <template>
      <div class="home">
        <img alt="Vue logo" src="../assets/logo.png">
        <h1>{{myTestString}}</h1>
      </div>
    </template>
    
    <script>
    // @ is an alias to /src
    
    export default {
      name: 'Home',
      computed: {
        myTestString() {
          return this.$store.state.myTestString;
        }
      }
    }
    </script>
    

    运行效果:

    在About.vue中也试一下:
    <template>
      <div class="about">
        <h1>This is an about page</h1>
        <h1>{{myTestString}}</h1>
      </div>
    </template>
    
    
    <script>
    export default {
      name: 'About',
      computed: {
        myTestString() {
          return this.$store.state.myTestString;
        }
      }
    }
    </script>
    
    运行效果:

    如何在任一组件中 修改 VueX的 数据

    流程总结:
    要修改数据的组件,
    发起dispatch(事件) --->

    store/index.jsactions
    dispatch的事件 进行 监听 和回调处理,
    然后发起一个commit(事件) --->

    store/index.jsmutations
    commit的事件 进行 监听 和回调处理,
    处理逻辑中,完成对数据的修改;

    --- 首先,需要在事件触发的函数里,
    派发一个action,
    改变数据 这里在About.vue中,
    我们派testChange【这玩意是可以自定义的】的action,
    this.$store.dispatch("testChange");

    <template>
      <div class="about">
        <h1 @click="handleClick">This is an about page</h1>
        <h1>{{ myTestString }}</h1>
      </div>
    </template>
    
    
    <script>
    export default {
      name: "About",
      computed: {
        myTestString() {
          return this.$store.state.myTestString;
        },
      },
      methods: {
        handleClick() {
          this.$store.dispatch("testChange");
        },
      },
    };
    </script>
    

    --- 接着在store/index.jsactions里,即这个VueX全局数据仓库中,
    dispatch的 监听回调处理,
    store/index.js中的actions会响应任意组件的dispatch

    --- 再接着,
    actions里 对应的回调方法中,使用commit('自定义事件名')
    触发一个mutations
    store/index.js中的mutations
    会响应actionscommit

    --- 最后,
    store/index.js中的mutations里,
    actionscommit的监听回调,
    在对应commit的 事件回调函数中(如testChange()),
    修改数据(如this.state.myTestString = "lueluelue";)即可;

    import { createStore } from 'vuex'
    
    export default createStore({
      state: {
        myTestString: "heheda",
      },
      mutations: {
        testChange() {
          console.log("mutations --- testChange");
          this.state.myTestString = "lueluelue";
        }
      },
      actions: {
        testChange() {
          console.log("actions --- testChange");
          this.commit('testChange');
        }
      },
      modules: {
      }
    })
    

    运行:

    点击文本,
    可见完成了数据的修改,效果: 点击到Home页,
    可见这边的数据也跟着改变了,
    体现了VueX的全局特性

    以上是比较完整的步骤,而如果修改数据的时候不涉及异步操作,则可以简化上述流程

    即省略组件的dispatchstore的actions的步骤,
    组件直接就commit,
    然后回调到store的mutations,
    直接修改数据:

    运行效果基本同上例;

    VueX的异步操作 同步操作

    VueX建议在mutations中只进行立即执行的同步操作
    如果要进行异步操作,必须要在actions中进行,
    也就是要采用上上节的步骤 进行VueX数据的修改;

    例程,首先需要组件发起dispatch:


    接着在actions中进行异步操作:
    import { createStore } from 'vuex'
    
    export default createStore({
      state: {
        myTestString: "heheda",
      },
      mutations: {
        testChange() {
          console.log("mutations --- testChange");
          this.state.myTestString = "lueluelue";
        }
      },
      actions: {
        testChange() {
          setTimeout(() => {
            console.log("actions --- testChange");
            this.commit('testChange');
          }, 2000);
        }
      },
      modules: {
      }
    })
    

    运行,点击文本,两秒后文本(即背后的数据)自动改变:

    带参数地 修改VueX数据

    --- About.vue
    dispatch时,
    传递的 第一个参数为action
    第二个参数为意图改动的目标数据参数

    <template>
      <div class="about">
        <h1 @click="handleClick">This is an about page</h1>
        <h1>{{ myTestString }}</h1>
      </div>
    </template>
    
    
    <script>
    export default {
      name: "About",
      computed: {
        myTestString() {
          return this.$store.state.myTestString;
        },
      },
      methods: {
        handleClick() {
          this.$store.dispatch("testChange", "xixixihehehe");
        },
      },
    };
    </script>
    

    --- store/index.js:

    --- actions中的 事件回调函数,自动生成两个形参,
    第一个为store实例,
    第二个为 组件中dispatch 传递过来的 数据参数;

    --- mutations的 事件回调函数,也自动生成两个形参,
    第一个为 state实例,
    它的值是 以Proxy的结构存储着
    回调当前事件处理函数的时刻 store 数据仓库的 状态【即 state属性】,
    第二个为 actions中commit 【同步操作时,也可以是组件中的commit】
    传递过来的 数据参数;

    import { createStore } from 'vuex'
    
    export default createStore({
      state: {
        myTestString: "heheda",
      },
      mutations: {
        testChange(state, str) {
          console.log("mutations --- testChange");
          console.log("mutations --- testChange --- state", state);
          state.myTestString = str;
        }
      },
      actions: {
        testChange(store, str) {
          setTimeout(() => {
            console.log("actions --- testChange");
            console.log("actions --- testChange --- store", store);
            // this.commit('testChange');
            store.commit('testChange', str);
          }, 2000);
        }
      },
      modules: {
      }
    })
    

    运行,点击文本,
    两秒后字体改变,效果:

    VueX修改数据 流程设计的理解

    这样设计,
    --- 可以把同步操作的逻辑封装在mutations中处理,
    把异步操作的逻辑封装在actions中处理;

    --- 又可以通过对触发事件名自定义
    对特定的业务处理逻辑、修改数据代码块 做标记;

    --- 如此使得项目可维护性高、可拓展性高、可读性高,
    出问题时容易排查,拓展代码时也比较方便;

    在setup【compositionAPI】中使用VueX

    --- Home.vue:

    <template>
      <div class="home">
        <img alt="Vue logo" src="../assets/logo.png" />
        <h1>{{ myTestString }}</h1>
      </div>
    </template>
    
    <script>
    import { useStore } from "vuex";
    export default {
      name: "Home",
      setup() {
        const store = useStore();
        const myTestString = store.state.myTestString;
        return { myTestString };
      },
    };
    </script>
    
    运行效果:
    使用toRefs整理上述代码
    <template>
      <div class="home">
        <img alt="Vue logo" src="../assets/logo.png" />
        <h1>{{ myTestString }}</h1>
      </div>
    </template>
    
    <script>
    import { toRefs } from "vue";
    import { useStore } from "vuex";
    export default {
      name: "Home",
      setup() {
        const store = useStore();
        const { myTestString } = toRefs(store.state);
        return { myTestString };
      },
    };
    </script>
    
    

    运行效果同上例;

    在About页中 试试 setup中修改数据

    --- About.vue

    <template>
      <div class="about">
        <h1 @click="handleClick">This is an about page</h1>
        <h1>{{ myTestString }}</h1>
      </div>
    </template>
    
    
    <script>
    import { toRefs } from "vue";
    import { useStore } from "vuex";
    export default {
      name: "About",
      setup() {
        const store = useStore();
        const { myTestString } = toRefs(store.state);
        const handleClick = () => {
          store.commit("testChange", "xixixihehehe");
        };
        return { myTestString, handleClick };
      }
    };
    </script>
    

    --- store/index.js:

    import { createStore } from 'vuex'
    
    export default createStore({
      state: {
        myTestString: "heheda",
      },
      mutations: {
        testChange(state, str) {
          console.log("mutations --- testChange");
          console.log("mutations --- testChange --- state", state);
          state.myTestString = str;
        }
      },
      modules: {
      }
    })
    
    

    运行,到About页,


    点击文本: Home页数据同步:

    试一下 setup异步处理

    --- About.vue

    <template>
      <div class="about">
        <h1 @click="handleClick">This is an about page</h1>
        <h1>{{ myTestString }}</h1>
      </div>
    </template>
    
    
    <script>
    import { toRefs } from "vue";
    import { useStore } from "vuex";
    export default {
      name: "About",
      setup() {
        const store = useStore();
        const { myTestString } = toRefs(store.state);
        const handleClick = () => {
          store.dispatch("testChange", "xixixihehehe");
        };
        return { myTestString, handleClick };
      }
    };
    </script>
    

    --- store/index.js

    import { createStore } from 'vuex'
    
    export default createStore({
      state: {
        myTestString: "heheda",
      },
      mutations: {
        testChange(state, str) {
          console.log("mutations --- testChange");
          console.log("mutations --- testChange --- state", state);
          state.myTestString = str;
        }
      },
      actions: {
        testChange(store, str) {
          setTimeout(() => {
            console.log("actions --- testChange");
            console.log("actions --- testChange --- store", store);
            // this.commit('testChange');
            store.commit('testChange', str);
          }, 2000);
        }
      },
      modules: {
      }
    })
    

    使用axios发送ajax请求

    • 首先需要安装axios:

    找到一个fastmock接口,
    https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/register
    其内容:


    在About.vue中请求数据并显示:
    --- 主要注意要import
    --- get方法的参数为url,访问数据接口;
    --- then接收 接口回复;
    <template>
      <div class="about">
        <h1 @click="handleClick">This is an about page</h1>
        <h1>{{ myTestString }}</h1>
      </div>
    </template>
    
    
    <script>
    import { toRefs } from "vue";
    import { useStore } from "vuex";
    import axios from "axios";
    export default {
      name: "About",
      setup() {
        axios
            .get(
              "https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/register"
            )
            .then((response) => {
              console.log("response", response);
              const msg = response.data.desc;
              console.log("response.data.desc", msg);
            });
    
        const store = useStore();
        const { myTestString } = toRefs(store.state);
        const handleClick = () => {
          store.dispatch("testChange", "xixixihehehe");
        };
        return { myTestString, handleClick };
      },
    };
    </script>
    

    运行效果:

    把上例的axios请求 封装到 actions中

    --- About.vue

    <template>
      <div class="about">
        <h1 @click="handleClick">This is an about page</h1>
        <h1>{{ myTestString }}</h1>
      </div>
    </template>
    
    
    <script>
    import { toRefs } from "vue";
    import { useStore } from "vuex";
    export default {
      name: "About",
      setup() {
        const store = useStore();
        const { myTestString } = toRefs(store.state);
        const handleClick = () => {
          store.dispatch("testChange", "xixixihehehe");
        };
        return { myTestString, handleClick };
      },
    };
    </script>
    

    --- store/index.js

    import { createStore } from 'vuex'
    import axios from "axios";
    
    export default createStore({
      state: {
        myTestString: "heheda",
      },
      mutations: {
        testChange(state, str) {
          console.log("mutations --- testChange");
          console.log("mutations --- testChange --- state", state);
          state.myTestString = str;
        }
      },
      actions: {
        testChange(store) {
          axios
            .get(
              "https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/register"
            )
            .then((response) => {
              console.log("response", response);
              const msg = response.data.desc;
              console.log("response.data.desc", msg);
              store.commit('testChange', msg);
            });
        }
      },
      modules: {
      }
    })
    

    运行:

    点击文本,两秒后:

    相关文章

      网友评论

          本文标题:Vue3 | VueCli、node.js安装、nrm切换镜像源

          本文链接:https://www.haomeiwen.com/subject/kxayrltx.html