vue3学习笔记

setup()

生命周期的与vue2的不同点在:beforeCreatedcreated都在setup()里进行默认调用,其他的都要写在setup()里面,算做compositionAPI

props由父组件传过来的值会自动被响应式,不用再去reactive包一层(注意不能在子组件里直接修改props的值)。

setup()的第一个参数是props(不可进行解构,否则会丢失双向绑定),第二个参数是context,有3个值 attrs,slots,emit,(可进行解构)

props: {name: String,num: Number
},
setup (props, ctx) {props.name // 获取props的name的值ctx.emit('add', value) // 在子组件中使用emit像父组件传递值,与vue2中的this.$emit()有较大区别
}

watch()监听两个回调函数,第一个函数return你要监听数据,第二个函数有参数new Value,然后执行你的操作。

reactive, ref

return出去的ref数据在template里不用.value去调用。

如果将一个对象通过ref创建,那么会通过reactive进行创建。

const person = ref({name: '李四',info: {age: 11,height: 174}
})
console.log(person.value) // 会打印一个Proxy对象,说明是通过reactive创建的

如果在reactive里访问/修改ref,它会自动展开ref,也就是自动给你.value

const count = ref(0)const state = reactive({count
})console.log(state.count)

如果在reactive里放的是Array或者原生集合(比如Map),他们取值都必须加上.value,不会自动展开

const arr = reactive([ref(100),2])console.log(arr[0].value)

unref

如果是ref对象就返回通过reactive创建的数据,如果是普通对象,就直接返回

const info = {name: '李四',age: 22
}
const info2 = ref({name: '李四',age: 22
})
console.log(unref(info)) // {name: '李四', age: '22'}
console.log(unref(info2)) // Proxy{name: '李四', age: '22'}// unref就等同于 isRef(info) ? info.value : info

toRef

可以通过toRefreactive响应源数据(source property)里的值单独拿出来使用。转引用一下,用的对方不多。官方示例是对自己写的composition API进行传值。

const toRef1 = reactive({name: 'xx',age: 11
})
const nameRef = toRef(toRef1, 'name')
nameRef.value = '徐忠炜'
console.log(toRef1.name) // 徐忠炜

toRefs

获取源数据所有数据。在template里直接写属性名就可以使用

<template><h1> {{count}} </h1>
</template>
export default {name: 'App',setup(props, ctx) {const state = reactive({count: 4})return {...toRefs(state)}}
}

customRef

用于防抖节流(图片懒加载、边输入边请求接口的场景)。

computed (API)

跟vue2一样的用法

// 这里用的get
const hello = ref('先生,欢迎来到红浪漫会所。')
const xiaogege = computed(() => {return `徐忠炜${hello.value}`
})
console.log(xiaogege.value) // 徐忠炜先生,欢迎来到红浪漫会所。

readonly

让响应式数据或者普通对象都只读,并且是深层的(DEEP)

const read = reactive({a:1,b: {c: 3,d: [3,4,5,6]}
})
const readOnly = readonly(read)
console.log(readOnly.a) // 1
readOnly.a = 3 // Set operation on key "a" failed: target is readonly.

watchEffect

watchEffect会立即执行(在onBeforeMount之前),并响应式的追踪当前watchEffect里的依赖(数据),并且只要数据改变了它就重新执行一次。当watchEffect写在setup()生命周期里时,在该组件被销毁时它会自动停止监听。

watchEffect还返回一个stop,用于我们手动停止监听。

const stop = watchEffect(() => {// do something
})// later
stop()

Side Effect Invalidation(副作用失效时)

watchEffect即将重新执行/stop时会执行一次onInvalidate方法,watchEffect接收一个onInvalidate参数,其实onInvalidate是一个函数,这个函数的执行顺序是先与watchEffect里面其他所有的程序。

以后慢慢消化SideEffect

const count = ref(0)count.value = 1const stop = watchEffect((onInvalidate) => {console.log(count.value)onInvalidate(() => {console.log('onInvalidate is triggered')})
})
// 打印结果
// 0
// onInvalidate is triggered
// 1

2020-12-03 听至 21p https://www.bilibili.com/video/BV1Q54y1k7At?p=21

watchEffect刷新时间是在所有组件刷新之前调用。也就是执行顺序基本在最前面。

watchEffect的第二个对象(OPTIONS),默认是pre,还有postsync。具体解释看下面

watchEffect(() => {console.log(count.value)
}, {flush: 'pre' // 呼应上面的话,pre是默认在所有组件刷新之前调用flush: 'post' // post是默认在所有组件刷新之后调用,第一次在onBeforeMount之后调用(onMounted之前),之后改变在onbeforeUpdate之后调用(onUpdate之前)flush: 'sync'  // 同步执行
})

