邂逅Vue3开发体验
Vue
认识Vue
Vue(读音/vju:/)是一套用于构建用户界面的渐进式框架。
- 全称为Vue.js或Vuejs
- 渐进式框架的含义:可以在项目中一点点引入和使用Vue,而不一定需要使用Vue来开发整个项目。
Vue在前端中的地位
目前前端最流行的三大框架:Vue、React、Angular。
- Angular:入门门槛较高,国内市场占有率较低,本身非常优秀
- React:在国内外市场占有率非常高,作为前端工程师必须学习的一个框架
- Vue:在国内市场占有率最高,几乎所有前端岗位都会对Vue有要求。
数据对比:
Vue3
2020年9月19日,Vue3发布了正式版,命名为One Piece。
新特性:更好的性能、更小的包体积、更好的TypeScript集成、更优秀的API设计。
Vue3带来的变化(源码)
源码通过monorepo的形式来管理源代码:
- Mono 单个 Repo:repository仓库
- 主要是将许多项目的代码存储在同一个repository中
- 这样做的目的是多个包本身相互独立,可以有自己的功能逻辑、单元测试等,同时又在一个仓库下方便管理。
- 模块划分更清晰,可维护性、可拓展性更强
源码使用TypeScript来进行重写:
- 在Vue2.x时,Vue使用Flow来进行类型检测
- 在Vue3.x时,Vue的源码全部使用TypeScript来进行重构,并且Vue本身对于TypeScript支持也更好了
Vue3带来的变化(性能)
使用Proxy进行数据劫持
- 在Vue2.x时,使用Object.defineProperty来劫持数据的getter和setter方法
- 这种方式一致存在的一个缺陷就是当给对象添加或者删除属性时,是无法劫持和监听的
- 所以在Vue2.x时,不得不提供一些特殊的API,比如set或set或set或delete,事实上都是一些hack方法,增加了开发者学习新API的成本
- 而在Vue3.x开始,Vue使用Proxy来实现数据劫持
删除了一些不必要的API:
- 移除了实例上的on,on,on,off和$once
- 移除了一些特性:如filter、内联模板等
包括编译方面的优化
- 生成Block Tree、Slot编译优化、diff算法优化
Vue3带来的变化(新的API)
由Options API到Composition API
-
在Vue2.x的时候,通过Options API来描述组件对象,包括data、props、methods、computed、生命周期等等选项,存在比较大的问题是多个逻辑可能是在不同的地方。
如created中会使用某一个method来修改data数据,代码的内聚性非常差。
-
Composition API可以将相关联的代码放到同一处进行处理,而不需要在多个Options之间寻找
Hooks函数增加代码复用性:
- 在Vue2.x时,通常通过mixins在多个组件之间共享逻辑,但是有一个很大的缺陷就是mixins也是由一大堆的Options组成的,并且多个mixins会存在命名冲突的问题;
- 在Vue3.x中,可以通过Hook函数,将一部分独立的逻辑抽取出去,并且它们可以做到是响应式的
如何使用Vue
Vue的本质就是一个JavaScript库,使用该库的方式:
- 在页面中通过CDN方式来引入
- 下载Vue的JavaScript文件,并且自己手动引入
- 通过npm包管理工具安装使用它(webpack部分再提)
- 直接通过Vue CLI创建项目,并且使用它
CDN引入
CDN称为内容分法网络(Content Delievery Network或Content Distribution Network)。
- 指通过相互连接的网络系统,利用最靠近每个用户的服务器,更快、更可靠地将音乐、图片、视频、应用程序及其他文件发送给用户。
- 来提供高性能、可拓展性及低成本的网络内容传递给用户
常用CDN服务器分为两类:
- 自己的CDN服务器:需要购买,阿里、腾讯、亚马逊、谷歌等都可以购买
- 开源CDN服务器:国际上使用较多的是unpkg、JSDelivr、cdnjs。
Vue的CDN引入
<script src="https://unpkg.com/vue@next"></script>
引入示例如下:
<body>
<div id="app"></div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const why = {
template: "<h2>hello world</h2>",
};
const app = Vue.createApp(why);
app.mount("#app"); //mount()表示要将代码显示的部分挂载到什么位置,即挂载到属性为app的div元素上
</script>
</body>
效果即为在网页中展示hello world字样:
下载和引入
通过打开刚才的CDN链接可以下载Vue的源码:
- 打开链接,复制其中所有的代码;
- 创建一个新的文件,比如
vue.js
,将代码复制到其中。
通过 script
标签,引入刚才的文件:
<script src="../js/vue.js"></script>
案例实现:
<div id="app"></div>
<script src="../js/vue.js"></script>
<script>
Vue.createApp({
template: "<h2>你好哇,帅哥</h2>",
}).mount("#app");
</script>
计数器案例
如果我们希望实现一个计数器的案例:
- 点击+1,内容会显示数字+1
- 点击-1,内容会显示数字-1
可以选择很多种方式实现:对比原生和Vue的实现方式的不同。
-
原生实现:
<h2 class="counter">0</h2> <button class="increment">+1</button> <button class="decrement">-1</button> <script> //1.获取所有元素 const counterEl = document.querySelector(".counter"); const incrementEl = document.querySelector(".increment"); const decrementEl = document.querySelector(".decrement"); //2.定义变量 let counter = 100; counterEl.innerHTML = counter; //3.监听按钮的点击 incrementEl.addEventListener("click", () => { counter += 1; counterEl.innerHTML = counter; }); decrementEl.addEventListener("click", () => { counter -= 1; counterEl.innerHTML = counter; }); </script>
-
Vue实现:
<div id="app"></div> <script src="../js/vue.js"></script> <script> Vue.createApp({ template: ` <div> <h2>{{counter}}</h2> <button @click='increment'>+1</button> <button @click='decrement'>-1</button> </div> `, data: function () { return { counter: 100, }; }, //定义各种方法 methods: { increment() { console.log("点击了+1"); this.counter++; }, decrement() { console.log("点击了-1"); this.counter--; }, }, }).mount("#app"); </script>
声明式和命令式
原生开发和Vue开发的模式和特点,其实涉及到两种不同的编程范式:命令式编程和声明式编程。命令式编程关注的是“how to do”,声明式编程关注的是“what to do”,由框架(机器)完成“how”的过程。
- 原生实现过程中,每完成一个操作,都要通过JavaScript编写一条代码,来给浏览器一条指令。这样的编写过程,称之为命令式编程。在早期的原生JavaScript和jQuery开发的过程中,都是通过这种方式编写代码的。
- 在Vue实现过程中,我们会在createApp传入的对象中声明需要的内容,模板template、数据data、方法methods。这样的编写代码的过程,称之为声明式编程。目前Vue、React、Angular的编程模式,称之为声明式编程。
MVVM模型
MVC和MVVM都是一种软件的体系结构:
-
MVC是Model-View-Controller的简称,是在前期被使用非常多的架构模式,比如iOS、前端。
-
MVVM是Model-View-ViewMode的简称,是目前非常流行的架构模式。
通常情况下,称Vue是一个MVVM的框架。Vue官方其实有说明,Vue虽然没有完全遵守MVVM的模型,但是整个设计是受到它的启发的。
Vue属性
template属性
在使用createApp的时候,我们传入了一个对象,接下来我们详细解析一下之前传入的属性分别代表什么含义。
template属性:表示Vue需要帮助我们渲染的模版信息。目前我们看到它里面有很多HTML标签,这些标签会替换掉我们挂载到的元素(比如id为app的div)的innerHTML;模板还有一些特有的语法,比如{{}}
、@click
。
但这个模板的写法IDE可能没有任何提示,会阻碍我们的编程效率。
Vue提供两种方式解决这个问题:
-
写法一:使用script标签,并且标记它的类型为
x-template
。<script type="x-template" id="why"> <div> <h2>{{counter}}</h2> <button @click='increment'>+1</button> <button @click='decrement'>-1</button> </div> </script> <script src="../js/vue.js"></script>
template: "#why"
-
写法二:使用任意标签(通常使用
template
标签,因为不会被浏览器渲染),设置idtemplate
元素是一种用于保存客户端内容的机制,该内容在加载页面时不会被呈现,但随后可以在运行时使用JavaScript实例化。
<template id="why"> <div> <h2>{{counter}}</h2> <button @click="increment">+1</button> <button @click="decrement">-1</button> </div> </template>
template: "#why"
-
这个时候,在
createApp
的对象中,我们需要传入的template
以#
开头。如果字符串是以#
开始,那么它将被用作querySelector
,并且使用匹配元素的innerHTML
作为模板字符串。
data属性
data属性是传入一个函数,并且该函数需要返回一个对象;
- 在Vue2.x的时候,也可以传入一个对象(虽然官方推荐是一个函数)
- 在Vue3.x的时候,只能传入一个函数,否则就会直接在浏览器中报错
data返回的对象会被Vue的响应式系统劫持,之后对该对象修改或者访问都会在劫持中被处理。所以我们在template中通过 {{counter}}
访问counter,可以从对象中获取到数据。修改counter的值时,template中的 {{counter}}
也会发生改变。
methods属性
methods属性是一个对象,通常我们会在这个对象中定义很多的方法。这些方法可以被绑定到template模板中。在该方法中,我们可以使用this关键字来直接访问到data中返回的对象的属性。
官方文档有这么一段描述:
其他属性
还可以定义很多其他属性:比如props、computed、watch、emits、setup等。也包括很多生命周期函数。
Vue的源码
-
下载源码:下载地址(推荐通过git clone下载)
-
安装Vue源码相关依赖,执行
yarn install
-
对项目执行打包操作,执行
yarn dev
(执行前修改脚本) -
通过
packages/vue/dist/vue.global.js
调试代码
转载自:https://juejin.cn/post/7235309338096713788