1. 项目初始化
1.1 安装 vue-cli
- 第一步安装
vue-cli
:注意! 如果在vue2
中已经安装过这里就不需要再安装了。
npm install -g @vue/cli
- 以下安装方式是错误的:
npm install -g vue
npm install -g vue-cli
- 安装成功后,我们即可使用
vue
命令,测试方法:
vue -V
1.2 初始化 vue 项目
- 使用
vue2.0
中创建项目的方式创建项目 :
vue create project-name
- 输入命令后,会出现命令行交互窗口,这里我们选择
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
注意:在初始化项目的时候需要对
Router
、Vuex
进行同时安装。因为此时项目还属于使用vue 2.0
创建,如果后期升级vue3.0
时可以同时升级Router
和Vuex
的版本。
小提示: 回车后会自动安装依赖,为了加速安装速度,我们可以使用淘宝源来加快初始化速度 。
vue create -r https://registry.npm.taobao.org project-name
2. 升级为 Vue 3.0 项目
- 目前创建
Vue 3.0
项目需要通过插件升级的方式来实现,vue-cli
还没有直接支持,我们进入项目目录,并输入以下指令:
cd project-name // 切换到项目目录下
vue add vue-next
- 执行上述指令后,会自动安装 vue-cli-plugin-vue-next 插件(查看vue3.0项目代码),该插件会完成以下操作:
- 安装
Vue 3.0
依赖;- 更新
Vue 3.0 webpack loader
配置,使其能够支持.vue
文件构建(这点非常重要);- 创建
Vue 3.0
的模板代码;- 自动将代码中的
Vue Router
和Vuex
升级到4.0
版本,如果未安装则不会升级;- 自动生成
Vue Router
和Vuex
模板代码。
完成上述操作后,项目正式升级到
Vue 3.0
,注意该插件还不能支持typescript
。在升级为
Vue 3.0
版本之后启动项目报如下错误 :
ERROR Error: Cannot find module 'vue-loader-v16/package.json'
2.1 解决升级 vue 3.0 之后 vue-loader-v16找不到问题
查询资料找到一篇文章中的解决方案: vue3项目报错 Error: Cannot find module ‘vue-loader-v16/package.json‘
升级
npm
npm i -g npm
- 删除并重新安装
node_modules
依赖包
npm i
- 重新下载
vue-loader-v16
cnpm i -D vue-loader-v16
3. Vue 3.0 基本特性的体验
3.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>
- 之后在
/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
- 初始化
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(一)
/* 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中状态和事件绑定 、计算属性和监听器
-
Vue 3.0
中定义状态的方法改为类似React Hooks
的方法,下面我们在CompositionApiContinue.vue
中定义一个状态count
: 从vue
中导入ref
对状态进行初始化
// 初始化 count 的值为 1
const count = ref(1)
-
Vue 3.0
中初始化状态通过setup
方法,定义状态需要调用ref
方法。接下来我们定义一个事件,用来更新count
状态:注意这里对count的修改需要修改count的value属性。
const add = () => {
// 对状态的值进行改变 需要使用 value
count.value++
}
- 这些定义好的状态和事件需要通过
return
返回一个对象进行返回:
// 初始化完成之后需要进行返回
return {
count,
add,
doubleCount,
threeCount
}
- 使用
watch
监听状态的改变: 需要在vue
中导入watch
函数
// 使用 watch 监听值的改变
/**
* 注意watch 传递的第一个参数需要是函数的返回值
*/
watch(() => count.value, (newVal, oldVal) => {
console.log(newVal)
console.log(oldVal)
})
- 使用
Vue3.0
中的计算属性,需要在Vue
中导入computed
函数:
// 计算属性
const doubleCount = computed(() => count.value * 2)
const threeCount = computed(() => count.value * 3)
- 完整代码:
<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的使用
- 首先要获取
$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 的使用
-
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: {}
}
}
});
- 页面中的代码 :
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
}
}
}