Vue 3.0 全家桶抢先体验


Posted in Javascript onApril 28, 2020


Vue 3.0 全家桶发布内容包括:

  • vue: Beta
  • vue-router: Alpha
  • vuex: Alpha
  • vue-class-component: Alpha
  • vue-cli: Experimental support via vue-cli-plugin-vue-next
  • eslint-plugin-vue: Alpha
  • vue-test-utils: Alpha
  • vue-devtools: WIP
  • jsx: WIP

可以看到 Vue 3.0 beta 版本是一个项目系列,包含了我们在开发过程中需要的套件、webpack 插件等等,本文将带大家快速搭建基于 Vue 3.0 的项目框架,这和之前很多 Vue 3.0 的 Demo 不同,是具备商业化项目能力的框架,本文将包括以下内容:

  • 基于 vue-cli 快速搭建 Vue 3.0 项目
  • Vue 3.0 基本特性体验
  • 集成 vue-router 和 vuex 4.0

说个题外话,今天中午我搭建 Vue 3.0 项目时,发现了 vue-router-next 一个 block 级别的 BUG,想在 vue-router-next 项目 issue 中反馈时,发现已经有人提交了相似问题,随后晚上测试时,bug 已经被 fixed,为 Vue 团队的高效点赞,issue 地址,所以当大家发现使用中问题时,可以及时到项目 issue 下进行反馈,这是一支可以信赖的团队!

Vue 3.0 项目初始化

Vue 3.0 项目初始化过程和 Vue 2.0 类似,具体步骤如下:

Vue 项目初始化

第一步,安装 vue-cli:

npm install -g @vue/cli

注意以下命令是错误的!

npm install -g vue
npm install -g vue-cli

安装成功后,我们即可使用 vue 命令,测试方法:

$ vue -V
@vue/cli 4.3.1

第二步,初始化 vue 项目:

vue create vue-next-test

输入命令后,会出现命令行交互窗口,这里我们选择 Manually select features:

Vue CLI v4.3.1
? Please pick a preset: 
 default (babel, eslint) 
❯ Manually select features

随后我们勾选:Router、Vuex、CSS Pre-processors 和 Linter / 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

注意:Vue 3.0 项目目前需要从 Vue 2.0 项目升级而来,所以为了直接升级到 Vue 3.0 全家桶,我们需要在 Vue 项目创建过程中勾选 Router 和 Vuex,所以避免手动写初始化代码

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

vue create -r https://registry.npm.taobao.org vue-next-test

项目创建完毕后,目录结构如下:

.
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
│  ├── favicon.ico
│  └── index.html
└── src
  ├── App.vue
  ├── assets
  │  └── logo.png
  ├── components
  │  └── HelloWorld.vue
  ├── main.js
  ├── router
  │  └── index.js
  ├── store
  │  └── index.js
  └── views
    ├── About.vue
    └── Home.vue

升级 Vue 3.0 项目

目前创建 Vue 3.0 项目需要通过插件升级的方式来实现,vue-cli 还没有直接支持,我们进入项目目录,并输入以下指令:

cd vue-next-test
vue add vue-next

执行上述指令后,会自动安装 vue-cli-plugin-vue-next 插件(查看项目代码),该插件会完成以下操作:

  • 安装 Vue 3.0 依赖
  • 更新 Vue 3.0 webpack loader 配置,使其能够支持 .vue 文件构建(这点非常重要)
  • 创建 Vue 3.0 的模板代码
  • 自动将代码中的 Vue Router 和 Vuex 升级到 4.0 版本,如果未安装则不会升级
  • 自动生成 Vue Router 和 Vuex 模板代码

完成上述操作后,项目正式升级到 Vue 3.0,注意该插件还能支持 typescript,用 typescript 的同学还得再等等。

Vue 3.0 基本特性体验

下面我们从项目开发的角度逐步体验 Vue 3.0 的开发流程

创建路由

项目开发中,我们通常需要创建新页面,然后添加路由配置,我们在 /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>

之后在 /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',
  component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
 },
 {
  path: '/test',
  name: 'Test',
  component: () => import(/* webpackChunkName: "test" */ '../views/Test.vue')
 }
]

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

export default router

初始化 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>

启动项目:

npm run serve

在浏览器中访问项目地址,此时已经可以跳转到 Test 页面:

Vue 3.0 全家桶抢先体验

状态和事件绑定

Vue 3.0 中定义状态的方法改为类似 React Hooks 的方法,下面我们在 Test.vue 中定义一个状态 count:

<template>
 <div class="test">
  <h1>test count: {{count}}</h1>
 </div>
</template>

<script>
 import { ref } from 'vue'

 export default {
  setup () {
   const count = ref(0)
   return {
    count
   }
  }
 }
</script>

Vue 3.0 中初始化状态通过 setup 方法,定义状态需要调用 ref 方法。接下来我们定义一个事件,用来更新 count 状态:

