【vue3.0 】vue 3.0 入门学习笔记

1. 项目初始化
1.1 安装 vue-cli
  1. 第一步安装vue-cli:注意! 如果在vue2中已经安装过这里就不需要再安装了。
npm install -g @vue/cli
  1. 以下安装方式是错误的:
npm install -g vue
npm install -g vue-cli
  1. 安装成功后,我们即可使用 vue 命令,测试方法:
vue -V
1.2 初始化 vue 项目
  1. 使用 vue2.0中创建项目的方式创建项目 :
vue create project-name
  1. 输入命令后,会出现命令行交互窗口,这里我们选择 Manually select features(手动选择) :
Vue CLI v4.3.1
? Please pick a preset: 
  default (babel, eslint) 
❯ Manually select features 
  1. 随后我们勾选:Router、Vuex、CSS Pre-processorsLinter / Formatter,这些都是开发商业级项目必须的:
Vue CLI v4.3.1
? Please pick a preset: Manually select features
? Check the features needed for your project: 
 ◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◉ Router
 ◉ Vuex
 ◉ CSS Pre-processors
❯◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

注意:在初始化项目的时候需要对 RouterVuex 进行同时安装。因为此时项目还属于使用 vue 2.0 创建,如果后期升级 vue3.0时可以同时升级 RouterVuex的版本。

小提示: 回车后会自动安装依赖,为了加速安装速度,我们可以使用淘宝源来加快初始化速度 。

vue create -r https://registry.npm.taobao.org project-name
2. 升级为 Vue 3.0 项目
  1. 目前创建 Vue 3.0 项目需要通过插件升级的方式来实现,vue-cli 还没有直接支持,我们进入项目目录,并输入以下指令:
cd project-name // 切换到项目目录下
vue add vue-next
  1. 执行上述指令后,会自动安装 vue-cli-plugin-vue-next 插件(查看vue3.0项目代码),该插件会完成以下操作:
  • 安装 Vue 3.0 依赖;
  • 更新 Vue 3.0 webpack loader 配置,使其能够支持.vue 文件构建(这点非常重要);
  • 创建Vue 3.0的模板代码;
  • 自动将代码中的Vue RouterVuex 升级到 4.0 版本,如果未安装则不会升级;
  • 自动生成 Vue RouterVuex模板代码。
  1. 完成上述操作后,项目正式升级到Vue 3.0,注意该插件还不能支持 typescript

  2. 在升级为 Vue 3.0版本之后启动项目报如下错误 :

ERROR  Error: Cannot find module 'vue-loader-v16/package.json'
2.1 解决升级 vue 3.0 之后 vue-loader-v16找不到问题
  1. 查询资料找到一篇文章中的解决方案: vue3项目报错 Error: Cannot find module ‘vue-loader-v16/package.json‘

  2. 升级npm

npm i -g npm
  1. 删除并重新安装node_modules依赖包
npm i
  1. 重新下载 vue-loader-v16
cnpm i -D vue-loader-v16
3. Vue 3.0 基本特性的体验
3.1 创建页面并添加新的路由
  1. 项目开发中,我们通常需要创建新页面,然后添加路由配置,我们在/src/views 目录下创建 Test.vue
<template>
  <div class="test">
    <h1>test page</h1>
  </div>
</template>

<script>
 export default {
 }
</script>

