据知,vue目前稳定的版本:2.6.x,后续出 2.7.x 版本(加入部分vue3内容),维护18个月之后,除安全漏洞更新之外,其余的不再继续更新。说明将全面拥抱vue3.0时代

vue3.0在使用中兼容vue2.0的信息

一、亮点速览

1.Performance [pfmns]

  • 重写了虚拟Dom的实现(跳过静态节点,只处理动态节点)
  • update性能提高1.3~2倍
  • SSR速度提高了2~3倍

Tree shaking [ekŋ]

  • 可以将无用模块“剪辑”,仅打包需要的

Fragment ['frægmnt]

  • 不再限于模板中的单个根节点

<Teleport> [telpt]

  • 以前称为<Portal> [ptl],译作传送门

<Suspense> [sspens]

  • 可在嵌套层级中等待嵌套的异步依赖项

TypeScript

  • 更好的TypeScript支持

Custom Renderer API

  • 自定义渲染器API
  • 用户可以尝试WebGL自定义渲染器

Composition [kmpzn] API

  • 组合式API,替换原有的 Options [pnz] API
  • 根据逻辑相关性组织代码,提高可读性和可维护性
  • 更好的重用逻辑代码(避免mixins混入时命名冲突的问题)
  • 但是依然可以延用 Options [pnz] API

Proxy [prksi]

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

  • 响应式原理不再基于 Object.defineProperty

二、基于vue/cli配置vue3.0

https://github.com/vuejs/vue-next

vue-cli-plugin-vue-next
$ npm install -g @vue/cli$ vue --version$ vue create xxx$ vue add vue-next
"dependencies": {"vue": "^3.0.0-beta.1"},"devDependencies": {"@vue/compiler-sfc": "^3.0.0-beta.1","eslint-plugin-vue": "^7.0.0-alpha.0","vue-cli-plugin-vue-next": "~0.1.3"},eslintConfig": {    "extends": [      "plugin:vue/vue3-essential"    ]}

三、基于vite配置vue3.0

由 vue 作者尤雨溪开发的 web 开发工具

https://github.com/vitejs/vite

  • 基于浏览器原生 ES imports 的开发服务器(利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用)
  • 同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢
$ npm init vite-app xxx$ cd xxx$ npm install$ npm run dev$ npm run build或者$ yarn create vite-app xxx$ yarn$ yarn dev$ yarn build

四、掌握setup和响应式系统API

https://vue-composition-api-rfc.netlify.app/zh/api.html

setup

setup 函数是一个新的组件选项,作为在组件内使用 Composition API 的入口点

  • 初始化props和beforeCreate之间调用
  • 可以接收 props 和 context
  • this在setup()中不可用

props是响应式的,可以基于watchEffect/watch监听,解构赋值后则无效

export default {props: {title: String,},setup(props) {watchEffect(() => {console.log(`title is: ` + props.title);});}};

返回的结果可以直接在模板中渲染使用

export default {props: { title: String },setup() {let supNum = 0,oppNum = 0;let change = lx => {lx === 0 ? supNum++ : oppNum++;};return {supNum,oppNum,change};}};

ref

接受一个参数值并返回一个响应式且可改变的 ref 对象

  • ref 对象拥有一个指向内部值的单一属性 .value
  • 当ref在模板中使用的时候,它会自动解套,无需在模板内额外书写 .value
import { ref } from "vue";export default {setup() {let supNum = ref(0),oppNum = ref(0);let change = lx => {lx === 0 ? supNum.value++ : oppNum.value++;};return {supNum,oppNum,change};}};

reactive

接收一个普通对象然后返回该普通对象的响应式代理

等同于 2.x 的 Vue.observable()

  • 响应式转换是“深层的”:会影响对象内部所有嵌套的属性
import { ref, reactive } from "vue";export default {props: { title: String },setup() {let state = reactive({supNum: 0,oppNum: 0,arr: [10, 20]});let change = lx => {lx === 0 ? state.supNum++ : state.oppNum++;// 比Object.defineProperty好用在于:对于数据或者并未初始化的对象成员,都可以随意修改值,而且具备响应式的效果state.arr[0] = state.arr[0] + 1;state.name = "珠峰";};return {//...toRefs(state),state,change};}};

unref / toRef / toRefs / isRef / isProxy / isReactive / isReadonly

readonly

传入一个对象(响应式或普通)或 ref,返回一个原始对象的只读代理

一个只读的代理是“深层的”,对象内部任何嵌套的属性也都是只读的

const original = reactive({ count: 0 })const copy = readonly(original)watchEffect(() => {// 依赖追踪console.log(copy.count)});// original 上的修改会触发 copy 上的侦听original.count++;// 无法修改 copy 并会被警告copy.count++; // warning!

computed

传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象
const count = ref(1);const plusOne = computed(() => count.value + 1);console.log(plusOne.value); //2plusOne.value++; //错误!
或者传入一个拥有 get 和 set 函数的对象,创建一个可手动修改的计算状态
const count = ref(1);const plusOne = computed({get: () => count.value + 1,set: val => {count.value = val - 1;}});plusOne.value = 1;console.log(count.value); //0
import { ref, reactive, toRefs, computed } from "vue";export default {props: { title: String },setup() {......// 计算属性let ratio = computed({get: () => {let total = state.supNum + state.oppNum;return total === 0? "--": ((state.supNum / total) * 100).toFixed(2) + "%";}});return {......,ratio};}};

watchEffect

立即执行传入的一个函数,并响应式追踪其依赖,并在其依赖变更时重新运行该函数
export default {props: {title: String,},setup(props) {watchEffect(() => {console.log(`title is: ` + props.title);});}};

watch

watch API 完全等效于 2.x this.$watch

  • watch 需要侦听特定的数据源,并在回调函数中执行副作用
  • 默认情况是懒执行的,也就是说仅在侦听的源变更时才执行回调

侦听单个数据源

// 侦听器的数据源可以是一个拥有返回值的 getter 函数,也可以是

const state = reactive({ count: 0 })watch(() => state.count,(count, prevCount) => {/* ... */});const count = ref(0)watch(count, (count, prevCount) => {/* ... */});
import { ref, reactive, toRefs, computed, watch } from "vue";export default {setup() {....let ratio = ref("--");watch(state, (state, preState) => {let total = state.supNum + state.oppNum;ratio.value =total === 0 ? "--" : ((state.supNum / total) * 100).toFixed(2) + "%";});return {...,ratio};}};

五、掌握新生命周期函数和模板refs的使用

模板 Refs

当使用组合式 API 时,reactive refs 和 template refs 的概念已经是统一的
<template><div ref="root"></div></template><script>  import { ref, onMounted } from 'vue';  export default {    setup() {      const root = ref(null);      onMounted(() => {        console.log(root.value);      });      return {        root      };    }  }</script>

生命周期函数

可以直接导入 onXXX 一族的函数来注册生命周期钩子

  • 这些生命周期钩子注册函数只能在 setup() 期间同步使用
  • 在卸载组件时,生命周期钩子内部同步创建的侦听器和计算状态也将删除