<template>
 <div class="test">
  <h1>test count: {{count}}</h1>
  <button @click="add">add</button>
 </div>
</template>

<script>
 import { ref } from 'vue'

 export default {
  setup () {
   const count = ref(0)
   const add = () => {
    count.value++
   }
   return {
    count,
    add
   }
  }
 }
</script>

这里的 add 方法不再需要定义在 methods 中,但注意更新 count 值的时候不能直接使用 count++,而应使用 count.value++,更新代码后,点击按钮,count 的值就会更新了:

Vue 3.0 全家桶抢先体验

计算属性和监听器

Vue 3.0 中计算属性和监听器的实现依赖 computed 和 watch 方法:

<template>
 <div class="test">
  <h1>test count: {{count}}</h1>
  <div>count * 2 = {{doubleCount}}</div>
  <button @click="add">add</button>
 </div>
</template>

<script>
 import { ref, computed, watch } from 'vue'

 export default {
  setup () {
   const count = ref(0)
   const add = () => {
    count.value++
   }
   watch(() => count.value, val => {
    console.log(`count is ${val}`)
   })
   const doubleCount = computed(() => count.value * 2)
   return {
    count,
    doubleCount,
    add
   }
  }
 }
</script>

计算属性 computed 是一个方法,里面需要包含一个回调函数,当我们访问计算属性返回结果时,会自动获取回调函数的值:

const doubleCount = computed(() => count.value * 2)

监听器 watch 同样是一个方法,它包含 2 个参数,2 个参数都是 function:

watch(() => count.value, 
 val => {
  console.log(`count is ${val}`)
 })

第一个参数是监听的值,count.value 表示当 count.value 发生变化就会触发监听器的回调函数,即第二个参数,第二个参数可以执行监听时候的回调

获取路由

Vue 3.0 中通过 getCurrentInstance 方法获取当前组件的实例,然后通过 ctx 属性获得当前上下文,ctx.$router 是 Vue Router 实例,里面包含了 currentRoute 可以获取到当前的路由信息

<script>
 import { getCurrentInstance } from 'vue'

 export default {
  setup () {
   const { ctx } = getCurrentInstance()
   console.log(ctx.$router.currentRoute.value)
  }
 }
</script>

Vuex 集成

Vuex 的集成方法如下:

定义 Vuex 状态

第一步,修改 src/store/index.js 文件:

import Vuex from 'vuex'

export default Vuex.createStore({
 state: {
  test: {
   a: 1
  }
 },
 mutations: {
  setTestA(state, value) {
   state.test.a = value
  }
 },
 actions: {
 },
 modules: {
 }
})

Vuex 的语法和 API 基本没有改变,我们在 state 中创建了一个 test.a 状态,在 mutations 中添加了修改 state.test.a 状态的方法: setTestA

引用 Vuex 状态

第二步,在 Test.vue 中,通过计算属性使用 Vuex 状态:

<template>
 <div class="test">
  <h1>test count: {{count}}</h1>
  <div>count * 2 = {{doubleCount}}</div>
  <div>state from vuex {{a}}</div>
  <button @click="add">add</button>
 </div>
</template>

<script>
 import { ref, computed, watch, getCurrentInstance } from 'vue'

 export default {
  setup () {
   const count = ref(0)
   const add = () => {
    count.value++
   }
   watch(() => count.value, val => {
    console.log(`count is ${val}`)
   })
   const doubleCount = computed(() => count.value * 2)
   const { ctx } = getCurrentInstance()
   console.log(ctx.$router.currentRoute.value)
   const a = computed(() => ctx.$store.state.test.a)
   return {
    count,
    doubleCount,
    add,
    a
   }
  }
 }
</script>

这里我们通过计算属性来引用 Vuex 中的状态:

const a = computed(() => ctx.$store.state.test.a)

ctx 是上节中我们提到的当前组件实例

更新 Vuex 状

更新 Vuex 状态仍然使用 commit 方法,这点和 Vuex 3.0 版本一致:

<template>
 <div class="test">
  <h1>test count: {{count}}</h1>
  <div>count * 2 = {{doubleCount}}</div>
  <div>state from vuex {{a}}</div>
  <button @click="add">add</button>
  <button @click="update">update a</button>
 </div>
</template>

<script>
 import { ref, computed, watch, getCurrentInstance } from 'vue'

 export default {
  setup () {
   const count = ref(0)
   const add = () => {
    count.value++
   }
   watch(() => count.value, val => {
    console.log(`count is ${val}`)
   })
   const doubleCount = computed(() => count.value * 2)
   const { ctx } = getCurrentInstance()
   console.log(ctx.$router.currentRoute.value)
   const a = computed(() => ctx.$store.state.test.a)
   const update = () => {
    ctx.$store.commit('setTestA', count)
   }
   return {
    count,
    doubleCount,
    add,
    a,
    update
   }
  }
 }
