● $route 表示当前激活的路由的状态信息,包含了当前URL解析得到的信息,包含当前的path路径,params参数,query对象,name路径名等属性
●
r
o
u
t
e
r
路由器对象(
n
e
w
的路由器对象),包含一些操作路由的功能函数,来实现编程式导航。一般指的是在任何组件内访问路由。如:路由编程式导航的
router 路由器对象(new的路由器对象),包含一些操作路由的功能函数,来实现编程式导航。一般指的是在任何组件内访问路由。如:路由编程式导航的
router路由器对象(new的路由器对象),包含一些操作路由的功能函数,来实现编程式导航。一般指的是在任何组件内访问路由。如:路由编程式导航的router.push()
● 获取路由参数
import { useRoute,useRouter } from "vue-router"
// useRoute 相当于vue2中的this.$route(),表示当前的路由对象
// useRouter 相当于vue2中的this.$router(),表示全局的路由对象
const route = useRoute()
const query=route.query // 地址兰参数
const prarams=route.params
// 使用router
const router = useRouter()
query=router.currentRoute.value.query
prarams=router.currentRoute.value.params
创建组件实例,然后初始化 props ,紧接着就调用setup 函数。从生命周期钩子的视角来看,它会在 beforeCreate 钩子之前被调用 但是在vue2.x版本中,是先执行beforeCreatd 之后是setup再是created
● reactive() 会返回一个修改过的原始的对象,此行为与 Vue 2 中的 Vue.observable 一致,而在vue3中,reactive() 会返回一个新的的代理对象。
● 使用组合函数时必须始终保持对这个所返回对象的引用以保持响应性。这个对象不能被解构或展开,可以使用toRefs
Api去解决这个问题
const user=reactive({name:'jake',age:28})
// 使用解构
const {name,age}=toRefs(user)
● 为什么通过ref
申明的会有这个value
? 由于 JavaScript 中基础类型是值传递而非引用传递,一个响应式的值一旦作为 property 被赋值或从一个函数返回,而失去了响应性之后,也就失去了用途。为了确保始终可以读取到最新的计算结果,我们需要将这个值上包裹到一个对象中再返回。另外我们同样需要劫持对这个对象 .value property 的读/写操作,现在我们可以通过引用来传递计算值,也不需要担心其响应式特性会丢失了。当然代价就是:为了获取最新的值,我们每次都需要写 .value。
● 那为什么在template模板中,又不需要写.value了呢? 在渲染过程中,Vue 会直接使用其内部的值,也就是说在模板中你可以把 {{ count.value }} 直接写为 {{ count }} 。
● 自动注册子组件
● 属性和方法无需返回
● 支持props、emit和contex
setup script语法糖提供了三个新的API来供我们使用:defineProps
、defineEmit
和useContext
/** child.vue */
<template>
<div>{{ props.msg }}</div>
<a-button type="primary" @click="handleClick">emit</a-button>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue';
// props
let props = defineProps({
msg: {
type: String,
default: ''
}
});
// emit
const emit = defineEmits(['child-click']);
function handleClick() {
emit('child-click', 'child组件的回传信息');
}
// 导出数据
const childData = reactive({
name: 'child',
description: '这里是子组件的信息'
});
defineExpose({ childData });
</script>
/** main.vue */
<template>
<div>主页面</div>
<div>
<Child ref="childRef" :msg="msg" @child-click="handleClick"></Child>
<hr />
<div>来自child的值{{ childMsg }}</div>
<a-button type="primary" @click="getInstance">获取实例</a-button>
</div>
</template>
<script lang="ts" setup>
import Child from './child.vue';
import { ref, reactive, onMounted, getCurrentInstance } from 'vue';
const msg = ref('主页面的props');
let childMsg = ref<string>('');
const handleClick = (res: string) => {
childMsg.value = res;
};
// 获取refForm
const childRef = ref();
// 获取实例
const instance = getCurrentInstance();
function getInstance() {
console.log('log内容getInstance', instance.refs['childRef'].childData);
console.log('log内容childRef', childRef.value.childData);
}
</script>
<style lang="less" scoped></style>
const message = {
setup() {
const num = ref(1)
return {
num
}
},
template: `
{{num}}
这是一个弹窗
`
}
// 初始化组件生成vdom
const vm = createVNode(message)
// 创建容器,也可以用已经存在的
const container = document.createElement('div')
//render通过patch 变成dom
render(vm, container)
// 弹窗挂到任何你想去的地方
document.body.appendChild(container.firstElementChild)
/** main*/
<template>
<h3>pageTitle{{ pageTitle }}</h3>
<h4>obj:{{ obj.billNo }}--{{ obj.billEntity.billName }}</h4>
<hr />
<child v-model:title="pageTitle" @emitFun="emitFun"></child>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import child from './child.vue';
const pageTitle = ref('这是v-model:title');
const obj = reactive({
billNo: '3333',
billEntity: {
billName: '单据名称',
remark: '备注'
}
});
const emitFun = (data: any) => {
Object.assign(obj, data);
};
/**child*/
<template>
<input type="text" @input="setInput" />
<a-input @input="setInput"></a-input>
<a-button type="primary" @click="setValue">调用update:value</a-button>
</template>
<script lang="ts" setup>
const emit = defineEmits(['update:title', 'emitFun']);
let props = defineProps({
msg: {
type: String,
default: ''
}
});
function setInput(val: any) {
emit('update:title', val.target.value);
}
function setValue() {
emit('emitFun', {
billNo: '3333-5555',
billEntity: {
billName: '单据名称child',
remark: '备注child'
}
});
}
</script>
Vue 3 中的Suspense特性允许你在异步组件加载时显示占位符,这有助于提高用户体验,同时减少了不必要的渲染。
包裹了两个
元素,但最终渲染的 DOM 结构中并不会包含额外的父元素。<template>
<div>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<v-fragment>
<p>Paragraph 3</p>
<p>Paragraph 4</p>
</v-fragment>
</div>
</template>
Teleport
允许你将组件的内容渲染到 DOM
结构的不同位置,而不受父组件的限制。这对于处理模态框、对话框、通知消息等需要在页面的不同位置渲染的情况非常有用。
元素,并将其 to
属性设置为一个目标选择器,以指定内容应该被渲染到哪个 DOM 元素中。<template>
<div>
<button @click="showModal">Show Modal</button>
<teleport to="#modal-container">
<Modal v-if="isModalVisible" @close="closeModal" />
</teleport>
</div>
</template>
在上面的示例中,Modal 组件的内容会被渲染到页面中具有 id=“modal-container” 的 DOM 元素内部。