zxpnet网站 zxpnet网站
首页
前端
后端服务器
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

zxpnet

一个爱学习的java开发攻城狮
首页
前端
后端服务器
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 大前端课程视频归档
  • html

  • js

  • 前端框架

  • 自动化构建

  • typescript

  • es6

  • bootstrap

  • layer

  • vue

  • vue3

    • 邂逅Vue3和Vue3开发体验
    • Vue3基础语法
      • 一、模板语法
        • 1>、mustache语法
        • 2>、基本指令
        • v-once
        • v-text
        • v-html
        • v-pre
        • v-cloak
        • v-bind
        • 绑定基本属性
        • 绑定class属性
        • 绑定style属性
        • 绑定自定义属性
        • v-on
        • 3>、条件渲染
        • v-if、v-else、v-else-if
        • template元素
        • v-show
        • v-show和v-if区别
        • 4>、 列表渲染
        • v-for基本使用
        • v-for支持类型
        • template元素
        • 数组更新检测
        • key和diff算法
        • 2.6.1. 认识VNode和VDOM
      • 计算属性computed
      • 监听器
      • 过滤器
      • v-model与表单
        • v-model修饰符
        • v-model.lazy
        • v-model.number
        • v-model.trim
      • js对象
        • 对象浅拷贝
        • 对象深拷贝
    • Vue3组件化开发
    • Vue3过渡&动画实现
    • Babel和devServer
    • Composition API
    • vue3高级语法
    • vue3源码
    • vue-router路由
    • vuex状态管理
    • vue开源项目
    • vue3-cms项目笔记
    • pinia状态管理
  • vuepress

  • hexo博客

  • 文档

  • biz业务

  • frontend
  • vue3
shollin
2022-01-04
目录

Vue3基础语法

  • 一、模板语法
    • 1>、mustache语法
    • 2>、基本指令
    • 3>、条件渲染
    • 4>、 列表渲染
    • key和diff算法
  • 计算属性computed
  • 监听器
  • 过滤器
  • v-model与表单
    • v-model修饰符
  • js对象
    • 对象浅拷贝
    • 对象深拷贝

# 一、模板语法

# 1>、mustache语法

即{{}}语法,可以写表达式、调用methods里面的函数、可以使用计算属性computed、三目运算符

<!-- JavaScript表达式 -->
<h2>{{ counter * 2}}</h2>
<h2>{{message.split(" ").reverse().join(" ")}}</h2>

<!-- 调用一个methods中的函数 -->
<h2>{{reverse(message)}}</h2>

<!-- 三元运算符 -->
<h2>{{ true ? message: counter }}</h2>
1
2
3
4
5
6
7
8
9

# 2>、基本指令

# v-once

用于指定元素或者组件只渲染一次:

  • 当数据发生变化时,元素或者组件以及其所有的自己诶单将视为静态内容并且跳过;
  • 该指令可以用于性能优化;

# v-text

用于更新元素的 textContent:

# v-html

默认情况下,如果我们展示的内容本身是 html 的,那么vue并不会对其进行特殊的解析。如果我们希望这个内容被Vue可以解析出来,那么可以使用 v-html 来展示

# v-pre

v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签:

  • 跳过不需要编译的节点,加快编译的速度;

# v-cloak

这个指令保持在元素上直到关联组件实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到组件实例准备完毕

# v-bind

前端讲的一系列指令,主要是和内容相关的,元素除了内容之外还会有各种各样的属性。

绑定属性我们使用v-bind:

  • 缩写::

  • 预期:any (with argument) | Object (without argument)

  • 参数:attrOrProp (optional)

  • 修饰符:

    • .camel - 将 kebab-case attribute 名转换为 camelCase。
  • 用法:动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。

# 绑定基本属性

如src,href等,

# 绑定class属性

有对象语法和数组语法

<!-- 1.普通的绑定方式 -->
    <div :class="className">{{message}}</div>
    <!-- 2.对象绑定 -->
    <!-- 动态切换class是否加入: {类(变量): boolean(true/false)} -->
    <div class="why" :class="{nba: true, 'james': true}"></div>
    <!-- 案例练习 -->
    <div :class="{'active': isActive}">哈哈哈</div>
    <button @click="toggle">切换</button>
    <!-- 绑定对象 -->
    <div :class="classObj">哈哈哈</div>
    <!-- 从methods中获取 -->
    <div :class="getClassObj()">呵呵呵</div>
    
