从一个工做多年的Vue初学者角度学习Vue3:初识Vue组件

本文字数:4708,阅读彻底文大约要花费30分钟。css

一直以为框架只是工具,工做中用不上就不必去学,要用的时候再去学习便可。html

因此对国内很是火爆的Vue框架也只有一个初浅的印象:前端

  • Vue是一个渐进式的JavaScript框架
  • Vue2经过defineProperty拦截对象实现响应式,而Vue3则改为了Proxy实现响应式
  • Vue3增长了Composite API以解决代码复用和可维护性问题

为了拓展DevUI的生态,让DevUI的最佳实践可以服务更多的开发者,今年3月份咱们在社区正式发起了Vue DevUI开源项目,吸引了不少社区小伙伴们的加入。vue

目前已经有35+位组件田主认领了60+个组件👏🎉🥳react

如下是贡献者花名册:git

gitee.com/devui/vue-d…github

我正好也利用这个契机,系统地学习了一遍Vue3,趁着刚学完,从初学者的角度总结Vue3的关键特性(只是从我我的的角度,不必定彻底按照文档来)。typescript

本文从如下技术栈的角度进行阐述:api

💡提示:截止到2021年8月7日,以上库/框架的版本都是最新版本。浏览器

文章较长,若是想直接看小结,能够跳转到如下章节: 6 小结

1 先跑起来再说

对于一个小白来讲,要学习一门新技术,最快的方式就是:

先跑起来再说

跑起来以后,咱们会对这门新技术有一个直观的印象,后续看文档也会更清晰。

另外就是要多思考,带着问题去学习,记忆会更深入,也更容易理解其中的原理。

后续咱们学习过程当中学到的新知识点,我都会加上官网的连接,不过这些官网资料只是一个进一步学习的参考,关键是咱们本身要有思考,并带着问题去学习。

Vite是尤大大比较推荐的开发Vue3的工具,据说很是丝滑,因此第一步先建一个Vite的工程跑起来。

直接参考官网的开始章节,一个命令就搞定啦:

yarn create vite learning-vue3 --template vue-ts
复制代码

--template这个参数是选择一个工程模板,咱们选择的是vue-tsVue 3 + Typescript + Vite

Vite除了建立Vue的工程,还能够建立React/Preact/Svelte等多种框架的工程。

Vite果真很是快,不到3s就建立了一个基本的脚手架工程。

$ yarn create vite learning-vue3 --template vue-ts
yarn create v1.22.10
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...

success Installed "create-vite@2.5.4" with binaries:
      - create-vite
      - cva