<style lang="less" scoped>
.test {
  color: red;
}
</style>
  1. 之后在 /src/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')
  },
  {
    path: '/test',
    name: 'Test',
    // 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/Test.vue')
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router
  1. 初始化 Vue Router 的过程与 3.0 版本变化不大,只是之前采用构造函数的方式,这里改为使用 createRouter 来创建 Vue Router 实例,配置的方法基本一致,配置完成后我们还需要在 App.vue 中增加链接到 Test.vue 的路由:
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <router-link to="/test">Test</router-link>
    </div>
    <router-view/>
  </div>
</template>
3.2 CompositionApi(一)
vue3.0中CompositionAPI的具体体现
 /*  CompositionAPI */
    import {reactive, watchEffect} from 'vue'

    /**
     * 创建状态
     * @type {UnwrapNestedRefs<{count: number}>}
     */
    const state = reactive({
      count: 1
    })

    /**
     * 进行累加操作
     * */
    const increment = () => {
      state.count++
    }

    /**
     * 观察效果
     */
    watchEffect(() => {
      document.body.innerHTML = `count:${state.count}`
      document.body.addEventListener('click', increment)
    })
3.3 Vue3.0中状态和事件绑定 、计算属性和监听器
  1. Vue 3.0 中定义状态的方法改为类似 React Hooks 的方法,下面我们在 CompositionApiContinue.vue中定义一个状态 count: 从vue中导入 ref对状态进行初始化
      // 初始化 count 的值为 1
        const count = ref(1)
  1. Vue 3.0 中初始化状态通过 setup 方法,定义状态需要调用 ref 方法。接下来我们定义一个事件,用来更新 count状态:注意这里对count的修改需要修改count的value属性。
 const add = () => {
          // 对状态的值进行改变 需要使用 value
          count.value++
        }
  1. 这些定义好的状态和事件需要通过 return 返回一个对象进行返回:
      // 初始化完成之后需要进行返回
        return {
          count,
          add,
          doubleCount,
          threeCount
        }
  1. 使用 watch监听状态的改变: 需要在vue中导入 watch函数
      // 使用 watch 监听值的改变
        /**
         * 注意watch 传递的第一个参数需要是函数的返回值
         */
        watch(() => count.value, (newVal, oldVal) => {
          console.log(newVal)
          console.log(oldVal)
        })
  1. 使用Vue3.0 中的计算属性,需要在Vue中导入computed函数:
        // 计算属性
        const doubleCount = computed(() => count.value * 2)
        const threeCount = computed(() => count.value * 3)
  1. 完整代码:
<template>
    <!-- vue 3.0 中状态和事件绑定 -->
    <div class="composition-api">
        <h1>test count : {{count}}</h1>
        <h1>test doubleCount : {{doubleCount}}</h1>
        <h1>test threeCount : {{threeCount}}</h1>
        <button @click="add">add</button>
    </div>
</template>

<script>
    /* 状态初始化 、 事件绑定 、 计算属性 、 监听器 */
    import {ref, computed, watch} from 'vue'

    export default {
      name: "index",
      // 在 vue 3.0 中初始化状态使用 setup
      setup() {
        // 初始化 count 的值为 1
        const count = ref(1)
        const add = () => {
          // 对状态的值进行改变 需要使用 value
          count.value++
        }

        // 使用 watch 监听值的改变
        /**
         * 注意watch 传递的第一个参数需要是函数的返回值
         */
        watch(() => count.value, (newVal, oldVal) => {
          console.log(newVal)
          console.log(oldVal)
        })

        // 计算属性
        const doubleCount = computed(() => count.value * 2)
        const threeCount = computed(() => count.value * 3)

        // 初始化完成之后需要进行返回
        return {
          count,
          add,
          doubleCount,
          threeCount
        }
      }

    }
</script>
3.4 Vue 3.0 中 Vue-Router的使用
  1. 首先要获取 $router(全局)$route(局部) 这两个对象首先需要获取到当前的 Vue实例。此时需要从vue中导入一个 getCurrentInstance的方法用于获取vue实例。
       /* 在vue 中导入 获取当前 Vue 实例的方法  */
    import {getCurrentInstance} from 'vue'

    export default {
      name: "index",
      // 设置数据的方法
      setup() {

        const {ctx} = getCurrentInstance()
        // 获取全局的路由对象
        console.log(ctx.$router)

        /**
         * 跳转到 about 页面
         */
        const goToAbout = () => {
          ctx.$router.push('/about')
        }

        // 获取当前路由对象
        console.log(ctx.$route)

        return {
          goToAbout
        }
      }
    }
3.5 Vue 3.0 中 Vuex 的使用
  1. vuex 中的代码:
import Vuex from 'vuex'

export default Vuex.createStore({
  state: {
    number: 100
  },
  mutations: {
    SET_NUMBER(state, value) {
      state.number = value
    }
  },
  actions: {
    setNumber({commit}, value) {
      commit('SET_NUMBER', value)
    }
  },
  modules: {
    a: {
      state: {
        aa: 10
      },
      mutations: {
        SET_AA(state, value) {
          state.aa = value
        }
      },
      getters: {
        aaValue: (state) => state.aa
      }
    },
    b: {
      state: {
        bb: 22
      },
      /**
       * 同步方法
       */
      mutations: {
        SET_BB(state, value) {
          state.bb = value
        }
      },
      /**
       * 异步方法
       */
      actions: {}
    }
  }
});

  1. 页面中的代码 :
import {getCurrentInstance, ref, computed} from 'vue'

  export default {
    name: "index",
    setup() {

      const count = ref(1)

      // 获取当前的 vue 实例
      const {ctx} = getCurrentInstance()
      // 获取 vuex 中的 state 中的值 这儿需要使用计算属性获取在后面才能改变其值
      const number = computed(() => ctx.$store.state.number)
      // 通过 mutations 修改 vuex 中的 number 值
      const updateNumber = () => {
        count.value++
        // ctx.$store.commit('SET_NUMBER', ctx.$store.state.number * 2)
        // 调用actions中的异步方法
        ctx.$store.dispatch('setNumber', ctx.$store.state.number * 3)
      }
      const aa = computed(() => ctx.$store.getters.aaValue)
      // 更新aa的值
      const updateAA = () => {
        ctx.$store.commit('SET_AA', ctx.$store.state.a.aa * 5)
      }
      return {
        number,
        updateNumber,
        aa,
        updateAA
      }
    }
  }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容