赞
踩
config是一个包含Vue应用程序全局配置的对象。可以在挂载应用程序之前修改下面列出的属性:
const app = Vue.createApp({})
app.config = {...}
app.config.devtools = true
配置是否允许vue-devtools检查。此选项的默认值在开发版本中为true,在生产版本中为false。您可以将其设置为true以启用对生产版本的检查。
app.config.errorHandler = (err, vm, info) => {
// handle error
// info是Vue特定的错误信息,例如 在哪个生命周期挂钩中发现错误
}
为组件渲染功能和观察程序期间的未捕获错误分配处理程序。
app.config.warnHandler = function(msg, vm, trace) {
// trace是组件层次结构跟踪
}
为运行时Vue警告分配自定义处理程序。这仅在开发期间有效,在生产中将被忽略。
app.config.globalProperties.foo = 'bar'
app.component('child-component', {
mounted() {
console.log(this.foo) // 'bar'
}
})
冲突时,组件的属性将具有优先权
在 vue2.x 中是 Vue.prototype
// 2.x
Vue.prototype.$http = () => {}
// 3.x
const app = Vue.createApp({})
app.config.globalProperties.$http = () => {}
app.config.isCustomElement = tag => tag.startsWith('ion-')
指定一种方法来识别在Vue之外定义的自定义元素(例如,使用Web组件API)。 如果component符合此条件,则不需要本地或全局注册,并且Vue不会发出有关Unknown自定义元素的警告。
此功能不需要匹配所有HTML和SVG标签,Vue解析器会自动执行此检查
const app = Vue.createApp({
mounted() {
console.log(this.$options.hello)
}
})
app.config.optionMergeStrategies.hello = (parent, child, vm) => {
return `Hello, ${child}`
}
app.mixin({
hello: 'Vue'
})
// 'Hello, Vue
自定义选项定义合并策略。
合并策略将分别在父实例和子实例上定义的该选项的值作为第一个参数和第二个参数。 上下文应用程序实例作为第三个参数传递。
app.config.performance = true
将其设置为true可在浏览器devtool性能/时间线面板中启用组件初始化,编译,渲染和补丁性能跟踪。 仅在开发模式和支持Performance.mark API的浏览器中工作。
在Vue 3.x,全局改变Vue行为的API都在createApp方法所创建的应用程序实例中
import { createApp } from 'vue'
const app = createApp({})
import { createApp } from 'vue'
const app = createApp({})
// 注册一个 options 对象
app.component('my-component', {
/* ... */
})
// 检索注册的组件
const MyComponent = app.component('my-component')
包含应用程序配置的对象。(往上翻)
参数:
生命周期:
app.directive('my-directive', {
// 挂载前
beforeMount() {},
// 挂载后
mounted() {},
// 更新前
beforeUpdate() {},
// 更新后
updated() {},
// 卸载前
beforeUnmount() {},
// 卸载后
unmounted() {}
})
绑定的DOM元素
绑定的DOM所对应的虚拟节点
之前的虚拟节点,仅在beforeUpdate和updated中可用
除el之外,您应该将这些参数视为只读,并且永远不要修改它们。
import { createApp } from 'vue' import App from './App.vue' let app = createApp(App) app.directive('drag', { beforeMount (el, binding) { console.log(el, binding) let oDiv = el; //当前元素 oDiv.onmousedown = function (e) { //鼠标按下,计算当前元素距离可视区的距离 let disX = e.clientX - oDiv.offsetLeft; let disY = e.clientY - oDiv.offsetTop; document.onmousemove = function (e) { //通过事件委托,计算移动的距离 let l = e.clientX - disX; let t = e.clientY - disY; //移动当前元素 oDiv.style.left = l + 'px'; oDiv.style.top = t + 'px'; //将此时的位置传出去 binding.value({x:e.pageX,y:e.pageY}, el) }; document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; }; }; } }) app.mount('#app')
template中使用
<template> <div v-drag="dragFun" class="div1"></div> </template> <script> export default { setup() { let dragFun = (val, e) => { console.log(val, e) // val 是 在binging.value 的值 // e 是对应的element元素 } return { dragFun } } } </script>
在整个应用范围内应用mixin。一旦注册,它们就可以在当前应用程序中任何组件的模板中使用。
挂载到跟组件上
import { createApp } from 'vue'
const app = createApp({})
app.mount('#app')
设置一个可以注入到应用程序内组件中的值。组件应使用注入来接收提供的值。
provide 和 inject 不是反应性的
import {provide} from 'vue'
setup() {
provide('city', '杭州')
provide('person', {
name: 'Bob',
age: 18
})
}
import {inject} from 'vue'
setup() {
let city = inject('city')
let person = inject('person')
let noProvide = inject('noProvide', 'noProvide hah')
}
卸载
import { createApp } from 'vue'
const app = createApp({})
app.mount('#app')
// 5 秒钟之后卸载
setTimeout(() => app.unmount('#app'), 5000)
使用 Vue 其他插件
//2.x
Vue.use(router)
//3.x
import { createApp } from 'vue'
const app = createApp({})
app.use(router)
返回一个组件实例
const app = Vue.createApp({})
接收根组件选项对象作为第一个参数:
const app = Vue.createApp({
data() {
return {}
},
methods: {},
computed: {}
})
第二个参数,我们可以将根 props 传递给应用程序
const app = Vue.createApp(
{
props: ['username']
},
{ username: 'Evan' }
)
<div id="app">
{{ username }}
</div>
返回一个返回的“虚拟节点”,通常缩写为VNode。
render() {
return Vue.h('h1', {}, 'Some title')
}
h('div', {}, [
'Some text comes first.',
h('h1', 'A headline'),
h(MyComponent, {
someProp: 'foobar'
})
])
import { defineComponent } from 'vue'
const MyComponent = defineComponent({
data() {
return { count: 1 }
},
methods: {
increment() {
this.count++
}
}
})
异步组件
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
app.component('async-component', AsyncComp)
components: {
AsyncComponent: defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
}
const AsyncComp = defineAsyncComponent({ // 工厂函数 loader: () => import('./Foo.vue') // 加载异步组件时要使用的组件 loadingComponent: LoadingComponent, // 加载失败时使用的组件 errorComponent: ErrorComponent, // 显示加载组件之前的延迟。 默认值:200ms。 delay: 200, // 如果提供并超过了超时,则将显示错误组件。 默认值:无穷大 timeout: 3000, // 一个返回布尔值的函数,该值指示加载程序承诺拒绝时异步组件是否应重试 retryWhen: error => error.code !== 404, // 允许的最大重试次数 maxRetries: 3, // 定义组件是否 suspensible: false })
resolveComponent 只能在 render 或者 setup 中使用
一个 component
import { resolveComponent } from 'vue'
render() {
const MyComponent = resolveComponent('MyComponent')
}
resolveDynamicComponent 只能在 render 或者 setup 中使用
一个 component
import { resolveDynamicComponent } from 'vue'
render () {
const MyComponent = resolveDynamicComponent('MyComponent')
}
resolveDirective 只能在 render 或者 setup 中使用
接收一个 指令名称
const app = Vue.createApp({})
app.directive('highlight', {})
import { resolveDirective } from 'vue'
render () {
const highlightDirective = resolveDirective('highlight')
}
withDirectives 只能在 render 或者 setup 中使用
import { withDirectives, resolveDirective } from 'vue'
const foo = resolveDirective('foo')
const bar = resolveDirective('bar')
return withDirectives(h('div'), [
[foo, this.x],
[bar, this.y]
])
const MyDirective = resolveDirective('MyDirective')
const nodeWithDirectives = withDirectives(
h('div'),
[ [MyDirective, 100, 'click', { prevent: true }] ]
)
自定义渲染平台
import { createRenderer } from 'vue'
const { render, createApp } = createRenderer<Node, Element>({
patchProp,
...nodeOps
})
异步更新队列
import { createApp, nextTick } from 'vue' const app = createApp({ setup() { const message = ref('Hello!') const changeMessage = async newMessage => { message.value = newMessage await nextTick() console.log('Now DOM is updated') } }, methods: { this.$nextTick(() => { // ... }) } })
类型:Function
const data = { a: 1 }
const vm = Vue.createApp({
data() {
return data
}
}).mount('#app')
//或者
data: vm => ({ a: vm.myProp })
类型:Array | Object
当使用 Object 的时候:
props: {
age: {
type: Number,
default: 0,
required: true,
validator: value => {
return value >= 0
}
}
}
计算属性
类型:{ [key: string]: Function | { get: Function, set: Function } }
计算的属性的值会被缓存,并且仅在响应性依赖项更改时重新计算。
computed: {
aDouble() {
return this.a * 2
}
}
组件方法
类型:{ [key: string]: Function }
methods: {
checkVal () {
return true
}
}
监听
类型:{ [key: string]: string | Function | Object | Array}
watch: { dataA (val, oldVal) { console.log(val, oldVal) }, // 在 methods 里面的方法 dataB: 'someMethod', // 深度监听 dataC: { handler(val, oldVal) { console.log('c changed') }, deep: true }, // 立即执行 dataD: { handler(val, oldVal) { console.log('d changed') }, immediate: true }, // 传入一个数组 dataE: [ 'handle1', function handle2(val, oldVal) { console.log('handle2 triggered') }, { handler: function handle3(val, oldVal) { console.log('handle3 triggered') } } ] }, methods: { someMethod() { console.log('b changed') }, handle1() { console.log('handle 1 triggered') } }
不能使用箭头函数来定义watch
自组件通过 emit 的事件列表
类型:Array | Object
当为对象时可以验证传入的值是否有效
const app = Vue.createApp({}) // 当为数组时 app.component('todo-item', { emits: ['check'], created() { this.$emit('check') } }) // 当为一个对象时 app.component('reply-form', { emits: { click: null, submit: payload => { if (payload.email && payload.password) { return true } else { console.warn(`Invalid submit event payload!`) return false } } } })
组件实例创建之前,data、event、watcher 不能调用
组件实例创建之后,data、event、watcher可以使用
$el属性不能调用,不能操作DOM
组件实例挂载之前立即被调用:render函数将被首次调用
在服务器端渲染期间不会调用此钩子函数。
组件实例挂载之后调用
mounted不能保证所有子组件也都已安装。 如果要等到整个视图渲染完毕,可以在mount的内部使用vm.$nextTick
在服务器端渲染期间不会调用此钩子函数。
组件实例更新之前
在服务器端渲染期间不会调用此钩子函数。
组件更新之后
更新并不能保证所有子组件也都已重新呈现。如果要等到整个视图重新渲染后,可以在更新后使用vm.$nextTick
在服务器端渲染期间不会调用此钩子函数。
kept-alive 组件激活时的钩子函数
在服务器端渲染期间不会调用此钩子函数。
kept-alive 组件卸载时的钩子
在服务器端渲染期间不会调用此钩子函数
卸载之前调用
在服务器端渲染期间不会调用此钩子函数
卸载之后调用,调用此钩子后,组件实例的所有指令均已解除绑定,所有事件侦听器均已删除,所有子组件实例也已卸载。
在服务器端渲染期间不会调用此钩子函数
类型: (err: Error, instance: Component, info: string) => ?boolean
当捕获到任何后代组件的错误时调用。挂钩接收三个参数:错误,触发错误的组件实例以及包含有关捕获错误的位置信息的字符串。 挂钩可以返回false,以阻止错误进一步传播。
虚拟dom 被 tracked 时调用
renderTracked({ key, target, type }) {}
触发虚拟DOM重新呈现时调用
renderTriggered({ key, target, type }) {}
$watch返回一个unwatch函数,该函数停止触发监听
const unwatch = vm.$watch('a', cb)
// 5秒钟之后停止监听
setTimeout(() => {
unwatch()
}, 5000)
<button v-on:click="$emit('give-advice', adviceText)">
Click but
</button>
强制重新渲染组件实例。它不会影响所有子组件,只会影响实例本身和插入了插槽内容的子组件。
触发之后 会触发 updated() 钩子函数
在下一个DOM更新周期后执行的回调。
methods: {
example() {
this.$nextTick(() => {})
}
}
返回一个对象的反应性拷贝数据
const person = reactive({
name: 'Bob',
age: 18
})
基于 ES6 的Proxy代理实现
返回一个只读的对象,或者只读的ref
const ref1 = ref(0)
const read1 = readonly({
read: 'only'
})
const read2 = readonly(ref1)
read1.read = 'change'
// ⚠️ reactivity.esm-bundler.js?a1e9:301 Set operation on key "read" failed: target is readonly
read2.value = 10
// ⚠️ Set operation on key "value" failed: target is readonly.
检查代理对象是由 reactive 还是 readonly 创建的,返回 true 和 false
const ref1 = ref(0)
const book = reactive({
title: 'this is vue3'
})
const read1 = readonly({
read: 'only'
})
console.log(isProxy(ref1), isProxy(book), isProxy(read1))
// false true true
检查代理对象是否由 reactive 创建的,返回 true 和 false
const ref1 = ref(0)
const book = reactive({
title: 'this is vue3'
})
const read1 = readonly({
read: 'only'
})
console.log(isReactive(ref1), isReactive(book), isReactive(read1))
// false true false
如果一个对象是由 readonly 创建的 reactive 对象,则返回的也是 true
let react = reactive({
name: 'Bob'
})
let react1 = readonly(react)
console.log(isProxy(react1), isReactive(react1))
// true true
检查代理对象是不是 readonly,返回 true 和 false
const ref1 = ref(0)
const read1 = readonly({
read: 'only'
})
let react = reactive({
name: 'Bob'
})
let react1 = readonly(react)
const ref2 = readonly(ref1)
console.log(isReadonly(react1), isReadonly(read1), isReadonly(ref2))
// true true true
返回反应式或只读代理的原始原始对象。可用于临时读取而不会产生代理访问/跟踪开销,也可用于写入而不会触发更改。 不建议保留对原始对象的持久引用。 请谨慎使用。
let obj = {a: 1} let reactObj = reactive(obj) let toRawObj = toRaw(obj) let toRawObj1 = toRaw(reactObj) console.log(obj, reactObj, toRawObj, toRawObj1, toRawObj === obj, toRawObj1 === obj, toRawObj === toRawObj1) // {a: 1} Proxy {a: 1} {a: 1} {a: 1} true true true setTimeout(() => { obj.a = 2 console.log(obj, reactObj, toRawObj, toRawObj1, toRawObj === obj, toRawObj1 === obj, toRawObj === toRawObj1) // {a: 2} Proxy {a: 2} {a: 2} {a: 2} true true true }, 1000) setTimeout(() => { reactObj.a = 3 console.log(obj, reactObj, toRawObj, toRawObj1, toRawObj === obj, toRawObj1 === obj, toRawObj === toRawObj1) // {a: 3} Proxy {a: 3} {a: 3} {a: 3} true true true }, 2000)
标记一个对象,使其永远不会转换为代理。 返回对象本身。
let obj = {a: 1} let reactObj = reactive(obj) let toRawObj = markRaw(obj) let toRawObj1 = markRaw(reactObj) console.log(obj, reactObj, toRawObj, toRawObj1, toRawObj === obj, toRawObj1 === obj, toRawObj === toRawObj1) // {a: 1, __v_skip: true}a: 3__v_skip: true__proto__: Object Proxy {a: 1, __v_skip: true} {a: 1, __v_skip: true} Proxy {a: 1, __v_skip: true} true false false setTimeout(() => { obj.a = 2 console.log(obj, reactObj, toRawObj, toRawObj1, toRawObj === obj, toRawObj1 === obj, toRawObj === toRawObj1) // {a: 2, __v_skip: true}a: 3__v_skip: true__proto__: Object Proxy {a: 2, __v_skip: true} {a: 2, __v_skip: true}a: 3__v_skip: true__proto__: Object Proxy {a: 2, __v_skip: true} true false false }, 1000) setTimeout(() => { reactObj.a = 3 console.log(obj, reactObj, toRawObj, toRawObj1, toRawObj === obj, toRawObj1 === obj, toRawObj === toRawObj1) // {a: 3, __v_skip: true} Proxy {a: 3, __v_skip: true} {a: 3, __v_skip: true} Proxy {a: 3, __v_skip: true} true false false }, 2000)
创建一个反应式代理,该反应式代理跟踪其自身属性的反应性,但不执行嵌套对象的深度反应式转换。
const book = reactive({ title: 'this is vue3', address: { city: 'hz', area: 'bj' } }) console.log(isReactive(book.address)) // true const obj = shallowReactive({ name: 'Bob', age: 18, address: { city: 'hz', area: 'bj' } }) console.log(isReactive(obj.address)) // false
创建一个代理,使其自身的属性为只读,但不执行嵌套对象的深度只读转换。
const book = readonly({ title: 'this is vue3', address: { city: 'hz', area: 'bj' } }) console.log(isReadonly(book.address)) // true const obj = shallowReadonly({ name: 'Bob', age: 18, address: { city: 'hz', area: 'bj' } }) console.log(isReadonly(obj.address)) // false
接受一个值并返回一个反应性且可变的ref对象。ref对象具有指向内部值的单个属性.value。
const ref1 = ref(0) __v_isRef: true _rawValue: 0 _shallow: false _value: 0 value: 0 const ref2 = ref({ name: 'Bob', age: 18 }) __v_isRef: true _rawValue: {name: "Alice", age: 18} _shallow: false _value: Proxy {name: "Alice", age: 18} value: Proxy [[Handler]]: Object [[Target]]: Object age: 18 name: "Alice" __proto__: Object [[IsRevoked]]: false
一般使用 ref 定义基本类型
如果参数是 ref 则返回内部的 value 值,否则返回 参数本身,是 val = isRef(val) ? val.value : val
的语法糖
const ref1 = ref(0)
const ref2 = ref({
name: 'Bob',
age: 18
})
const obj = reactive({
name: 'Alice',
age: 20
})
console.log(unref(ref1), unref(ref2), unref(obj))
// 0
// Proxy
// Proxy
创建一个 reactive 的对象的属性 做为 ref 的引用,保持反应性连接
const obj = reactive({
name: 'Alice',
age: 20
})
const toR1 = toRef(obj, 'name')
const notoR2 = obj.name
setTimeout(() => {
obj.name = 'Jack'
}, 1000)
// 1000 毫秒之后 toR1.value 值为 Jack, notoR2 的值为 Alice
将反应对象转换为普通对象,其中所得对象的每个属性都是指向原始对象相应属性的ref。
const obj = reactive({ name: 'Alice', age: 20 }) const refs1 = toRefs(obj) console.log(refs1) {name: ObjectRefImpl, age: ObjectRefImpl} age: ObjectRefImpl __v_isRef: true _key: "age" _object: Proxy {name: "Jack", age: 20} value: 20 __proto__: Object name: ObjectRefImpl __v_isRef: true _key: "name" _object: Proxy {name: "Jack", age: 20} value: "Jack" __proto__: Object setTimeout(() => { obj.name = 'Jack' }, 1000) // 1000 毫秒之后 refs1.name.value 的值也变为 Jack
检查是否是 ref 对象
const ref1 = ref(0)
const ref2 = ref({
name: 'Bob',
age: 18
})
const obj = reactive({
name: 'Alice',
age: 20
})
console.log(isRef(ref1), isRef(ref2), isRef(obj))
// true true false
<template> <div class="my-com2"> <input v-model="text" /> </div> </template> <script> import {customRef} from 'vue' function useDebouncedRef(value, delay = 200) { let timeout return customRef((track, trigger) => { return { get() { console.log(value) track() return value }, set(newValue) { console.log(newValue) clearTimeout(timeout) timeout = setTimeout(() => { value = newValue trigger() }, delay) } } }) } export default{ setup () { return { text: useDebouncedRef('hello') } } } </script> <style scoped> </style>
const ref1 = ref(0) const ref2 = ref({ name: 'Bob', age: 18 }) const obj = reactive({ name: 'Alice', age: 20 }) const a1 = shallowRef(ref1) const a2 = shallowRef(ref2) const a3 = shallowRef(obj) console.log(isReactive(a1), isReactive(a2), isReactive(a3)) // false false false
const s1 = shallowRef({
name: 'Bob'
})
s1.value.name = 'Alice'
triggerRef(s1)
console.log(s1.value.name)
// Alice
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。