第一章

Options API与Composition API

重写双向绑定

vue2

基于Object.defineProperty()实现

vue3 基于Proxy

proxy与Object.defineProperty(obj, prop, desc)方式相比有以下优势:

//丢掉麻烦的备份数据

//省去for in 循环

//可以监听数组变化

//代码更简化

//可以监听动态新增的属性;

//可以监听删除的属性 ;

//可以监听数组的索引和 length 属性;

   let proxyObj = new Proxy(obj,{
get : function (target,prop) {
return prop in target ? target[prop] : 0
},
set : function (target,prop,value) {
target[prop] = 888;
}
})

Vue3 优化Vdom

https://vue-next-template-explorer.netlify.app/

在这个网站可以看到静态标记

TEXT = 1 // 动态文本节点
CLASS=1<<1,1 // 2//动态class
STYLE=1<<2,// 4 //动态style
PROPS=1<<3,// 8 //动态属性,但不包含类名和样式
FULLPR0PS=1<<4,// 16 //具有动态key属性,当key改变时,需要进行完整的diff比较。
HYDRATE_ EVENTS = 1 << 5,// 32 //带有监听事件的节点
STABLE FRAGMENT = 1 << 6, // 64 //一个不会改变子节点顺序的fragment
KEYED_ FRAGMENT = 1 << 7, // 128 //带有key属性的fragment 或部分子字节有key
UNKEYED FRAGMENT = 1<< 8, // 256 //子节点没有key 的fragment
NEED PATCH = 1 << 9, // 512 //一个节点只会进行非props比较
DYNAMIC_SLOTS = 1 << 10 // 1024 // 动态slot
HOISTED = -1 // 静态节点
BALL = -2

支持多个根节点

支持render JSX

Vue3源码引入tree shaking特性,将全局 API 进行分块。如果你不使用其某些功能,它们将不会包含在你的基础包中

就是比如你要用watch 就是import {watch} from 'vue' 其他的computed 没用到就不会给你打包减少体积

第二章

环境配置 略

npm init vite@latest 使用vite

