vue3基础知识的简单应用
- vue3基础知识的简单应用
- 运行结果
vue3基础知识的简单应用
父组件代码
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App" :foo="'foo'" v-model:bar="bar"/>
<p>{{ bar }}</p>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
import { provide, ref } from 'vue'
export default {
name: 'HomeView',
components: {
HelloWorld
},
setup() {
// 接受两个参数:第一个参数是要注入的 key,可以是一个字符串或者一个 symbol,第二个参数是要注入的值
// 建是foo,值是bar
provide('foo', 'bar')
const count = ref(0)
provide('count', count)
const bar = ref('bar')
return {
bar
}
}
}
</script>
子组件代码
<template>
<div class="hello">
<p>ref变量:{{ count }}</p>
<p>computed:{{ testComputed }}</p>
<p>customRef:{{ text }}</p>
<input v-model="text" />
<vNode></vNode>
</div>
</template>
<script setup>
import { ref, computed, reactive, watchEffect, watch, toRef, toRefs, shallowRef, triggerRef, toRaw, inject, h } from 'vue'
import { useDebouncedRef } from './customRef.js'
const text = useDebouncedRef('hello')
const count = ref(0)
console.log('ref变量count.value', count.value)
const countObj = reactive({ count: 1 })
console.log('reactive对象', countObj.count)
// ref用来代理对象,获取对象浅层需要用.value,获取深层直接访问即可,因为ref的深层是用reactive来实现的
const refObj = ref({ count: { a: 1 } })
console.log('ref代理对象', refObj.value.count, refObj.value.count.a)
const a = 2
// computed 返回的值也是ref类型,需要通过.value来获取
const testComputed = computed(() => {
return a + 1
})
console.log('computed', testComputed.value) // 3
const watchReactive = reactive({ count: {a: 2, b: { c: 4 }}})
// watchEffect:watchEffect会自动监听watchEffect回调里面的属性
// 副作用函数的参数onCleanup也是一个函数,用来注册清理回调。清理回调会在该副作用下一次执行前被调用,停止监听器的时候也会调用
// 第二个参数是一个可选的选项,可以用来调整副作用的刷新时机或调试副作用的依赖,默认情况下,侦听器将在组件渲染之前执行。设置 flush: 'post' 将会使侦听器延迟到组件渲染之后再执行。详见回调的触发时机。在某些特殊情况下 (例如要使缓存失效),可能有必要在响应式依赖发生改变时立即触发侦听器。这可以通过设置 flush: 'sync' 来实现。然而,该设置应谨慎使用,因为如果有多个属性同时更新,这将导致一些性能和数据一致性的问题
// 返回值,返回一个可以停止监听器的函数
let watchEffectCount = ref(0)
const stopwatchEffectCount = watchEffect(
(onCleanup) => {
let t = watchEffectCount.value
console.log('监听watchEffect', watchEffectCount.value)
onCleanup(() => {
// 在回调出发
console.log('6666', t)
})
},
{
flush: 'post'
}
)
// watch
// 参数1:第一个参数是侦听器的源。这个来源可以是以下几种:
// 一个函数,返回一个值
// 一个 ref
// 一个响应式对象
// ...或是由以上类型的值组成的数组
// 第二个参数是在发生变化时要调用的回调函数
// 第三个可选的参数是一个对象,immediate、deep、flush、onTrack / onTrigger
// 返回值,停止监听函数
// PS:监听reactive对象的时候,默认开启深度建通,且无法设置为deep:false
watch(
watchReactive,
() => {
console.log('watch监听watchEffectCount', watchReactive.count.a)
},
{ immediate: true, flush: 'post', deep: false }
)
setTimeout(() => {
stopwatchEffectCount() // 停止侦听 则调用该返回值即可
}, 1000 * 5)
// toRef
// 基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同
// 将ref或者reactive对象的属性转化成ref对象,并保持同步,相当于用ref定义一个对象,浅层是ref,深层是reactive
const _toRef = toRef(watchReactive, 'count')
// toRefs,将一个对象转化为react对象
const _toRefs = toRefs(watchReactive)
watchReactive.count.a = 4
console.log('toRef', _toRef.value.a)
console.log('_toRefs', _toRefs.count.value.b.c)
// shallowRef:ref() 的浅层作用形式,只有更改_shallowRef.value的时候才会出发监听
const _shallowRef = shallowRef({ count: 1 })
// triggerRef
// 强制触发依赖于一个浅层 ref 的副作用,这通常在对浅引用的内部值进行深度变更后使用
// 会触发更改监听
watchEffect(() => {
console.log('triggerRef', _shallowRef.value.count)
})
// 不会触发更改监听
_shallowRef.value.count = 2
console.log('_shallowRef1', _shallowRef.value)
triggerRef(_shallowRef)
_shallowRef.value = { count: 3 }
console.log('_shallowRef2', _shallowRef.value)
watchEffectCount.value++
console.log('computed变量testComputed', testComputed.value)
// toRaw
// 根据一个 Vue 创建的代理返回其原始对象。
const toRawOrigin = { a: 2}
const _toRawOrigin = reactive(toRawOrigin)
const _toRaw = toRaw(_toRawOrigin)
toRaw.a = 4
console.log('toRaw1', _toRaw.a)
console.log('toRaw', toRaw(_toRawOrigin) === toRawOrigin) // true
// 生命周期
const inject1 = inject('foo')
console.log('inject1', inject1)
// defineProps() 和 defineEmits()
const props = defineProps({
foo: String,
bar: Number
})
const emit = defineEmits(['update'])
console.log('defineProps', props)
// 双向绑定v-model
emit('update:bar', 'car')
// 暴露属性出去
defineExpose({_toRaw})
// h函数创建节点
const vNode = h('div', {
class: 'test'
}, h('p', {class: '666'}, '++++'))
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
运行结果
ps:以上代码是对vue3知识点的简单案例应用