<div :class="['why', nba, isActive? 'active': '']">呵呵呵</div>
<div :class="['why', nba, {'actvie': isActive}]">嘻嘻嘻</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 绑定style属性
# 绑定自定义属性
<div v-bind="info" :[title]="'aaa'">绑定自定义属性</div>
1

# v-on

前面我们绑定了元素的内容和属性,在前端开发中另外一个非常重要的特性就是交互。

在前端开发中,我们需要经常和用户进行各种各样的交互:

  • 这个时候,我们就必须监听用户发生的时间,比如点击、拖拽、键盘事件等等
  • 在Vue中如何监听事件呢?使用v-on指令

v-on的使用:

  • 缩写:@

  • 预期:Function | Inline Statement | Object

  • 参数:event

  • 修饰符:

    • .stop - 调用 event.stopPropagation()。
    • .prevent - 调用 event.preventDefault()。
    • .capture - 添加事件侦听器时使用 capture 模式。
    • .self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
    • .{keyAlias} - 仅当事件是从特定键触发时才触发回调。
    • .once - 只触发一次回调。
    • .left - 只当点击鼠标左键时触发。
    • .right - 只当点击鼠标右键时触发。
    • .middle - 只当点击鼠标中键时触发。
    • .passive - { passive: true } 模式添加侦听器
  • 用法:绑定事件监听

<!-- 1.绑定函数 -->
    <button v-on:click="btnClick">按钮1</button>
    <button @click="btnClick">按钮2</button>
    <div v-on:mousemove="mouseMove">div的区域</div>

    <!-- 2.绑定对象 -->
    <button v-on="{click: btnClick, mousemove: mouseMove}">特殊按钮3</button>

    <!-- 3.内联语句 -->
    <!-- 默认会把event对象传入 -->
    <button @click="btn4Click">按钮4</button>
    <!-- 内联语句传入其他属性 -->
    <button @click="btn4Click($event, 'why')">按钮5</button>

    <!-- 4.修饰符 -->
    <div @click="divClick">
      <button @click.stop="btnClick">按钮6</button>
    </div>
    <input type="text" @keyup.enter="onEnter">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 3>、条件渲染

在某些情况下,我们需要根据当前的条件决定某些元素或组件是否渲染,这个时候我们就需要进行条件判断了。

Vue提供了下面的指令来进行条件判断:

  • v-if
  • v-else
  • v-else-if
  • v-show

下面我们来对它们进行学习。

# v-if、v-else、v-else-if

v-if、v-else、v-else-if用于根据条件来渲染某一块的内容:

  • 这些内容只有在条件为true时,才会被渲染出来;
  • 这三个指令与JavaScript的条件语句if、else、else if类似;

v-if的渲染原理:

  • v-if是惰性的;
  • 当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉;
  • 当条件为true时,才会真正渲染条件块中的内容;
 <!-- vue3中, template不再要求必须只有一个根元素 -->
    <template id="my-app">
      <input type="text" v-model.number="score">
      <h2 v-if="score > 90">优秀</h2>
      <h2 v-else-if="score > 80">良好</h2>
      <h2 v-else-if="score > 60">普通</h2>
      <h2 v-else>不及格</h2>
    </template>
1
2
3
4
5
6
7
8

# template元素

因为v-if是一个指令,所以必须将其添加到一个元素上:

  • 但是如果我们希望切换的是多个元素呢?
  • 此时我们渲染div,但是我们并不希望div这种元素被渲染;
  • 这个时候,我们可以选择使用template;

template元素可以当做不可见的包裹元素,并且在v-if上使用,但是最终template不会被渲染出来:

  • 有点类似于小程序中的block

# v-show

v-show和v-if的用法看起来是一致的:

# v-show和v-if区别

首先,在用法上的区别:

  • v-show是不支持template;
  • v-show不可以和v-else一起使用;

其次,本质的区别:

  • v-show元素无论是否需要显示到浏览器上,它的DOM实际都是有渲染的,只是通过CSS的display属性来进行切换;
  • v-if当条件为false时,其对应的原生压根不会被渲染到DOM中;