开始 {#getting-started} | Vite中文网 (vitejs.cn)

nvm nrm 的使用

第三章

在vite中使用scss 直接npm install --save-dev sass 就可以 无需额外配置

Vite目录

public 下面的不会被编译 可以存放静态资源

assets 下面可以存放可编译的静态资源

components 下面用来存放我们的组件

App.vue 是全局组件

main ts 全局的ts文件

index.html 非常重要的入口文件 (webpack,rollup 他们的入口文件都是enrty input 是一个js文件 而Vite 的入口文件是一个html文件,他刚开始不会编译这些js文件 只有当你用到的时候 如script src="xxxxx.js" 会发起一个请求被vite拦截这时候才会解析js文件)

vite config ts 这是vite的配置文件具体配置项 后面会详解

VsCode Vue3 插件推荐 Vue Language Features (Volar)

SFC 语法规范

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

每个 *.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> 标签可以通过 scoped 或 module attribute (更多详情请查看 SFC 样式特性) 将样式封装在当前组件内。多个不同封装模式的 <style> 标签可以在同一个组件中混

四、模板语法&vue指令

​ 插值表达式操作API

<template>
<div>{{ message.split('-') }}</div>
</template> <script setup lang="ts">;
const message:string = "h-e-l-l-o"
</script>

指令

v- 开头都是vue 的指令

v-text 用来显示文本

v-html 用来展示富文本

v-if 用来控制元素的显示隐藏(切换真假DOM)

v-else-if 表示 v-if 的“else if 块”。可以链式调用

v-else v-if条件收尾语句

v-show 用来控制元素的显示隐藏(display none block Css切换)

v-on 简写@ 用来给元素添加事件

v-bind 简写: 用来绑定元素的属性Attr

v-model 双向绑定

v-for 用来遍历元素

v-on修饰符阻止冒泡案例

@click.stop = 'child'

阻止表单提交

@click.prevent = 'submit'

bind绑定class

<template>
<div :class="[flag ? 'active' : 'other', 'h']">12323</div>
</template> <script setup lang="ts">;
const flag: boolean = false;
</script> <style>
.active {
color: red;
}
.other {
color: blue;
}
.h {
height: 300px;
border: 1px solid #ccc;
}
</style>

2

<template>
<div :class="flag">{{flag}}</div>
</template> <script setup lang="ts">;
type Cls = {
other: boolean,
h: boolean
}
const flag: Cls = {
other: false,
h: true
}; var myBoolean = new Boolean(flag)
console.log('myBoolean',myBoolean)//myBoolean [Boolean: true] </script> <style>
.active {
color: red;
}
.other {
color: blue;
}
.h {
height: 300px;
border: 1px solid #ccc;
}
</style>

五、虚拟DOM与diff算法

https://github.com/vuejs/core 源码地址

有key的话先进行双向的对比,最后剩下中间的乱序的再来进行对比 避免浪费性能

六、Ref全家桶

<template>
<div>
<button @click="changeMsg">change</button>
<div>{{ message }}</div>
<div>{{ shallow }}</div>
<div>{{ custom }}</div>
</div>
</template> <script setup lang="ts">;
import { ref, Ref, isRef, shallowRef, triggerRef, customRef } from 'vue'
let message: Ref<string> = ref("我是message")
let notRef: number = 1
let shallow = shallowRef({
msg: 'message',
info: {
name: '孙悟空',
age: '18'
}
})
function MyRef<T>(value: T) {
return customRef((track, trigger) => {
return {
get() {
track()
return value
}, set(newValue: T) {
value = newValue
trigger()
}
} })
}
let custom = MyRef<string>('custom')
const changeMsg = () => {
message.value = "change msg" //使用ref劫持到数据的变化从而在页面上触发更新
console.log('message', message)
console.log('notRef', isRef(notRef), 'message', isRef(message))
custom.value = 'customchanged'//自定义Ref
shallow.value.msg = 'changed'
shallow.value.info = { name: 'xxx', age: '20' }//ref更新会造成shallowRefer的更新
}
const change = () => {
shallow.value.msg = 'changed'
shallow.value.info = { name: 'xxx', age: '20' }//修改对象中的属性
// triggerRef(shallow)//强制刷新页面 }
</script>;

七、Reactive全家桶

import { reactive} from 'vue'

let person = reactive('sad')

会报错的 只能接收复杂数据类型

<template>
<div>
<div>msg {{ msg }}</div>
<div>obj{{ obj }}</div>
<div> per{{ person }}</div>
<button @click="change1">change1</button>
<button @click="change2">change2</button>
<div>{{ state }}</div>
</div>
</template> <script setup lang="ts">;
import { reactive, readonly, shallowReactive } from 'vue'
let msg = reactive<number[]>([])//可以传复杂数据类型
type Person = {
list?: Array<number>
}
let person = reactive<Person>({
list: []
})
const copy = readonly(person)
person.list?.push(1)
// copy.list = person.list?.push(1)//Set operation on key "list" failed: target is readonly.
let obj = reactive({
name: '孙悟空'
})
obj.name = '猪八戒'//复杂数据类型直接用reactive 比较方便 setTimeout(() => {
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
// msg = arr 这样直接赋值的话会破坏掉reactive的响应式
//数组异步赋值问题
//直接赋值会破坏响应式
// 解决 1. push 方法 不会破坏响应式
msg.push(...arr)
console.log('msg', msg)
//解决2 包裹一层对象
person.list = arr;
console.log(person);
}, 1000) const obj1 = {
a: 1,
first: {
b: 2,
second: {
c: 3
}
}
}
const state = shallowReactive(obj1) function change1() {
state.a = 7//浅层修改可以生效
}
function change2() {
state.first.b = 8
state.first.second.c = 9
console.log(state);//深层修改
}
// change1()
// change2() 在DOM挂载之前这些操作都是 会生效的 只有在DOM生效之后shallowReactive才是只有浅修改的
</script>;

八、to全家桶

toRef toRefs toRaw

