您现在的位置是:首页 >技术杂谈 >vue3学习网站首页技术杂谈
vue3学习
简介vue3学习
小白学习多多指教~
简介
//查看vue版本 必须在4.5.0以上
vue --version
//升级vue
npm install -g @vue/cli
yarn global add @vue/cli
//创建项目
vue create my-project
回顾vue2 对比 vue3
- vue2 逻辑比较分散 可读性差 可维护性差 对typescript支持有限
- vue3 逻辑分明 可维护性高
Vue3 新特性介绍
- 重写向数据绑定
-
//vue2 //defineProperty只有知道key,才能读取拦截,所以新增属性v2表示无能为力 Object.defineProperty(data,'count',{ get(){}, set(){}, }) //vue3 Proxy //知道对象名就可以读取或拦截data上任意的key new Proxy(data,{ get(key){}, set(key,value){} }) 相比有以下优势: 丢掉麻烦的备份数据 省去for in 循环 可以监听数组变化 代码更简化 可以监听动态新增的属性; 可以监听删除的属性 ; 可以监听数组的索引和 length 属性;
-
- VDOM性能瓶颈,优化diff算法
- vue2中diff算法是整体全量比对,在vue3中加入了静态标签(PatchFlag)的概念
PatchFlag给元素增加标记。- 大于1的,diff运算时会与old vdom进行比对更新。
- 小于1的,diff运算时会忽略这些元素,只整体递归遍历vdom tree时进行比对更新
- vue2中diff算法是整体全量比对,在vue3中加入了静态标签(PatchFlag)的概念
- Fragments
- vue3 允许我们支持多个根节点
- 支持render JSX 写法
- 按需加载
-
代码中没有用到的部分代码中不会打包到dist目录中
-
- Composition API
- Setup 语法糖式编程
setup
- setup函数处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之间的函数 (无法使用 data数据、 methods方法的)
- setup函数 Composition API(组合API)的入口
- setup函数 变量和方法,要return出去的 ,不然无法使用
- setup函数 this为undefined
- setup函数 只能同步,不能异步
模板语法
<template>
<div>{{ name}}</div>
<div>{{ message == 0 ? '我是neek0' : '我不是neeko' }}</div>
<div>{{ message + 1 }}</div>
<div>{{ name.split('')}}</div>
</template>
<script setup lang="ts">
const name:string="My name is Nekko"
const age:number=1
</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修饰符 冒泡案例
- v-once 性能优化只渲染一次
- v-memo 性能优化会有缓存
虚拟dom
通过JS来生成一个AST节点树。
为什么不直接操作真实dom? 真实dom上面的属性是非常多的,直接操作DOM非常浪费性能。
如何解决? 通过js计算性能来换取操作dom所消耗的性能,当然我们不可避免要操作DOM
,但是我们尽可能少的操作真实dom,而操作js是非常快的
diff算法
ref和reactive
相同点:都是实现响应式数据
ref
- 创建响应式变量,主要是一些 基本数据类型
- 可以直接返回创建的值。
- ref( ) 创建的是对象类型,在js使用 .value 形式获取
- 在 template模板中直接读取,自动展开渲染内部的值。
reactive
- 创建响应式对象,主要是 object 和 array 类型。
- 可以直接返回创建的值,以链式调用读取,也可以直接读取变量里的值(需要用到 toRefs )
- 在js中,不需要.value,可以 直接修改
- 在template模板中,需要用 x.y 的形式获取值;
const test = reactive({
id: 1,
name: 'neeko',
})
console.log(test.id) // 1
computed
计算属性, 当依赖项发生改变时,值也会发生改变。
- 函数形式 返回只读响应式ref对象。ref.value暴露getter函数返回值
- 对象形式 接受一个带有get和set函数的对象来创建一个可读写 ref 对象。
<script setup lang="ts">
import { computed, ref } from "vue";
const lastName = ref<string>("");
const fristname = ref<string>("");
//函数形式 只读
const name = computed<string>(() => {
return lastName.value + "-" + fristname.value;
});
//对象形式 读写
const name = computed<string>({
get: () => {
return lastName.value + fristname.value;
},
set: (v) => {
//当值发生改变时,把牛给姓,华给名
[lastName.value,fristname.value]=v.split('-')
},
});
const changeNameClick=()=>{
name.value='李-华'
}
</script>
watch和watchEffect
watch函数与watchEffect函数都是监听器,在写法和用法上有一定区别,属于是同一功能的两种不同形态,底层都是一样的。
watch
watch
显式指定依赖数据(第一个参数),依赖数据更新时执行回调函数- 具有一定的惰性lazy ,第一次页面展示的时候不会执行,数据变化时才会执行(设置
immediate: true
时可以变为非惰性,页面首次加载就会执行) - 三个参数,第一个是监视的对象,第二个是监视的回调函数,第三个是监视的配置
const mesage1 = ref({
nav: {
tit: {
name: "neeko",
},
},
});
//监听单个ref对象
watch(
mesage1,
(newV, oldV) => {
console.log(newV, oldV);
},
{
immediate: true, //是否立即调用一次
deep: true, //是否开启深度监听 只有深度监听才能收听到ref对象类型
}
);
//多个监听ref对象
watch(
[mesage1,mesage],
(newV, oldV) => {
console.log(newV, oldV);
},
{
immediate: true, //是否立即调用一次
deep: true, //是否开启深度监听 只有深度监听才能收听到ref对象
}
);
reactive与deep深度监听
//reactive
const mesage1 = reactive({
nav: {
tit: {
name: "neeko",
},
},
});
watch(
mesage1,
(newV, oldV) => {
//若监视的是reactive定义的响应式数据,则无法正确获得oldValue
console.log(newV, oldV);
},
{
immediate: true, //是否立即调用一次
deep: false, //是否开启深度监听 即时关闭深度监听,reactive作为监听深层对象也能监听到
}
);
watchEffect
watchEffect自动
收集函数中依赖数据,依赖项更新时重新执行,不用像watch前面指定依赖项- 非惰性,进入页面会立即加载一次
- 参数为一个函数,在可以在监听之前做操作
watchEffect((oninvalidate) => {
oninvalidate(() => {
//触发监听之前会调用这个函数
//可以进行一些逻辑,例如防抖
});
console.log(mesage);
console.log(mesage1);
});
停止更新
const stop = watchEffect(
() => {
console.log(mesage);
console.log(mesage1);
}
);
//调用函数名,停止更新
stop()
配置项
const stop = watchEffect(
() => {
const btn: HTMLElement = document.getElementById("btn") as HTMLElement;
console.log(btn);
},
{
flush:"post",
onTrigger () {
debugger
}
}
);
flush属性 刷新时机
- pre 组件更新前执行
- aync 强制效果始终同步触发
- post 组件更新后执行
onTrigger 调试watchEffect
组件
<template>
<Shopping/>
</template>
<script setup lang="ts">
//不需要注册 直接使用
import Shopping from "../components/BBStudy/Shopping.vue";
</script>
父传子
//父元素
<Watch :title="title" />
let title: string = "关于 Watch";
//子元素
const props=defineProps({
title: { type: String, default: "默认值" },
});
接收props ts方式
//无默认值
const props = defineProps<{
title:string;
}>();
console.log(props.title);
//有默认值
type Props = {
title?: string,
data?: number[]
}
withDefaults(defineProps<Props>(), {
title: "张三",
data: () => [1, 2, 3]
})
子传父
生命周期
- beforeCreate -> use setup()
- created -> use setup()
- beforeMount -> onBeforeMount DOM实际渲染安装之前调用,根元素还不存在
- mounted -> onMounted 组件第一次渲染后调用,可以访问DOM
- beforeUpdate -> onBeforeUpdate 数据更新时调用,发生在虚拟 DOM 打补丁之前
- updated -> onUpdated DOM更新后,
updated
的方法即会调用 - beforeDestroy -> onBeforeUnmount 卸载组件实例之前调用,这个阶段实例是完全正常的
- destroyed -> onUnmounted 卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。
- activated -> onActivated
- deactivated -> onDeactivated
- errorCaptured -> onErrorCaptured
//added
onRenderTracked
onRenderTriggered //注册一个调试钩子,当响应式依赖的变更触发了组件渲染时调用。
style
Less 快速入门 | Less.js 中文文档 - Less 中文网
npm install less -D 安装即可
npm install sass -D 安装即可
<style lang="less"></style>
<style lang="scss"></style>
什么是scoped?
- 实现组件的私有化, 当前style属性只属于当前模块.
- 在DOM结构中可以发现,vue通过在DOM结构以及css样式上加了唯一标记,达到样式私有化,不污染全局的作用
什么是bem?
- css架构 oocss 实现的一种 (面向对象css) ,bem实际上是
block
块层、element
元素层、modifier
修饰符层 - element-ui就是使用这种架构
-
.block {} 块级 .block-element {} 块级-元素级 .block-element--modifier {} 块级-元素级__修饰符级
挖个坑 sass 编写bem结构 p15 3:14
引入本地图片图片
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。