开发中如何进行选择呢?

  • 如果我们的原生需要在显示和隐藏之间频繁的切换,那么使用v-show;
  • 如果不会频繁的发生切换,那么使用v-if;

# 4>、 列表渲染

在真实开发中,我们往往会从服务器拿到一组数据,并且需要对其进行渲染。

  • 这个时候我们可以使用v-for来完成;
  • v-for类似于JavaScript的for循环,可以用于遍历一组数据;

# v-for基本使用

v-for的基本格式是 "item in 数组":

  • 数组通常是来自data或者prop,也可以是其他方式;
  • item是我们给每项元素起的一个别名,这个别名可以自定来定义;

我们知道,在遍历一个数组的时候会经常需要拿到数组的索引:

  • 如果我们需要索引,可以使用格式:"(item, index) in 数组";
  • 注意上面的顺序:数组元素项item是在前面的,索引项index是在后面的;

# v-for支持类型

v-for也支持遍历对象,并且支持有一二三个参数:

  • 一个参数:"value in object";

  • 二个参数:"(value, key) in object";

  • 三个参数:"(value, key, index) in object";

    v-for同时也支持数字的遍历:

# template元素

类似于v-if,你可以使用 template 元素来循环渲染一段包含多个元素的内容:

  • 我们使用template来对多个元素进行包裹,而不是使用div来完成;
# 数组更新检测

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

替换数组的方法

上面的方法会直接修改原来的数组,但是某些方法不会替换原来的数组,而是会生成新的数组,比如 filter()、concat() 和 slice()。

# key和diff算法

# 2.6.1. 认识VNode和VDOM

在使用v-for进行列表渲染时,我们通常会给元素或者组件绑定一个key属性。

这个key属性有什么作用呢?我们先来看一下官方的解释:

  • key属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes;
  • 如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法;
  • 而使用key时,它会基于key的变化重新排列元素顺序,并且会移除/销毁key不存在的元素;

官方的解释对于初学者来说并不好理解,比如下面的问题:

  • 什么是新旧nodes,什么是VNode?
  • 没有key的时候,如何尝试修改和复用的?
  • 有key的时候,如何基于key重新排列的?

我们先来解释一下VNode的概念:

  • 因为目前我们还没有比较完整的学习组件的概念,所以目前我们先理解HTML元素创建出来的VNode;
  • VNode的全称是Virtual Node,也就是虚拟节点;
  • 事实上,无论是组件还是元素,它们最终在Vue中表示出来的都是一个个VNode;
  • VNode的本质是一个JavaScript的对象;

Vue内部在拿到vnode对象后,会对vnode进行处理,渲染成真实的DOM。

  • 这一部分我会在后面专门和大家阅读createApp函数中讲到;

图片DOM渲染过程

如果我们不只是一个简单的div,而是有一大堆的元素,那么它们应该会形成一个VNode Tree:

所以我们可以发现,Vue在进行diff算法的时候,会尽量利用我们的key来进行优化操作:

  • 在没有key的时候我们的效率是非常低效的;
  • 在进行插入或者重置顺序的时候,保持相同的key可以让diff算法更加的高效;

源码: packages/runtime-core/src/renderer.ts patchKeyedChildren、patchUnkeyedChildren

参考文章:

Vue3+TS系统学习三 - Vue3开发基础语法(一) (qq.com) (opens new window)

# 计算属性computed

# 监听器

  • 当变更(不是替换)对象或数组并使用 deep 选项时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变更之前值的副本
vm.$watch('someObject', callback, {
  deep: true, immediate: true
})
1
2
3

参考:

实例方法 | Vue.js (vuejs.org) (opens new window)

# 过滤器

vue3不再支持过滤器,推荐两种方法: 使用计算属性、使用全局方法

// Vue3不支持过滤器了, 推荐两种做法: 使用计算属性/使用全局的方法
filterBooks() {
      return this.books.map(item => {
        const newItem = Object.assign({}, item); // 拷贝一个新的对象
        newItem.price = "¥" + item.price;
        return newItem;
      })
}
1
2
3
4
5
6
7
8

# v-model与表单

  • v-model指令可以在表单 input、textarea、checkbox、radio、select元素上创建双向数据绑定;

  • 它会根据控件类型自动选取正确的方法来更新元素;

  • 尽管有些神奇,但 v-model 本质上不过是语法糖,它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理;

