一、VUE中的遗漏的知识
render 中的 h 函数
h 函数可以创建虚拟 dom,通过创建的虚拟 dom 再转化为真的的 DOM,从而渲染到页面中。
1 | <script> |
h 函数第一个参数为
tag name
,也就是你需要创建的标签名,第二参数为此标签上的属性,第三个参数为其内容数组。
插件
vue 中插件主要用于把一些通用性的功能封装起来
插件定义的基本语法
1 | const myPlugin = { |
当使用插件时,会调用插件的 install 方法。第一个参数 app 为生成的 app 对象,第二个参数为传递的参数。
1 | <script> |
数据校验插件
1 | const app = Vue.createApp({ |
Teleport 传送门-vue3
主要用于将 dom 元素挂载到其他位置,例如挂载到head
里。
1 | <body> |
components API-vue3
setup 函数
该函数会在创建组件之前执行,由于在执行 setup
时尚未创建组件实例,因此在 setup
选项中没有 this
。这意味着,除了 props
之外,你将无法访问组件中声明的任何属性——本地状态、计算属性或方法。
1 | // 对数据做校验的插件 |
setup 里返回的内容可以在实例中调用。
响应式引用与只读
主要用于将setup
中的变量转换为响应式的变量。默认变量并不是响应式的。
其中ref
处理基础类型的数据,reactive
用于处理非基础类型的数据(对象和数组)。
方法名 | 作用 |
---|---|
ref | 将基础类型数据转化为响应式数据 |
reactive | 将非基础类型的数据(对象和数组)。 |
readonly | 将数据设为只读 |
toRefs | 将非基础类型的子元素设置为响应式数据 |
基础类型引用
1
2
3
4
5
6
7
8setup(props, context) {
const { ref } = Vue
let name = ref('1')
setTimeout(() => {
name.value = '2'
}, 2000)
return { name }
}通过 ref 包装后,name 实则变成了
proxy({value: '2'})
这样的引用,当修改值时需要修改 name 的 value 属性。但是调用时不需要使用value
,vue 会识别并自动调用。非基础类型引用
1
2
3
4
5
6
7
8setup(props,context){
const { reactive, readonly, toRefs } = Vue
const nameObj = reactive({ name: 'xiaokang', age: 21 })
setTimeout(() => {
nameObj.age = '22'
}, 2000)
return { nameObj }
}通过
reactive
包装后,nameObj 就是响应式的了。组合使用
在非响应式引用里,只有整个对象是响应式的,而对象里的某个属性并不是响应式的,因此,需要将这个对象再次进行包装才可以使其属性变成响应式的。
1
2
3
4
5
6
7
8
9setup(props,context){
const { reactive, readonly, toRefs } = Vue
const nameObj = reactive({ name: 'xiaokang', age: 21 })
setTimeout(() => {
nameObj.age = '22'
}, 2000)
const { name, age } = toRefs(nameObj)
return { age }
}只读
1
2
3
4
5
6const nameObj = reactive({ name: 'xiaokang', age: 22 })
const nameObjCopy = readonly(nameObj)
setTimeout(() => {
nameObj.age = 21
nameObjCopy.age = 23
}, 2000)
参考:https://vue3js.cn/docs/zh/guide/composition-api-introduction.html#带-ref-的响应式变量
toRef
可以用来为源响应式对象上的 property 性创建一个 ref
。然后可以将 ref 传递出去,从而保持对其源 property 的响应式连接。
1 | setup(props, context) { |
setup 中 context 参数
context 参数一共可以结构出三个参数:
attrs
None-Props 属性
1
2
3
4
5
6
7
8
9
10
11
12
13const app = Vue.createApp({
template: `
<child app='app' style='color:red'></child>
`
})
app.component('child', {
template: '<div>child</div>',
setup(props, context) {
const { attrs, slots, emit } = context
console.log(attrs) // 接收没有被props接收的属性
}
})
const vm = app.mount('#root')slots
插槽
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const app = Vue.createApp({
template: `
<child app='app' style='color:red'>
插槽内容
</child>
`
})
app.component('child', {
setup(props, context) {
const { h } = Vue
const { attrs, slots, emit } = context
return () => h('div', {}, slots.default())
}
})
const vm = app.mount('#root')可以使用
jsx
进行模板渲染:https://github.com/vuejs/jsx-next#installationemit
触发自定义事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26const app = Vue.createApp({
template: `
<child @change='handleChange' app='app' style='color:red'>
插槽内容
</child>
`,
methods: {
handleChange() {
console.log(123)
}
}
})
app.component('child', {
template: "<div @click='handleClick'>123123</div>",
setup(props, context) {
const { h } = Vue
const { attrs, slots, emit } = context
function handleClick() {
emit('change')
}
return {
handleClick
}
}
})
const vm = app.mount('#root')
计算属性
计算属性同样使用Vue
对象提供的computed
方法。computed 方法接收参数有两种类型,一种是函数,另一种是对象。
1 | setup(props, context) { |
watch 与 watchEffect
就像我们如何使用 watch
选项在组件内的 user
property 上设置侦听器一样,我们也可以使用从 Vue 导入的 watch
函数执行相同的操作。它接受 3 个参数:
- 一个响应式引用或我们想要侦听的 getter 函数
- 一个回调函数
- 可选的配置选项
侦听单个源
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 侦听一个 getter
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
/* ... */
}
)
// 直接侦听ref
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
})侦听多个源
1
2
3watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
/* ... */
})
不同点 | watch | watchEffect |
---|---|---|
惰性 | 默认情况下是惰性的,但第三个参数传入immediate 为 true 可以立即执行 | 非惰性 |
能拿到原始值和当前值 | 能 | 只能拿到当前值 |
只可以侦听多个数据 | 可以 | 可以 |
1 | const stop = watchEffect(() => { |
生命周期
1 | setup() { |
Provide、Inject 和 ref
提供与注入
1 | const app = Vue.createApp({ |
通过
readonly
对提供的变量进行包装,实现数据单向流(子组件不能修改父组件的值)。
ref
1 | const app = Vue.createApp({ |