<template>
<div>
<button @click="change">按钮</button>
{{ state }}
<button @click="change1">按钮</button>
{{ state1 }}
</div>
</template> <script setup lang="ts">;
import { reactive, toRef, toRefs, toRaw } from 'vue' const obj = {
foo: 1,
bar: 1
}
const state = toRef(obj, 'bar')
// bar 转化为响应式对象
const change = () => {
state.value++
console.log(obj, state)//会对原始数据和响应数据造成影响 但是视图不会发生变化
} const obj1 = reactive({
foo: 1,
bar: 1
})
const state1 = toRef(obj1, 'bar')
const change1 = () => {
state1.value++//如果原始数据是reactive 绑定的 再通过toRef创建新的响应对象时 再修改响应对象的内容视图会触发更新
console.log(obj1, state1)
} let obj2 = reactive({
foo: 1,
bar: 2
})
// let {foo,bar} = obj2
// console.log(foo, bar);//数字类型并不是响应式的
let { foo, bar } = toRefs(obj2);
console.log(foo, bar);//响应式的了 在底层的也是去调用 toRef的 const obj3 = reactive({ foo: 1,
bar: 2
})
const raw = toRaw(obj3);
console.log('raw.bar',raw.bar)//变回数字类型了 将响应式的数据对象变回不响应的了
</script>

九、computed

<template>
<div>
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
<div>
{{ firstName }}--{{ lastName }}
</div>
<div>函数型{{ name }}</div>
<div>对象型{{ obj }}</div>
<Shop />
</div> </template> <script setup lang="ts">;
import { computed, ref } from 'vue'
import Shop from './components/shop.vue'
let firstName = ref('')
let lastName = ref('')
//函数型
const name = computed(() => {
return firstName.value + '·' + lastName.value
})
//对象型
const obj = computed({
get() {
return firstName.value + '·' + lastName.value
},
set() {
firstName.value + '·' + lastName.value
}
})
</script>; <style scoped>
</style>

十、watch

<template>
<div>
<input v-model="msg" type="text" />
<input v-model="data1" type="text" />
<input v-model="data2" type="text" />
<input v-model="data3" type="text" />
<br>
ref 深层
<input v-model="refObj.nav.bar.name" type="text" />
<br>
reactive深层
<input v-model="obj.nav.bar.name" type="text" />
<br>
reactive的单一值
<input v-model="reac.name" type="text" />
</div>
</template> <script setup lang="ts">;
/**
* watch第一个参数监听源
* watch第二个参数回调函数cb(newVal,oldVal)
* watch第三个参数一个options配置项是一个对象{
* immediate:true //是否立即调用一次
* deep:true //是否开启深度监听
* }
*/
import { ref, watch, reactive } from 'vue'
let msg = ref<string>('')
//监听一个值
watch(msg, (newValue, oldValue) => {
console.log('newValue', newValue)
console.log('oldValue', oldValue)
}) //监听多个值
let data1 = ref('')
let data2 = ref('')
let data3 = ref('')
//注意变成数组了
watch([data1, data2, data3], (newValue, oldValue) => {
console.log('newValue', newValue)
console.log('oldValue', oldValue)
}) //监听ref深层
let refObj = ref({
nav: {
bar: {
name: ""
}
}
})
watch(refObj, (newValue, oldValue) => {
console.log('newValue', newValue)
console.log('oldValue', oldValue)
}, {
immediate: true,
deep: true,
})//得加deep //监听reactive 对象的深层
let obj = reactive({
nav: {
bar: {
name: ""
}
}
})
watch(obj, (newValue, oldValue) => {
console.log('newValue', newValue)
console.log('oldValue', oldValue)
}) //监听reactive 的单一值
let reac = reactive({
name1: '',
name: ''
})
watch(() => reac.name, (newValue, oldValue) => {
console.log('newValue', newValue)
console.log('oldValue', oldValue)
})
</script> <style scoped>
</style>