<!-- 1.v-bind value的绑定 2.监听input事件, 更新message的值 -->
    <!-- <input type="text" :value="message" @input="inputChange"> -->
    <input type="text" v-model="message">
    
<!-- 1.绑定textarea -->
    <label for="intro">
      自我介绍
      <textarea name="intro" id="intro" cols="30" rows="10" v-model="intro"></textarea>
    </label>
    <h2>intro: {{intro}}</h2>

    <!-- 2.checkbox -->
    <!-- 2.1.单选框 -->
    <label for="agree">
      <input id="agree" type="checkbox" v-model="isAgree"> 同意协议
    </label>
    <h2>isAgree: {{isAgree}}</h2>

    <!-- 2.2.多选框, 需要设置value -->
    <span>你的爱好: </span>
    <label for="basketball">
      <input id="basketball" type="checkbox" v-model="hobbies" value="basketball"> 篮球
    </label>
    <label for="football">
      <input id="football" type="checkbox" v-model="hobbies" value="football"> 足球
    </label>
    <label for="tennis">
      <input id="tennis" type="checkbox" v-model="hobbies" value="tennis"> 网球
    </label>
    <h2>hobbies: {{hobbies}}</h2>

    <!-- 3.radio -->
    <span>你的爱好: </span>
    <label for="male">
      <input id="male" type="radio" v-model="gender" value="male">男
    </label>
    <label for="female">
      <input id="female" type="radio" v-model="gender" value="female">女
    </label>
    <h2>gender: {{gender}}</h2>

    <!-- 4.select -->
    <span>喜欢的水果: </span>
    <select v-model="fruit" multiple size="2">
      <option value="apple">苹果</option>
      <option value="orange">橘子</option>
      <option value="banana">香蕉</option>
    </select>
    <h2>fruit: {{fruit}}</h2>    
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

# v-model修饰符

# v-model.lazy

  • 默认情况下,v-model在进行双向绑定时,绑定的是input事件,那么会在每次内容输入后就将最新的值和绑定的属性进行同步;

  • 如果我们在v-model后跟上lazy修饰符,那么会将绑定的事件切换为 change 事件,只有在提交时(比如回车)才会触发;

# v-model.number

  • v-model里面的类型总是string类型,即使在我们设置input的type为number也是string类型; 如果是一个string类型,在可以转化的情况下会进行隐式转换的

  • 如果我们希望转换为数字类型,那么可以使用 .number 修饰符

# v-model.trim

去掉首尾空白字符

<!-- 1.lazy修饰符 -->
    <!-- <input type="text" v-model.lazy="message"> -->

    <!-- 2.number修饰符 -->
    <!-- <input type="text" type="number" v-model.number="message">
    <h2>{{message}}</h2>
    <button @click="showType">查看类型</button> -->

    <!-- 3.trim修饰符 -->
    <input type="text" v-model.trim="message">
1
2
3
4
5
6
7
8
9
10

# js对象

js的对象、数组是引用类型,即指向的是内存的一个地址,当一个对象赋值给另一个变量B时,实际上是把地址给了B

# 对象浅拷贝

先将原对象A的值拷贝一份在内存里面,然后新对象D指向新的地址, 如果原对象A里面有对象B的时候, 浅拷贝也只是拷贝B的地址,因此B变化, A和D都会变化。

const obj = Object.assign({}, info);  // 先在内存里面拷贝一份数据,再把地址赋值给新对象

// lodash库实现浅拷贝  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
const obj = _.clone(info);
1
2
3
4

image-20220119172429753

# 对象深拷贝

原理:先将对象序列化,再反序列化成一个新对象

const obj = JSON.parse(JSON.stringify(info));

// lodash库实现深拷贝
_.cloneDeep(info)
1
2
3
4
邂逅Vue3和Vue3开发体验
Vue3组件化开发

← 邂逅Vue3和Vue3开发体验 Vue3组件化开发→

最近更新
01
国际象棋
09-15
02
成语
09-15
03
自然拼读
09-15
更多文章>
Theme by Vdoing | Copyright © 2019-2023 zxpnet | 粤ICP备14079330号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式