vue3
吾日三省吾身
生命周期
-
onBeforeMount -
onMounted -
onBeforeUpdate -
onUpdated -
onBeforeUnmount -
onUnmounted -
onErrorCaptured -
onRenderTracked -
onRenderTriggered -
onActivated -
onDeactivated
slot
承载内容分发的出口
-
具名 -
作用域插槽
过渡动画
基于class的动画和过渡
<div :class="{ shake: noActivated }">
<button @click="noActivated = true">Click me</button>
</div>
过渡与style绑定
<div
<button
@mousemove="xCoordinate"
:style="{ backgroundColor: `hsl(${x}, 80%, 50%)` }"
class="movearea"
/>
</div>
性能
transform opacity perspective
过渡
class
v-enter-from
v-enter-active
v-enter-to
v-leave-from
v-leave-active
v-leave-to
css
transition
查看css是否发生重绘
组合式API
为什么会出现
碎片化使得理解和维护复杂组件变得困难。选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块。
如果能够将同一个逻辑关注点相关代码收集在一起会更好。而这正是组合式 API 使我们能够做到的。
setup
新的 setup 选项在组件创建之前执行,一旦 props 被解析,就将作为组合式 API 的入口。在setup中不要使用this,setup 选项是一个接收 props 和 context 的函数,setup 返回的所有内容都暴露给组件的其余部分 (计算属性、方法、生命周期钩子等等) 以及组件的模板。
-
可以返回一个渲染函数,该函数可以直接使用在同一作用域中声明的响应式状态:
import { h, ref, reactive } from 'vue' export default { setup() { const readersNumber = ref(0) const book = reactive({ title: 'Vue 3 Guide' }) // 请注意这里我们需要显式使用 ref 的 value return () => h('div', [readersNumber.value, book.title]) } } -
接受参数
props context
Props
setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。
因为props是响应式的所以不能使用ES6解构,会消除prop的响应性。
import { toRefs } from 'vue'
setup(props) {
const { title } = toRefs(props)
console.log(title.value)
}
Context
context 是一个普通 JavaScript 对象,暴露了其它可能在 setup 中有用的值,
Context不是响应式的,可以使用ES6解构
export default {
setup(props, context) {
// Attribute (非响应式对象,等同于 $attrs)
console.log(context.attrs)
// 插槽 (非响应式对象,等同于 $slots)
console.log(context.slots)
// 触发事件 (方法,等同于 $emit)
console.log(context.emit)
// 暴露公共 property (函数)
console.log(context.expose)
}
}
访问组件的property
执行setup时,组件实例尚未被创建,只能访问一下属性:
- props
- attrs
- slots
- emit
无法访问:
- data
- computed
- methods
- refs
ref
在vue3.0通过一个新的 ref 函数使任何响应式变量在任何地方起作用
import { ref } from 'vue'
const counter = ref(0)
watch响应式
从vue导入,接受三个参数
-
一个想要侦听的响应式引用或 getter 函数
-
一个回调
-
可选的配置项
import { ref, watch } from 'vue' const counter = ref(0) watch(counter, (newValue, oldValue) => { console.log('The new counter value is: ' + counter.value) })
独立的computed属性
不是在setup中编写
组件传值
Provide/Inject
父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这些数据
provide
provide函数用两个参数定义property
-
name
-
value
setup() { provide('location', 'North Pole') provide('geolocation', { longitude: 90, latitude: 135 }) }
inject
inject函数有两个参数
-
要inject的property的name
-
默认值
setup() { const userLocation = inject('location', 'The Universe') const userGeolocation = inject('geolocation') return { userLocation, userGeolocation } }
为其增加响应式
使用ref/reacive
如何确保通过provide传递的数据不会被inject的组件更改
给provide的property使用readonly
minxin
Mixin 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个 mixin 对象可以包含任意组件选项。当组件使用 mixin 对象时,所有 mixin 对象的选项将被“混合”进入该组件本身的选项。
选项合并
- data函数内:以组件自身的数据优先
- 同名钩子函数合并为一个数组,minxin对象的钩子在自身钩子之前调用
- 值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
自定义指令
using directive
渲染函数
JavaScript的编程能力,比模板更接近编辑器。
const { createApp, h } = Vue
const app = createApp({})
app.component('anchored-heading', {
render() {
return h(
'h' + this.level,
{},
this.$slots.default()
)
},
h()函数
一个用于创建 VNode 的实用程序。也许可以更准确地将其命名为 createVNode(),但由于频繁使用和简洁,它被称为 h() 。它接受三个参数:
- 一个HTML标签名、一个组件、一个异步组件、一个函数组件 --必须
- {Object}props --可选
- {String|Array|Object} children --可选
指令
- v-model
props: ['modelValue'],
emits: ['update:modelValue'],
render() {
return h(SomeComponent, {
modelValue: this.modelValue,
'onUpdate:modelValue': value => this.$emit('update:modelValue', value)
})
}
- v-on
render() {
return h('div', {
onClick: $event => console.log('clicked', $event.target)
})
}
响应式原理
基于es6proxy reflect
watchEffect 为了根据响应式状态自动应用和重新应用副作用,使用 watchEffect 函数。
它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。
准备开始写
项目创建
Vue-CLI
#1.如果尚未安装 则Install Vue CLI
npm/cnpm/yarn --g @vue/cli@next
# 2.创建一个新项目 按照提示选择ts
vue cretae project-name
#3.如果已有,则添加VueCLI插件
vue and typescript
额外
$forceUpdate--强制更新
v-once--只渲染一次缓存
小结
vue3更向react靠拢,学无止境。