vue3学习第一天的更多相关文章

  1. Vue3学习第一例:Vue3架构入门

    入门 Vue3的教程很少,官方网站实例不好整,另外由于Python的Django也掌握了,学习这个有些让人眼乱.Vue项目创建后,在public目录下面自动生成了一个index.htm,里面有个div ...

  2. Magento学习第一课——目录结构介绍

    Magento学习第一课--目录结构介绍 一.Magento为何强大 Magento是在Zend框架基础上建立起来的,这点保证了代码的安全性及稳定性.选择Zend的原因有很多,但是最基本的是因为zen ...

  3. YII2学习第一天

    YII2学习第一天,之前稍微看了看TP,感觉和自己的理念不是很符合,然后转学YII2了. 使用的文档是https://github.com/yiisoft/yii2/tree/master/docs/ ...

  4. Java学习第一天

    Java学习第一天 对于网络管理员或者黑客必须知道的八个cmd命令 详情请参考:http://www.2cto.com/os/201608/533964.html          nbtstat  ...

  5. 一、Android学习第一天——环境搭建(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 一. Android学习第一天——环境搭建 Android 开发环境的搭建 ...

  6. web学习第一章

    web学习第一章   我是大概9月10日开始走上IT之路的,一开始学习了小段时间的自动化办公软件, 昨天我开始学习客户端网页编程,我了解什么是WEB,一些比较老古董的计算模式和发展历史,印象最让我深刻 ...

  7. Java 学习第一步-JDK安装和Java环境变量配置

    Java学习第一步——JDK安装及Java环境变量配置 [原文]  2014-05-30 9:09  Java SE  阿超  9046 views Java作为当下很主流的编程语言,学习Java的朋 ...

  8. swift系统学习第一章

    第一节:变量,常量,类型推断,字符,字符串 //swift学习第一节 /* 变量 常量 类型推断 字符 字符串 */ import UIKit //变量 var str = "swift&q ...

  9. (译) 强化学习 第一部分:Q-Learning 以及相关探索

    (译) 强化学习 第一部分:Q-Learning 以及相关探索 Q-Learning review: Q-Learning 的基础要点是:有一个关于环境状态S的表达式,这些状态中可能的动作 a,然后你 ...

随机推荐

  1. 简单将Springboot项目部署到linux服务器上

    1.使用springboot的jar包方式 直接使用maven工具按照步骤点击就可以直接打包 2.到target目录下找到 jar包 3.将jar包放到linux的任意文件夹下(此项目是之前的kafk ...

  2. react 可视化编辑器1

    可视化编辑器1 前言 前面我们学习低代码,例如百度的低代码平台 amis,也有相应的可视化编辑器,通过拖拽的方式生成配置文件.就像这样 笔者自己也有类似需求:比如中台有个归档需求,通过选择一些配置让后 ...

  3. 前端框架Vue------>第一天学习、Vue学习的路径、Vue官网(1)

    文章目录 1.学习目标 2.前端知识体系 2.1 前端三要素 2.2.MVVM 3.第一个Vue程序 4.Vue实例的生命周期 vue的官方文档:https://cn.vuejs.org/ 1.学习目 ...

  4. 制作一个windows垃圾清理小程序

    制作一个windows垃圾清理小程序: 把下列代码保存为.bat文件(如垃圾清理.bat) 双击它就能很快地清理垃圾文件,大约一分钟不到. 就是下面的文字(这行不用复制)=============== ...

  5. RabbitMQ安装说明文档(超详细版本)

    RabbitMQ安装说明文档(超详细版本) 1. 安装依赖环境 在线安装依赖环境: yum install build-essential openssl openssl-devel unixODBC ...

  6. C# Static关键词的使用

    一.C#中类的方法分为静态方法和非静态方法 静态方法有Static关键词修饰 静态方法归类所有,而非静态方法归类的实例所有:静态方法无需类去实例化可直接调用 静态成员属于类所有,为各个类的实例所公用, ...

  7. 说说 Redis 事务

    更多技术文章,请关注我的个人博客 www.immaxfang.com 和小公众号 Max的学习札记. Redis 事务简介 Redis 只是提供了简单的事务功能.其本质是一组命令的集合,事务支持一次执 ...

  8. Cypher 笔记

    添加 // 创建节点 CREATE (n:MOVIE{name:"电影"}) // 创建节点 create (n:Test) set n.name="Test" ...

  9. Python基础之模块:4、正则表达式和re模块

    目录 一.正则表达式 1.正则表达式前戏 2.字符组 3.特殊符号 4.量词 5.贪婪匹配与非贪婪匹配 6.转义符 7.正则表达式实战 二.re模块 1.模块导入 2.常见操作方法 1.findall ...

  10. 将java装进u盘指南

    将java装入u盘指南 idea 将下载好的idea的文件夹移动到u盘中.在idea的bin目录里找到idea.properties文件,在最后添加以下两行 idea.config.path=U:/I ...