[###########################################################################################################################################################################################################] 232/232
Scaffolding project in /devui/kagol/learning-vue3...

Done. Now run:

  cd learning-vue3
  yarn
  yarn dev

✨  Done in 2.69s.
复制代码

并且很是友好地提示咱们下一步要执行的命令:

Done. Now run:

  cd learning-vue3
  yarn
  yarn dev
复制代码

按照提示操做,咱们很快就能将项目跑起来了!

vite.png

2 Vue组件初步印象

启动画面最底下,有一个指引,让咱们编辑components/HelloWorld.vue这个文件,测试下热更新(HMR)的功能。

咱们找到这个文件HelloWorld.vue,不着急修改它,先来观察下它的结构。

这个文件是以.vue为文件后缀的,表明这是一个Vue组件

一个Vue组件包含三个部分:

  • 最顶部是一个<template>标签
  • 中间是一个<script lang="ts">标签
  • 最下面是一个<style scoped>标签

HelloWorld.vue.png

这和咱们最先学习前端编写html页面的结构是同样的,将HTML/CSS/JavaScript分红三个区块。

不过咱们仍是注意到一点不一样:

  • HTML部分是用<template>这个特殊的标签包裹起来的;
  • <script>部分多了一个lang="ts"属性,表明支持TypeScript
  • <style>部分多了一个scoped属性,表明局部样式,即:这里面写的样式只针对当前这个Vue组件。

以上就是目前观察到的Vue组件的基本特色。

3 <template>分析

咱们把<template>/<script>/<style>三个标签展开,看下里面的结构。

先看下<template>,里面元素比较多,先都收起来,看下大体结构。

template.png

咱们注意到里面就是一些html元素,彷佛和写html没什么区别,不过仔细一看,还有会有些不一样:

  • 首先就是第2行的双大括号包裹的部分{{ msg }},这和咱们以前写的html有点不同,这是一种Vue的模板语法,叫文本插值,里面的msg是组件的变量,变量的值会被渲染到<h1>标签里面。
<h1>{{ msg }}</h1>
复制代码
  • 第30行是一个<button>标签,咱们很熟悉它是一个按钮,里面也有一个文本插值,绑定的是count变量,还有一个@click属性咱们没见过,这是Vue事件绑定的语法,绑定了button的点击事件。
<button type="button" @click="count++">count is: {{ count }}</button>
复制代码

Vite热更新 - template

咱们尝试修改下template里面的内容,好比将最后一行的:

hot module replacement.
复制代码

改为

hot module replacement(HMR).
复制代码

看下页面会有什么变化。

Vite热更新-template.gif

从以上动图能够看出,修改完template中的内容,一保存文件,页面内容立马刷新,几乎没有任何延迟,页面也没有刷新,开发体验很是丝滑。

猫猫震惊.gif

4 <script>分析

这部分是全文的核心部分,内容较长,若是想直接看本章节的小结,能够点击直通车连接: 4.9 小结

模板部分咱们已经有了一个初步的了解,再来看看脚本部分。

script.png

4.1 导入Vue方法

脚本的第一行从vue导入了两个方法:

  • ref:返回一个响应式且可变的ref对象;
  • defineComponent:用来定义一个同步的Vue组件。
import { ref, defineComponent } from 'vue'
复制代码

这两个方法是高频方法,必须紧紧记住。

4.2 导出Vue组件

第39行导出了一个Vue组件。

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: {
      type: String,
      required: true
    }
  },
  setup: () => {
    const count = ref(0)
    return { count }
  }
})
复制代码

Vue组件经过defineComponent方法来定义,该方法的参数是一个对象,该对象有3个属性:

  • name:一个字符串,表明组件的名字;
  • props:一个对象,表明组件的入参,也就是组件与外部进行交互的一个口子,外部使用组件时,能够经过props往组件内部传递数据;
  • setup:一个箭头函数,这是Vue3新推出的Composite API的入口,会在组件建立以前、props被解析以后执行。

4.3 组件入参

第42行定义了一个msg变量,以前咱们在template中已经见过它,但是它的值是什么呢?

props: {
    msg: {
      type: String,
      required: true
    }
  },
复制代码

咱们注意到msg是嵌套在props里面的,表明它是组件的一个入参,是组件与外部交互的API,那么它的值就应该是从外部传进来的。

从哪儿传进来的呢?使用组件是经过它的名字name来使用的,因此咱们在源代码里面搜索组件的名字:HelloWorld,发现是在App.vue中使用的:

<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
复制代码

4.4 使用Vue组件

使用一个组件和使用一个普通的html标签(好比div)几乎是同样的,惟一不一样的是使用组件以前须要先导入并声明该组件。

使用组件的方式很简单,只须要3步:

  • 导入组件
  • 声明组件
  • 使用组件

使用组件.png

4.5 Vite热更新 - script

