快速上手

全局安装 vue-cli(3.0+)脚手架

1
2
npm install -g @vue/cli
vue -V // 4.5.9

image
初始化项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
vue create <projectname>
--------------------------------------------------------------
❯ .babelrc ([Vue 3] node-sass, babel, pwa, router, vuex, eslint)
Default ([Vue 2] babel, eslint)
Default (Vue 3 Preview) ([Vue 3] babel, eslint)
* Manually select features
--------------------------------------------------------------
Check the features needed for your project:
◉ Choose Vue version
◉ Babel
◉ TypeScript
◉ Progressive Web App (PWA) Support
◉ Router
◉ Vuex
◉ CSS Pre-processors
❯◉ Linter / Formatter
◯ Unit Testing
◯ E2E Testing
--------------------------------------------------------------
? Choose a version of Vue.js that you want to start the project with
2.x
3.x (Preview)
--------------------------------------------------------------
? Use class-style component syntax? (y/N) y
--------------------------------------------------------------
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfi
lls, transpiling JSX)? (Y/n)
--------------------------------------------------------------
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported
by default):
Sass/SCSS (with dart-sass)
Sass/SCSS (with node-sass)
Less
Stylus
--------------------------------------------------------------
? Pick a linter / formatter config:
ESLint with error prevention only
ESLint + Airbnb config
ESLint + Standard config
ESLint + Prettier
TSLint (deprecated)
--------------------------------------------------------------

cd <projectname>
yarn install
yarn start
open http://localhost:8080

目录结构

起步

1
2
3
4
5
6
7
8
import { createApp } from "vue";
import App from "@/App.vue";
import router from "@/router";
import store from "@/store";
import plugin from "@/config/plugin";

// vue2.x版本与现版本的区别
createApp(App).use(plugin).use(store).use(router).mount("#app");

响应式系统工具集

unref unref 是 val = isRef(val) ? val.value : val 的语法糖 unref(ref(0))===unref(0)===0 返回 number
toRef toRef 可以用来为一个 reactive 对象的属性【某个属性区别 toRefs 每一个属性】创建一个 ref。这个 ref 可以被传递并且能够保持响应性 ​const state = reactive({ foo: 1 })

//reactive 获取单个属性转为 ref【fooRef 只是一个代理】
const fooRef = toRef(state, ‘foo’)
fooRef.value++
console.log(state.foo) //2 |
| toRefs | 把一个响应式对象转换成普通对象,该普通对象的每个 property 都是一个 ref ,和响应式对象 property 一一对应 | const state = reactive({ foo: 1})
const stateAsRefs = toRefs(state)
_stateAsRefs 的类型如下: _
foo: Ref |
| isRef | 检查一个值是否为一个 ref 对象 |

|
| ref | 用于封装普通类型 | const a=ref(10);
return {a}; |

数据监听

ref 只可以监听简单数据,reactive 可以监听所有数据、
写法一:

1
2
const a = ref(1);
const b = ref(2);

写法二:

1
2
3
4
const reactive = ({
a:1
b:2
})

在这里不评价哪种合适,也没有什么准确的答案,两者的主要区别在于:一,我们使用了 2 个变量来存储值;而风格二则当作对象的属性存储。这两种风格的代码工作的都没问题,关键在于个人或团队的偏好:使用单独的变量还是使用对象封装,我觉得 ref 更偏向于第一类人,而 reactive 更偏向于第二类吧

特性

  • ref 只可以监听简单数据
  • reactive 可以监听所有数据

ref 这种写法简单,但也有弊端,经过尝试,我发现他只能监听一些如数字、字符串、布尔之类的简单数据而如果需要监听如上面代码一样的 jsonArray 我们在 vue2 种都会使用$set 来进行变更,到了 vue3 我们终于可以愉快的使用 reactive 来实现了。

