简介

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

参考资料

Vite

创建项目

  • Vue3 推荐的脚手架是 vite ,据说编译打包什么的更加快,所以这里我们就用 vite 开始搭建项目,就不用 vue-cli 来搭建了
  • Vite HMR 速度快到惊人的 [模块热更新(HMR)
  • 采用 Rollup打包 它使用 Rollup 打包你的代码,并且它是预配置的 并且支持大部分rollup插件
  • 安装依赖:yarn (进入项目根目录后执行)
  • 启动项目:可以用截图中的 yarn dev 也可直接用 vite
1
2
3
4
5
6
# yarn 创建项目
yarn create vite
# npm 创建项目
npm init vite@latest
# pnpm 创建项目
pnpm create vite

vite创建项目

目录介绍

  • 以下目录一般是标准的操作,建议按照这种规范去实行
  • public:下面的不会被编译,可以存放图片或者静态资源
  • src
    • assets:可以被编译的,一般存放静态资源比如图片进行base64
    • components:公共组件
    • App.vue:全局的组件,尤其注意里面写的样式会影响到其它的
    • main.ts:公共的 ts 文件
  • index.html:非常重要的入口文件 (webpack,rollup 他们的入口文件都是enrty input 是一个js文件 而Vite 的入口文件是一个html文件,他刚开始不会编译这些js文件 只有当你用到的时候 如script src=”xxxxx.js” 会发起一个请求被vite拦截这时候才会解析js文件)
  • package.json:包配置信息
  • tsconfig.json:ts 的配置
  • vite.config.ts:vite的配置文件
  • yarn.lock:依赖的锁定版本

目录

vite 配置

  • vite 的配置都在 vite.config.js 中

相对路径

  • 打包后再的 html 在 windows 上是正常的,但是在 Mac或者 linux 上可能是访问不到,会有提示Refused to apply style from 'http://localhost:63342/assets/index.16c4fe9c.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
  • 原因就是 访问的路径默认是 /assets 下找 css js 资源, 但是在 Mac 或者 Linux 下会认为是最顶层的文件目录,因此找不到需要用 ./assets

修改前

修改后

alias-TODO

  • alias 别名

环境准备

  • 在时间中可能会遇到 切换 node 版本的情况,这里推荐使用 nvm 进行 node.js 版本的管理 这里就不展开了参考博客Nvm Nrm 使用教程

  • 下载插件 volar,在当vue3.2发布完之后 vetur 并不能给我们提供良好的代码提示,所以volar顺应而生

  • vetur相同,volar是一个针对vuevscode插件,不过与vetur不同的是,volar提供了更为强大的功能(使用的时候需要把vetur 设置为禁用状态)

  • 分别安装 Vue Language Features (Volar) TypeScript Vue Plugin(Volar)

认识 VUE

简介

  • Vue (读音 /vjuː/,类似于 view)是一套用于构建用户界面的渐进式框架
  • Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合
  • 和库不一样,Vue是一套架构,会基于自身特点向用户提供一套相当完整的解决方案,而且控制权在框架本身;对项目的侵入性较大,使用者要按照框架所规定的某种特定规范进行开发,项目如果需要更换框架,则需要重新架构整个项目。
  • 渐进式就跟下面图片一样,开发可以根据需求,逐渐递增所要的方式,但每个方式有不是依靠行特别强

渐进式框架

vue两大核心

  • 响应式的数据绑定:当数据发生改变,视图可以自动更新,可以不用关心dom操作,而专心数据操作
  • 可组合的视图组件:把视图按照功能切分成若干基本单元,组件可以一级一级组合整个应用形成倒置组件树,可维护,可重用,可测试
  • 组件:我们一般将需要复用的东西封装成一个组件 一处封装处处调用

Vue2 & Vue3

  • Vue3 组合式 API(Composition API) 主要用于在大型组件中提高代码逻辑的可复用性。
  • 传统的组件随着业务复杂度越来越高,代码量会不断的加大,整个代码逻辑都不易阅读和理解。
  • Vue3 使用组合式 API 的地方为 setup
  • 在 setup 中,我们可以按逻辑关注点对部分代码进行分组,然后提取逻辑片段并与其他组件共享代码。因此,组合式 API(Composition API) 允许我们编写更有条理的代码。
  • 发现传统的 vue2 使用 Option Api 逻辑比较分散 可读性差 可维护性差,对比 vue3 Composition Api 逻辑分明 可维护性 高

Composition API

Vue3 新特性

Composition Api

  • Setup 函数式编程 也叫vue Hook
  • 例如 ref reactive watch computed toRefs toRaws 我们会在下几个章节详解

重写双向绑定

  • vue2 基于 Object.defineProperty()实现
  • vue3 基于Proxy proxy与Object.defineProperty(obj, prop, desc)方式相比有以下优势:
    • 丢掉麻烦的备份数据
    • 省去for in 循环
    • 可以监听数组变化
    • 代码更简化
    • 可以监听动态新增的属性;
    • 可以监听删除的属性 ;
    • 可以监听数组的索引和 length 属性;
1
2
3
4
5
6
7
8
let proxyObj = new Proxy(obj,{
get : function (target,prop) {
return prop in target ? target[prop] : 0
},
set : function (target,prop,value) {
target[prop] = 888;
}
})

优化Vdom

  • 在Vue2中,每次更新diff,都是全量对比,Vue3则只对比带有标记的,这样大大减少了非动态内容的对比消耗

Fragment

  • Vue3 支持多个根节点,Vue2 template 中只能有一个根节点
1
2
3
4
<template>
<div>12</div>
<div>23</div>
</template>

Tree shaking

  • 之前 webpack 里面的树摇,能减少打包后的代码体积

VUE 开发初体验

VUE文件介绍

SFC 语法规范

  • *.vue 文件都由三种类型的顶层语法块所组成:<template> <script> <style>

template

  • 每个 *.vue 文件最多可同时包含一个顶层 <template> 块。
  • 其中的内容会被提取出来并传递给 @vue/compiler-dom,预编译为 JavaScript 的渲染函数,并附属到导出的组件上作为其 render 选项。

script

  • 每一个 *.vue 文件可同时包含多个 <script> 块 (不包括 <script setup>)
  • 该脚本将作为 ES Module 来执行
  • 默认导出的内容应该是 Vue 组件选项对象,它要么是一个普通的对象,要么是 defineComponent 的返回值

script setup

  • 每个 *.vue 文件最多可同时包含一个 <script setup> 块 (不包括常规的 <script>)
  • 该脚本会被预处理并作为组件的 setup() 函数使用,也就是说它会在每个组件实例中执行。<script setup> 的顶层绑定会自动暴露给模板。更多详情请查看 <script setup> 文档

style

  • 一个 *.vue 文件可以包含多个 <style> 标签。
  • <style> 标签可以通过 scopedmodule attribute (更多详情请查看 SFC 样式特性) 将样式封装在当前组件内。多个不同封装模式的 <style> 标签可以在同一个组件中混

js引入及创建 APP

  • 可以下载 cdn 地址的 js 到本地引用
  • 通过Vue.createApp 创建实例对象
  • 实例中 return返回的数据,可在被挂载的组件中通过 两对大括号的方式 声明式定义
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- vue@next 这个是最新版,不推荐这么用,一般用指定版本 或者下载 js 文件,防止自动更新后语法出错-->
<!-- <script src="https://unpkg.com/vue@next"></script>-->
<script src="../js/vue.global.js"></script>
</head>
<body>
<!--这是一个组件-->
<div id="demo">
{{messages}}<br>
{{msg}}
</div>

<script>
<!-- 创建一个实例 app -->
const app = Vue.createApp({
data() {
return {
messages: "this is a test",
msg: "hello vue"
}
}
}).mount("#demo") // 挂载上面的 demo 组件
console.log(`原始的 app.msg 信息:${app.msg}`);
app.msg = "hello vue3.2.31" // 这里能改变 data return 下 msg 值,也就是 return 里面的都是app实例的属性
</script>
</body>
</html>

引入及创建 APP

v-for

  • 取整个返回的数组:v-for="titles in articles
  • 从数组中下标 0 开始取 5 条:v-for="titles in articles.slice(0, 5) 将每次遍历的结果赋值给 titles

v-for 循环

插入属性

  • 对标签中新增属性,可通过冒号+属性名的方式来操作,例如:<div style="color: red;background:yellow" :style="{width,height}">
  • height,width 是 ES6 json 的简写,既是键又是值

插入属性

点击控制是否显示

  • 在 <h2> 标签上添加点击,改变show 的布尔值控制 display 属性是否显示
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
48
49
50
51
52
53
54
55
56
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.global.js"></script>
</head>
<body>
<style>
.box {
color: blue;
background: green;
display: none; /*将元素的显示设为无 隐藏*/
}

div.show {
display: block;
}
</style>
<div id="demo">
{{messages}}
<h2 @click="show = !show">{{msg}}</h2>
<!-- <div class="box" :class="{show:true}" :style="{width,height}">-->
<div class="box" :class="{show}" :style="{width,height}">
<ul>
<li v-for="titles in articles.slice(0, 5)">{{titles.title}}</li>
</ul>
</div>
</div>

<script>
const app = Vue.createApp({
data() {
return {
show: true,
messages: "this is a test",
msg: "hello vue",
height: "200px",
width: "300px",
articles: [
{title: 'title111111', content: "content1111"},
{title: 'title222222', content: "content1112"},
{title: 'title333333', content: "content1113"},
{title: 'title444444', content: "content1114"},
{title: 'title555555', content: "content1115"},
{title: 'title666666', content: "content1116"},
{title: 'title777777', content: "content1117"},
]
}
}
}).mount("#demo") // 挂载上面的 demo 组件
console.log(`原始的 app.msg 信息:${app.msg}`);
app.msg = "hello vue3.2.31" // 这里能改变 data return 下 msg 值,也就是 return 里面的都是app实例的属性
</script>
</body>
</html>

点击显示或隐藏

方法引用

  • 上面是在<h2>标签里面通过点击对,show属性取反,现在可以通过定义一个方法,改变属性取反,在<h2> 标签中引用方法
  • 方法名和属性名最好不要重复有可能会出现系统不知道找的是方法还是属性(但是方法后面会有括号)
  • 定义方法通过 methods 标签,和 data() 同级
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../js/vue.global.js"></script>
</head>
<body>
<style>
.box {
color: blue;
background: green;
display: none; /*将元素的显示设为无 隐藏*/
}

div.show {
display: block;
}
</style>
<div id="demo">
{{messages}}
<h2 @click="isShow()">{{msg}}</h2>
<!-- <div class="box" :class="{show:true}" :style="{width,height}">-->
<div class="box" :class="{show}" :style="{width,height}">
<ul>
<li v-for="titles in articles.slice(0, 5)">{{titles.title}}</li>
</ul>
</div>
</div>

<script>
const app = Vue.createApp({
data() {
return {
show: true,
messages: "this is a test",
msg: "hello vue",
height: "200px",
width: "300px",
articles: [
{title: 'title111111', content: "content1111"},
{title: 'title222222', content: "content1112"},
{title: 'title333333', content: "content1113"},
{title: 'title444444', content: "content1114"},
{title: 'title555555', content: "content1115"},
{title: 'title666666', content: "content1116"},
{title: 'title777777', content: "content1117"},
],

}
},
methods: {
isShow() {
this.show = !this.show;
}
}
}).mount("#demo") // 挂载上面的 demo 组件
console.log(`原始的 app.msg 信息:${app.msg}`);
app.msg = "hello vue3.2.31" // 这里能改变 data return 下 msg 值,也就是 return 里面的都是app实例的属性
</script>
</body>
</html>

方法定义与引用

语法

模板语法

  • 内容指定为 ts 变量可指定类型
  • template {{ }} 中可直接引用
  • number或者 Boolean 类型的可以用三目运算符
  • 还可直接计算,可调用 api等等
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
<script setup lang="ts">

let msg: string = "好像是 ts 的语法指定类型";
let num: number = 0; //1 为真,其它都为假
let num2: number = 3;
let str: string = "this,is,测,试";

</script>


<template>
<div>

<h2>{{ msg }}</h2>
<h2>{{ num ? `num为真${num}` : `num为假${num}` }}</h2>
<h2>{{ num2 + 1 }}</h2>
<h2>{{ str.split(",") }}</h2>
<h2>{{ str.split(",").map(v => `v=${v}`) }}</h2>
</div>
</template>


<style scoped>

</style>

体验

Vue指令

  • 3:30 P7

  • vue 的指令都是以 V 开头的

  • v-text:在一个标签中插入文本显示

  • v-html:插入富文本

  • v-if v-show:布尔值控制元素是否展示(v-show 操作的是 display:none,比 v-if 性能好)

  • v-if-else语法:如果要对比文本 v-if="flag == 'A'" 双引号套单引号

  • v-on:click 或者简写 @click 绑定事件