咱们尝试修改下这个msg的值(好比改为:Hello everyone! I'm learning Vue 3 + TypeScript + Vite),看下页面会有什么变化。

Vite热更新-script.gif

从以上动图能够看出,与修改template的效果同样,修改完msg的值,一保存文件,页面内容立马刷新,以前的:

Hello Vue 3 + TypeScript + Vite
复制代码

立马变成了:

Hello everyone! I'm learning Vue 3 + TypeScript + Vite
复制代码

几乎没有任何延迟,页面也没有刷新,开发体验很是丝滑。

猫猫震惊2.gif

4.6 响应式的ref对象

第48行定义了一个count变量:

setup: () => {
    const count = ref(0)
    return { count }
  }
复制代码

以前咱们在template中也见过这个变量,它的值就是这里定义的count,咱们注意到这个count的值是调用ref函数以后返回的,函数的参数是数字0。为何要包一层ref,而不是直接将0赋值给count变量呢?

const count = 0
复制代码

直接赋值不是更简洁吗?

咱们先来看下官网对ref的介绍:

接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具备指向内部值的单个 property `.value`。
复制代码

为了理解ref函数的做用,咱们先尝试在页面里点击一下这个count is: 0的按钮。

button.png

点击完发现里面的值立马变成:

count is: 1
复制代码

这时咱们将:

const count = ref(0)
复制代码

修改为:

const count = 0
复制代码

再次点击button按钮,发现值没有变。

咱们大体能理解ref函数返回响应式ref对象的含义:

响应式的意思就是这个变量的值是动态的,某些动做(点击按钮)改变了它的值,模板里面的文本插值立马也会跟着变化,从而页面里面的内容也会跟着刷新。

若是count没有被ref函数包裹,那它就不是响应式的,点击按钮改变它的值以后,模板的内容不会跟着变化。

有一个须要注意的点:

setup中定义的变量必须返回,才能在template中使用,不然插值不会被渲染,而且会在浏览器控制台警告提示这个变量没有在实例中定义。

warn.png

[Vue warn]: Property "count" was accessed during render but is not defined on instance.
复制代码

4.7 TypeScript支持

前面提到<script>中的lang="ts"属性是用来支持TypeScript的,咱们来试试看吧。

先定义一个type类型:

type Size = 'sm' | 'md' | 'lg'
复制代码

而后在setup方法中定义一个变量用来使用这个类型:

const size = ref<Size>('md')

return { size } // 记得返回哦
复制代码

最后在template经过文本插值使用该变量:

<p>{{ size }}</p>
复制代码

因为咱们在<script>中加了lang="ts",因此页面能正常显示md

这时咱们把lang="ts"去掉,保存文件并刷新页面,页面变成白页,而且浏览器控制台也报错:

Uncaught SyntaxError: unexpected token: identifier
复制代码

前面定义的Size类型也出现了红色的波浪下划线。

Size.png

提示type类型声明必须在TypeScript文件中使用:

Type aliases can only be used in TypeScript files.
复制代码

4.8 TypeScript类型错误高亮提示

这样彷佛看不出TypeScript的优点,咱们丰富下这个demo,来看看TypeScript的好处。

咱们加一个addSize方法,用来增长尺寸:

const addSize = () => {
  size.value = 'lg' // 给size变量赋值为Size类型中定义好的值是没问题的
}

return { addSize } // 记得返回哦
复制代码

template中使用该方法:

<button type="button" @click="addSize">Add size</button>
复制代码

若是将size赋值为Size类型定义的值,好比:largeVetur类型检查立刻就会提示,相应的赋值代码也会出现红色波浪下划线:

ts.png

这时咱们可以当即警觉:

这里的代码可能写得有问题

💡提示:Vetur是一款VSCode插件,用来作.vue文件的语法高亮和TypeScript类型检查等。

很是感谢你能阅读到这里,还有最后5分钟就阅读完了,经过小结巩固下学到的知识,而后喝杯水放松下吧😋

4.9 小结

<script>部分基本就是这些,咱们作一个简单的小结:

  1. defineComponent方法用于定义Vue组件
  2. Vue组件的名字经过name属性来定义,名字能够用来惟一区分一个组件
  3. Vue组件经过props属性来与外界进行数据交互
  4. setup方法是Vue3 Composite API的入口
  5. 使用Vue组件和使用html元素差很少,只是须要先导入、声明组件才能使用
  6. ref用于返回一个响应式对象
  7. lang="ts"用来支持TypeScript

5 <style>分析

最后再来看下<style>部分。

<style scoped>
a {
  color: #42b983;
}

label {
  margin: 0 0.5em;
  font-weight: bold;
}

code {
  background-color: #eee;
  padding: 2px 4px;
  border-radius: 4px;
  color: #304455;
}
</style>
复制代码

看着和写CSS没什么区别,只是有一点不同(前面也提到过),就是<style>标签中增长了一个scoped属性,这个属性用来定义局部样式,里面写的样式只针对当前组件生效。

5.1 局部样式

为了理解局部样式的含义,咱们在其余组件中也写一个<code>标签,看下它的样式是否是和HelloWorld组件中的同样,HelloWorld组件中,code标签样式是这样的(有一个灰色的背景色):

code.png

code {
  background-color: #eee;
  padding: 2px 4px;
  border-radius: 4px;
  color: #304455;
}
复制代码

咱们在App.vue中也写一个code标签:

<code>Vue DevUI</code>
复制代码

App.vue.png

发如今HelloWorld组件的style中写的样式并不会影响App组件中的code,这就是局部样式。

经过对比二者的html元素,发现HelloWorld组件中的元素都加上了一个data-v-开头的特殊属性,相应的css规则也加上了这个选择器。

scoped.png

这一点和Angular中的encapsulation属性很是相似。

5.2 Vite热更新 - style

除了templatescript的热更新,Vite也支持style样式的热更新,同样的丝滑,就再也不赘述。

6 小结

经过本文,咱们使用Vite启动了一个初始的项目工程,而且对Vue组件有了一个初步的认识,如今作个简单的小结巩固下吧。

  1. 先是搭建了一个Vue3+TypeScript+Vite的工程
  2. 而后了解了一下Vue组件的总体结构(.vue文件,template+script+style)
  3. 接着对template、script、style区块进行了单独的分析
  4. template和html很相似,只是增长了一些Vue特有的模板语法,如文本插值、事件绑定等
  5. script是定义组件逻辑的地方,能够经过lang="ts"支持TypeScript
  6. defineComponentref是Vue提供的两个很是经常使用的方法,defineComponent用来定义Vue组件,ref用来生成一个响应式的ref对象
  7. defineComponent方法的参数是一个对象,其中的name属性用来定义Vue组件的名字,使用组件时经过名字引用
  8. 使用Vue组件和使用html标签很相似,只是须要先导入和声明组件
  9. props属性用来定义组件与外部交互的API,是组件设计的关键
  10. setup方法是Vue3 Composite API的入口,它会在组件生成以前、props解析以后执行
  11. style用来编写组件的样式,能够经过scoped支持只对当前组件生效的局部样式

本篇文章到这里就结束了,如下是Vue DevUI开源项目的介绍,若是感兴趣能够选择继续阅读。


Vue DevUI正在火热🔥开发中,欢迎你们踊跃参与进来,一块儿共建一个基于DevUI设计理念的Vue开源组件库。

和社区其余组件库相比,咱们主要有如下优点:

  1. vue devui是基于devui沉浸、至简、灵活的设计价值观进行设计和开发的,这是经受过devcloud众多商用项目考验的,确保质量和体验
  2. vue devui的定位是一个跨端组件库,确保知足pc/mobile多端用户的需求
  3. devui是一个专一于用户体验的团队,背后有50+优秀的设计师和工程师,确保产品的优秀体验和技术的先进性
  4. 咱们有多个特点组件,好比甘特图、分类搜索、精灵导航、同时支持自定义字体图标和自定义svg的图标组件等
  5. 咱们支持按需加载、自定义主题、国际化等组件库标配特性。

如下是该项目的源码:

gitee.com/devui/vue-d…

参与贡献能够加小助手微信:devui-official,拉你进Vue DevUI核心成员小组~😋😋

欢迎关注咱们DevUI组件库,点亮咱们的小星星🌟:

github.com/devcloudfe/…

也欢迎使用DevUI新发布的DevUI Admin系统,开箱即用,10分钟搭建一个美观大气的后台管理系统!

再次预告:DevUI 12 和 DevUI Admin 2.0 立刻就要来了!

DevUI 将于本月10日发布 DevUI 12 版本,除了升级 Angular 12 以外,更有超多有趣的新特性,尽情期待!

DevUI Admin 2.0 版本也将在本月17号重磅发布,提供了一项神奇的黑科技,让咱们拭目以待吧!

参考:

Vue3中文文档

相关文章
相关标签/搜索