使用方式

  • ref 修改数据需要使用这样 count.value=xxx 的形式,而 reactive 只需要 state.reactiveField=值这样来使用
  • 第二点体现在 template 中引用时候为 reactiveField,不需要 state,也就是说我 reactive 对象里面字段是应该直接使用的
  • 体现在 reactive 在 return 时候需要 toRefs 来转换成响应式对象

生命周期

2.x 生命周期列表如下:

1
2
3
4
5
6
7
8
9
10
beforeCreate -> setup()
created -> setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount 组件卸载之前执行
destroyed -> onUnmounted
activated -> onActivated 中切换组件(组件激活)
deactivated -> onDeactivated 中切换组件(组件不激活)

3.x 生命周期变化
errorCaptured -> onErrorCaptured
onRenderTracked
onRenderTriggered

  1. beforeDestroy\destroyed 被替换为了 onBeforeUnmount、onUnmounted
  2. 去掉了 beforeCreate、created 直接使用 setup
  3. 新增了 onRenderTracked、onRenderTriggered(两个钩子都是到 DebuggerEvent 类似于 onTrack 和 onTrigger 观察者的选项)
vue2.0 vue3.0
beforeCreate setup
created setup
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount
destroyed onUnmounted
errorCaptured onErrorCaptured

新增方法

| v-is | 本节只影响在页面的 HTML 中直接编写 Vue 模板的情况
警告 v-is 功能 像一个动态 2.x :is
绑定 所以要根据注册的名称渲染组件,它的值应该是一个 JavaScript 字符串 |
<trv-is=”blog-post-row”>

<trv-is=”‘blog-post-row’”>

计算属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>
{{cop}}
</div>
</template>

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

export default {
name: "Test",
setup() {
const arr= ref([1,2,3,4,5])
// 计算属性
const cop = computed(() => arr.reverse());
return {
cop,
arr
};
}
};
</script>

监听数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<template>
<div>
<input v-model="count" />
<!-- gaocaipeng haonan -->
</div>
</template>
<script>
import { ref, watch } from "vue";
export default {
setup() {
// 定义响应式数据 count
const count = ref("");
// 定义 watch 监听
watch(
count,//新值 旧值
(newProps, usedProps) => {
// 执行异步任务
console.log(newProps, usedProps);//gaocaipeng haonan
},
// watch 刚被创建的时候不执行
{ lazy: true }
);
return {
count,
};
},
};
</script>
<style lang="scss" scoped></style>

事件对象:

  • key 那边变量发生了变化
  • newValue 更新后变量的值
  • oldValue 更新前变量的值
  • target 目前页面中的响应变量和函数
1
2
3
4
5
6
7
8
9
10
11
12
<script>
export default {
onRenderTracked((event) => {
console.log("vue3 状态跟踪组件----------->onRenderTracked");
console.log(event);
});
onRenderTriggered((event) => {
console.log("vue3 状态触发组件--------------->onRenderTriggered");
console.log(event);
});
}
</script>

路由

获取路由

1
2
3
4
5
6
7
8
9
10
11
<script>
import { getCurrentInstance } from 'vue' ;
export default {
setup() {
// getCurrentInstance方法,用来获取当前组件实例,然后通过ctx获取当前上下文
const { ctx } = getCurrentInstance()
console.log(ctx); // ctx代表vue2中的this
}
}

</script>

404 配置

按照 vue2.x 配置 404 页面会有下面报错,我们可以:
caught Error: Catch all routes (“*“) must now be defined using a param with a custom regexp.

1
2
3
4
5
{
path: "/:catchAll(.*)",
name: "404",
component: () => import("@/containers/notFound")
}

状态管理

依然可以使用 vuex 官方状态管理容器管理共享状态,下面是使用方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
import { useStore } from 'vuex'

export default {
setup(){
const store = useStore(); // 相当于 vue2中的 this.$store
store.dispatch(); // 通过store对象来dispatch 派发异步任务
store.commit(); // commit 修改store数据
return {
category:computed(() => store.state.home.currentCagegory
}
}
}
</script>