watchEffect第一次执行时是在mounted之前,如果你要操作DOM或者Template refs请把watchEffect放在onMounted生命周期里

<template><h1 ref='myRef'></h1>
</template>
export default {name: 'App',setup(props, ctx) {const myRef = ref(null)watchEffect(() => {console.log(myRef.value)})return {myRef}}
}
//打印结果
// null
// <h1></h1> (dom)// 如果放在onMounted里面
onMounted(() => {watchEffect(() => {console.log(myRef.value)})
})
// 打印结果
// <h1></h1> (dom)

watch

watch必须监听一个数据,还得有一个回调函数去处理数据

watch(() => {return count.value
}, (newValue, oldValue) => {// 源数据改变才执行(懒执行)
})

watch监听单一数据有两种写法

// watching a getter
const state = reactive({count: 0})
watch(() => state.count,(newValue, oldValue) => {// do something!}
)// watch a ref
const count = ref(0)
watch(count, (newValue,oldValue) => {// do something!
})

watch监听多个源数据

const foo = ref(1)
const bar = ref(2)setTimeout(() => {foo.value = 11bar.value = 22
}, 2000)// 监听要加上.value
watch(() => [foo.value, bar.value], ([newFoo, newBar], [oldFoo, oldBar]) => {// do something!
})

watch的执行顺序和watchEffect一样,配置参数也一样,详情往前翻。

isProxy

只有reactivereadonly创建的对象才能被isProxy验证为true

即使new Proxy创建的也为false*

isReactive

一个readonly对象用isReactive验证为false

const plain = readonly({name: 'Mary'
})
console.log(isReactive(plain)) // false

如果将一个reactive对象用readonly再包一下,那么验证为true

const state = reactive({name: 'John'
})
const stateCopy = readonly(state)
console.log(isReactive(stateCopy)) // true

shallowReactive

很简单,就是浅的响应式,说明嵌套的对象不会被代理,也就是没有响应式

markRaw

以后记得多看,现在用不到

生命周期

生命周期函数只能用在setup()里,并且是同步的。

Options API LifeCycleComposition API LifeCycle 的映射关系

Options API LifeCycle Composition API LifeCycle
beforeCreate setup()
created setup()
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
update onUpdate
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
renderTracked onRenderTracked
renderTriggered onRenderTriggered

setup()代替了beforeCreatecreate钩子,之前要写在他们里的东西现在只需写在setup()里面。

建议在onMounted里请求数据。

组件卸载时可在onbeforeUnmountonUnmounted里处理一些事件。

onErrorCaptured里捕获子孙组件的异常错误,也就是可以在父组件看到子组件的错误。

onRenderTracked函数里写debugger即可进入调试模式(组件第一次render时)。

onRenderTriggered函数里写debugger即可进入调试模式(rerender时)。

provide/inject (option API)

通常,父子组件传值我们用props。但想象一种情况,当有嵌套比较深的子组件时,比如是个孙组件,那么我们传值必须通过父 -> 子 -> 孙,这样非常麻烦。

为了解决这个情况,我们可以使用provideinject

举个例子:

RootTodoListTodoItemTodoListFooterClearTodoButtonTodoListStatistics

如果我们想把数据从TodoList传到TodoListStatistics,需经过TodoList->TodoListFooter->TodoListStatistics,但使用provide/inject,我们可以这样做:

// 祖先组件
export default {name: 'TodoList',provide: {name: '徐忠炜'}
}// 孙组件
<template>{{ name }}
</template>
export default {name: 'TodoListStatistics',inject: ['name']
}

!如果我们尝试传递一些组件的实例(绑定在this上),那么它是不会工作的。

如果实在要传实例,那么可以这样写(其实也更推荐这样写,就跟Vue2的data一样)

provide() {return {name: this.name}
}

之前这么做,它的数据是不会有响应式的。因为绑定的provide/inject默认是不被响应的。在Vue2中我们把数据用computed包起来就可以让它变成响应式

provide() {return {name: Vue.computed(() => '张三')}
}

provide/inject (composition API)

普通用法与optionAPI的一样

在setup()里使用provide

provide允许你定义两个参数,第一个是属性名(<string>),第二个是属性值

setup() {// 可定义多个provide('name', '张三')provide('age', 22)provide('lover', {name: '陈诗诗',xiongwei: '70D'})
}

在setup()里使用inject

inject允许你填两个参数,第一个是属性名,第二个是默认值(可选)。使用值时要加.value

setup() {const name = inject('name')const age = inject('age', 18)const lover = inject('lover')return {name,age,lover}
}

自带响应式,不用像Vue2里面那样去解决响应式的问题

如果要在inject的那个子组件去改变传递的数据,最好的解决方式是在父组件provide一个方法,方法里面去改变那个值

setup() {const lover = ref('nobody')const updateLover = () => {lover.value = null}provide('updateLover', updateLover)
}
// 子组件还是一样的方法去获取。完美!

还有,如果你为了杜绝在子组件不小心修改了传递的数据,那么你provide数据的时候给数据加个readonly

provide('name',readonly(name))

2020-12-09学习到 refs https://www.bilibili.com/video/BV1Q54y1k7At?p=36

refs (composition API)

setup()里声明一个refs,然后导出,在视图里进行绑定。

// Child.vue
<template><h1> {{ name }} </h1><button @click='changeName'>changeName</button>
</template>
setup() {const child = ref(null) const name = ref('张三')const changeName = () => {console.log(child.value) // 打印的domchild.value.innerText = '李四'}return {child,changeName}
}// 如果想在父组件调用子组件的方法或数据
// Father.vue
<template><child ref='child'></child>
</template>
setup() {const child = ref(null)console.log(child.value.name) // 张三
}

遍历生成refs

<div v-for='(item, i) in list' :ref='el => { if (el) divs[i] = el }'></div>setup() {const divs = ref([])onMounted(() => {console.log(divs.value) // 打印出经过代理的dom节点})
}

Application Config

Application Config

const app = Vue.createApp({})
app.config = {...
}

errorHandler

// 基本用不到
app.config.errorHandler = (err, vm, info) => {// handle error// 'info' 是Vue的特别的错误信息,比如生命周期呀。
}

warnHandler

// 基本用不到
app.config.warnHandler  = (msg, vm, trace) => {// 在运行时产生的一些警告// 'trace'
}

global properties

添加一个全局属性,在任何组件实例里都能引用

app.config.globalProperties.foo = 'bar'app.component('child-component', {mounted() {console.log(this.foo) // 'bar'}
})

就相当于在Vue2.x中,我们往Vue实例上绑东西是这样的

Vue.prototype.$axios = axios

在Vue3中,应该这样做

const app = Vue.createApp({})
app.config.globalProperties.$axios = axios

在组件中调用全局属性

// main.js
app.config.globalProperties.token = 'aofhbioasdlfbnislfbsdkl'// App.vue
// 获取globalProperties
const instace = getCurrentInstance()
console.log(`全局的token:${instace.ctx.token}`)

isCustomElement

使用方法,不报错的。

// vue.config.js
module.exports = {vueCompilerOptions: {isCustomElement: tag => /^jsjiajia-/.test(tag)}
}

Application API

const app = Vue.createApp({})

component 全局注册组件

app.component('componentName', component)

directive 自定义指令

实例一:不使用自定义指令,实现tab栏切换

<template><div class='tab' @click='handleTabClick($event)'><button data-index='0' :class='['tab-btn', {'active': curIndex === 0}]'></button><button data-index='1' :class='['tab-btn', {'active': curIndex === 1}]'></button><button data-index='2' :class='['tab-btn', {'active': curIndex === 2}]'></button></div>
</template>
export default {setup() {const curIndex = ref(0)const handleTabClick = e => {const tar = e.targetconst className = tar.classNameconst index = parseInt(tar.dataset.index)if (className === 'tab-btn') {curIndex.value = index}}return {curIndex,handleTabClick}}
}

实例二:使用自定义指令

<template><div class='tab' @click='handleTabClick($event)' v-tab="{ className: 'tab-btn', activeClass: 'active', curIndex}"><button data-index='0' class='tab-btn'></button><button data-index='1' class='tab-btn'></button><button data-index='2' class='tab-btn'></button></div>
</template>
<script>import tab from './tab.js'export default {directive: {tab},setup() {const curIndex = ref(0)const handleTabClick = e => {const tar = e.targetconst className = tar.classNameconst index = parseInt(tar.dataset.index)if (className === 'tab-btn') {curIndex.value = index}}return {curIndex,handleTabClick}}}
</script>// tab.js
export default {mounted(el,binding) {// el是指令挂载的对象// binding对象的value包含了传过来的值 binding.value.activeClassconst { className, activeClass, curIndex } = binding.valueconst btns = el.getElementsByClassName(className)btns[curIndex].className += ` ${activeClass}`},update(el,binding) {const { className, activeClass, curIndex } = binding.valueconst { oldIndex } = binding.oldValueconst btns = el.getElementsByClassName(className)btns[oldIndex].className = classNamebtns[curIndex].className += ` ${activeClass}`}
}

Vue3 文档学习笔记相关推荐

  1. 【ember zigbee】序章:协议栈相关文档学习笔记

    原文地址:https://blog.csdn.net/tainjau/article/details/90648114 文章目录 写在前面 一.材料出处 二.文档解析 2.1.EZSP Protoco ...

  2. python定义函数的组成部分有_Python文档学习笔记(4)--定义函数

    定义函数 关键字 def 引入函数的定义.其后必须跟有函数名和以括号标明的形式参数列表.组成函数体的语句从下一行开始,且必须缩进. 执行 一个函数会引入一个用于函数的局部变量的新符号表. 因此,在函数 ...

  3. IAM 策略文档学习笔记

    策略文档 IAM 许可策略 附加到确定角色可执行哪些任务的角色.将许可限定为仅角色需要进行的操作,以及仅为进行这些操作角色需要的资源.您可以使用 AWS 管理的或客户创建的 IAM 许可策略 操作:您 ...

  4. w3schools文档学习笔记 - XML

    http://www.w3school.com.cn/xml/xml_syntax.asp 在 XML 中,省略关闭标签是非法的.所有元素都必须有关闭标签 声明不属于XML本身的组成部分.它不是 XM ...

  5. Django1.10文档学习笔记二

    创建应用 1 创建project Django-admin startproject mysite 自动创建目录结构: mysite/    #项目容器 Manage.py    #命令行工具 mys ...

  6. Unity Shader unity文档学习笔记(十一):战争迷雾核心算法

    核心算法 非常简单 主要就是把一个点的世界坐标转换到贴图的UV坐标 给整个场景一个大的plane 加上写的shader 摄像机位置调成plane的正上方 Shader "Unlit/FogR ...

  7. Unity Shader unity文档学习笔记(十七):径向模糊 实现类似冲锋时的速度感

    实现思路:离中心点越远的像素 模糊效果越明显 UV偏移的量越大 shader // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'Uni ...

  8. Vue3项目搭建学习笔记

    Vue3项目搭建学习笔记 参考王红元老师vue课程 创建项目 vue create vue3-ts-cms 项目搭建规范 集成editorconfig配置 VSCode需要安装一个插件:EditorC ...

  9. FreeRTOS官方指导文档阅读笔记

    FreeRTOS官方指导文档阅读笔记 基于 161204_Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf,可 ...

最新文章

  1. 一步一步学Silverlight 2系列(35):升级Silverlight 2 Beta 1应用程序到Beta 2
  2. 根据文件属性或权限进行find查找
  3. Interview:算法岗位面试—2019秋招校园招聘—算法工程师【机器学习、深度学习(偏图像)】秋招感悟:初期阶段的傲娇→中期阶段的紧张→后期阶段的蜕变
  4. Python 中类的继承:属性初始化、类型判断、多态、多继承和对象信息的获取
  5. 如何根据jar包的名称找到包含对应源代码的jar包
  6. 搭建自己的base.js(2)-其他事件方法
  7. oracle中文转全拼音,Oracle 将汉字转为全拼或返回拼音首字母SQL(二)
  8. [linux]centos6.3安装flash插件rpm方式
  9. http客户端-性能比较系列-第二篇-多线程
  10. qq街景输入 dir-item.js
  11. Eclipse设置编辑器为绿豆沙颜色
  12. 超级计算机作文230字,我想养小兔子二年级作文230字
  13. 红米note3耍android8.0,凡人手机进化论 篇六:软件小白入门,红米note3全网通版刷入魔趣体验安卓9.0的快乐...
  14. 由Sensor光谱响应曲线联想到的白平衡增益计算
  15. 计算机图形几何算法详解勘误
  16. HIDL服务死亡通知实例 hidl_death_recipient
  17. 【自然语言处理与文本分析】文本特征提取方法总结。关键词提取方法。公认效果较好的IDF,RCF。
  18. Linux 流量监控软件 NetHogs
  19. Installing Zune software on Windows Server 2003 SP2 (x86)
  20. HTML5期末大作业:电影网站设计——电影介绍(11页) 大学生电影网页作品 电影网页设计作业模板 学生网页制作源代码下载

热门文章

  1. nodejs+vue+elementui在线日程管理系统php java python
  2. 如何管理好一个团队?团队管理书籍推荐
  3. Q45:圆圈中最后剩下的数字
  4. 前端下拉菜单的三种实现方法
  5. Hone C# III
  6. KEIL5编译错误L6406E解决方法
  7. 清华镜像源软件版本的确定(kafka安装)
  8. 34-Vue之ECharts高级-调色盘
  9. 1610:扫雷游戏地雷数计算
  10. Mendix架构体系概述(二)