setup函数
它主要有两个参数:
-
第一个参数:props
-
第二个参数:context
props
是父组件传递过来的属性会被放到props对象中,我们在setup中如果需要使用,那么就可以直接通过props参数获取
context
-
attrs:所有的非prop的attribute
-
slots:父组件传递过来的插槽(这个在以渲染函数返回时会有作用,后面会讲到)
-
emit:当我们组件内部需要发出事件时会用到em
readonly
readonly会返回原始对象的只读代理(也就是它依然是一个Proxy,这是一个proxy的set方法被劫持,并且不能对其进行修改)
script setup语法
当使用 <script setup> 的时候,任何在 <script setup> 声明的顶层的绑定 (包括变量,函数声明,以及 import 引入的内容) 都能在模板中直接使用
Teleport
-
to:指定将其中的内容移动到的目标元素,可以使用选择器
-
disabled:是否禁用 teleport 的功能
代码的效果:
异步组件Suspense
Suspense是一个内置的全局组件,该组件有两个插槽:
-
default:如果default可以显示,那么显示default的内容;
-
fallback:如果default无法显示,那么会显示fallback插槽的内容
当没有异步请求没有完成的时候,进入fallback插槽,完成则进default
动态组件(component :is)
用于实现在指定位置上,动态加载不同的组件
<component :is="componentTag"></component>
//componentTag 为自定义的变量,将需要加载的组件名赋值给它
代码范例
<template>
<div style="padding: 30px">
<button @click="change('1')">组件1</button>
<button @click="change('2')">组件2</button>
<button @click="change('3')">组件3</button>
<component :is="componentTag"></component>
</div>
</template>
<script>
import component1 from './component1'
import component2 from './component2'
import component3 from './component3'
export default {
components: { component1, component2, component3 },
setup() {
const componentTag = ref('')
const change = (index) => {
componentTag.value = 'component' + index
}
return {
componentTag,
change
}
}
}
</script>
keepAlive
keep-alive包裹的组件,在这个组件不活动时,vue会自动缓存这个组件,而不是销毁它
<template>
<div>
<button @click="showAdd = !showAdd">点击切换显示</button>
</div>
<keep-alive>
<one v-if="showAdd"></one>
<two v-else></two>
</keep-alive>
</template>
<script>
import { ref } from 'vue'
import one from './one.vue'
import two from './Two.vue'
export default {
name: 'HelloWorld',
components: {
one, two
},
setup() {
const showAdd = ref(false)
return {
showAdd
}
}
}
</script>
//在showAdd的值变化时,one和two两个组件进行切换,
//因为有keep-alive标签包裹,不显示的组件不会被销毁,vue把它缓存了起来,如下图:
切换页面时缓存页面
根据keepAlive来判断是否要缓存该页面,是true的话,使用keep-alive标签里面的组件;是false的话使用keep-alive标签外面的组件
加上key值 保证唯一不重复
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" v-if="$route.meta.keepAlive" :key="$route.name"></component>
</keep-alive>
<component :is="Component" v-if="!$route.meta.keepAlive" :key="$route.name">></component>
</router-view>
keepAlive之include属性
值为字符串或者正则表达式匹配的组件name会被缓存
keepAlive之exclude 属性
值为字符串或正则表达式匹配的组件name不会被缓存
keepAlive钩子函数
组件被缓存,并没有被销毁,所以组件在切换的时候也就不会被重新创建,自然也就不会调用created等生命周期函数,所以此时要使用activated与deactivated来获取当前组件是否处于活动状态
h() createVNode() render()
h()与createVNode()
h()
是Vue.js中的一个虚拟节点创建函数(createElement的别名)。它用于创建虚拟DOM节点,并返回对应的VNode对象。
h()
函数接受三个参数:第一个参数表示节点的标签名、组件的选项或者一个已经存在的组件;第二个参数是一个包含了节点属性的对象;第三个参数是节点的子元素。
下面的例子使用h()
函数创建了一个div
节点,其中包含了一个h1
和一个p
节点作为子元素:
const vnode = h('div', { class: 'container' }, [
h('h1', {}, 'Hello, Vue!'),
h('p', {}, 'This is a paragraph.')
]);
createVNode()
是Vue 3.x版本中的新增API,用于创建虚拟节点。它的用法类似于h()
函数,也用于创建VNode对象。
不同之处在于,createVNode()
可以支持更多的参数选项,例如组件的props、事件处理等
const vnode = createVNode(Component, { prop1: 'value1', prop2: 'value2' }, [
createVNode('h1', {}, 'Hello, Vue 3!')
]);
上面的例子使用createVNode()
函数创建了一个组件节点,并传递了组件的props。同时,它也创建了一个h1
节点作为子元素
render()
render()
是Vue.js中的一个渲染函数,用于将虚拟节点树渲染成真实的DOM元素。
把 indexPage.vue当做组件在app.vue中使用,app.vue:
<template>
<div>
<index-page />
</div>
</template>
<script>
import indexPage from './indexPage.vue'
export default {
name: 'APP',
components:{
indexPage
},
setup() {
return { }
}
}
</script>
indexPage.vue如下:
<script>
import { h, render } from "vue"
export default {
setup() {
const testDiv = h('div', { id: "myDivId" }, '我是h函数');
return () => {
/**
* render —— 渲染虚拟 DOM
* @param 参数1 要被渲染的虚拟 DOM,必选
* @param 参数2 要渲染的位置,必选
* @description 虚拟 DOM 创建完成后,需要使用 render 函数,才能在页面中渲染
*/
render(testDiv, document.body);
}
}
}
</script>
<script>
import { createVNode, render } from "vue"
export default {
setup() {
/**
* createVNode —— 创建虚拟 DOM
* @param 参数1 创建元素类型,必选
* @param 参数2 创建元素属性
* @paran 参数3 创建元素内容
* @description 虚拟 DOM 创建完成后,需要使用 render 函数,才能在页面中渲染
*/
const testDiv = createVNode('div', { id: "myDivId" }, '我是createVNode函数');
return () => {
render(testDiv, document.body);
}
}
}
</script>
综合实例:
<!-- h与createVNode函数 -->
<script>
import { createVNode, h, ref } from "vue"
export default {
setup() {
const changeNum = () => {
num.value++
console.log(num.value)
}
let num = ref(0);
return () => {
return createVNode(
// 1. 要渲染的标签名称:第一个参数【必需】
"button",
// 2. 渲染标签的属性:第二个参数【可选】
{
style: {
color: "#333",
border: "1px solid #ccc",
},
class: "",
id: "",
onClick: changeNum,
},
// 3. 渲染标签的子元素数组:第三个参数【可选】
[
h("p", num.value)
]
);
}
}
}
</script>