</script>

这里我们点击 update a 按钮后,会触发 update 方法,此时会通过 ctx.$store.commit 调用 setTestA 方法,将 count 的值覆盖 state.test.a 的值

总结

通过我第一时间体验 Vue 3.0-beta 版本后,感觉 Vue 3.0 已经具备了商业项目开发的必备条件,语法精炼,不管是代码可读性还是运行效率都非常赞。但由于未深入使用,目前还无法提出更多问题,需要在项目实战中进一步发现和总结问题,再和大家分享交流。

到此这篇关于Vue 3.0 全家桶抢先体验的文章就介绍到这了,更多相关Vue 3.0 全家桶内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木! 

Javascript 相关文章推荐
jquery 模式对话框终极版实现代码
Sep 28 Javascript
JavaScript Event学习第八章 事件的顺序
Feb 07 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
Jun 17 Javascript
浅谈js控制li标签排序问题 js调用php函数的方法
Oct 16 Javascript
用jQuery的AJax实现异步访问、异步加载
Nov 02 Javascript
jquery实现瀑布流效果 jquery下拉加载新数据
Dec 12 Javascript
JS前向后瞻正则表达式定义与用法示例
Dec 27 Javascript
关于Stream和Buffer的相互转换详解
Jul 26 Javascript
vue 本地环境跨域请求proxyTable的方法
Sep 19 Javascript
基于JavaScript 实现拖放功能
Sep 12 Javascript
Weex开发之WEEX-EROS开发踩坑(小结)
Oct 16 Javascript
Vuejs通过拖动改变元素宽度实现自适应
Sep 02 Javascript
React生命周期原理与用法踩坑笔记
Apr 28 #Javascript
js最全的数组的降维5种办法(小结)
Apr 28 #Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
Apr 28 #Javascript
React中Ref 的使用方法详解
Apr 28 #Javascript
在Webpack中用url-loader处理图片和字体的问题
Apr 28 #Javascript
react PropTypes校验传递的值操作示例
Apr 28 #Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
Apr 28 #Javascript
You might like
提高PHP编程效率 引入缓存机制提升性能
2010/02/15 PHP
深入理解PHP原理之异常机制
2010/08/21 PHP
sphinx增量索引的一个问题
2011/06/14 PHP
PHPMYADMIN导入数据最大为2M的解决方法
2012/04/23 PHP
php中的一些数组排序方法分享
2012/07/20 PHP
Php无限级栏目分类读取的实现代码
2014/02/19 PHP
jquery+php+ajax显示上传进度的多图片上传并生成缩略图代码
2014/10/15 PHP
php实现可用于mysql,mssql,pg数据库操作类
2014/12/13 PHP
JQuery中的ready函数冲突的解决方法
2010/05/17 Javascript
防止jQuery ajax Load使用缓存的方法小结
2014/02/22 Javascript
jquery默认校验规则整理
2014/03/24 Javascript
关于数据与后端进行交流匹配(点亮星星)
2016/08/03 Javascript
关于 jQuery Easyui异步加载tree的问题解析
2016/12/06 Javascript
Angular JS 生成动态二维码的方法
2017/02/23 Javascript
详解javascript replace高级用法
2019/02/17 Javascript
150行代码带你实现微信小程序中的数据侦听
2019/05/17 Javascript
解决layui数据表格Date日期格式的回显Object的问题
2019/09/19 Javascript
Json实现传值到后台代码实例
2020/06/30 Javascript
JavaScript实现HTML导航栏下拉菜单
2020/11/25 Javascript
jQuery使用hide()、toggle()函数实现相机品牌展示隐藏功能
2021/01/29 jQuery
详解Django中的form库的使用
2015/07/18 Python
Python中的左斜杠、右斜杠(正斜杠和反斜杠)
2016/08/30 Python
django使用xlwt导出excel文件实例代码
2018/02/06 Python
Python切片工具pillow用法示例
2018/03/30 Python
python 随机打乱 图片和对应的标签方法
2018/12/14 Python
python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
2019/06/27 Python
Python之虚拟环境virtualenv,pipreqs生成项目依赖第三方包的方法
2019/07/23 Python
印度最大的网上花店:Ferns N Petals(鲜花、礼品和蛋糕)
2017/10/16 全球购物
简历自我评价模版
2014/01/31 职场文书
2014道德模范事迹材料
2014/02/16 职场文书
《小猪家的桃花树》教学反思
2014/04/11 职场文书
面试自我介绍演讲稿
2014/04/29 职场文书
初中教师个人总结
2015/02/10 职场文书
2015年城乡环境综合治理工作总结
2015/07/24 职场文书
2016领导干部廉洁从政心得体会
2016/01/19 职场文书
python运算符之与用户交互
2022/04/13 Python