vue3
准备工作
创建项目
# npm 6.x
npm init @vitejs/app vite-vue3-starter --template vue-ts
# npm 7+(需要额外的双横线)
npm init @vitejs/app vite-vue3-starter -- --template vue-ts
# yarn
yarn create @vitejs/app vite-vue3-starter --template vue-ts
注:选择项目类型为vue+ts(小tips:git bash中直接按上下键切换选择自己想要的选项,虽然界面中不会动态展示切换的用户交互过程,但是别担心,在回车后可以看到是切换到了对应选项的)
vite
Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间。
支持了动态模块热重载(HMR):允许一个模块 “热替换” 它自己,而不会影响页面其余部分。
虚拟DOM
虚拟DOM就是通过JS来生成一个AST节点树(抽象语法树(AST)
- 有key
- 前序对比算法
- 尾序对比算法
- 新节点如果多出来就是挂载通过patch函数第一个参数为null
- 旧节点如果多出来就是卸载
- 情况特殊乱序
- 无key patch的时候会替换
- 乱序
- 进行前序和后序对比算法
- 然后进行相同的标记
- 移除和新增
一、组件核心 API 的使用
1.组件自动注册
在 script setup 中,引入的组件可以直接使用,无需再通过components
进行注册,并且无法指定当前组件的名字,它会自动以文件名为主,也就是不用再写name
属性了。示例:
<template>
<Child />
</template>
<script setup>
import Child from './Child.vue'
</script>
如果需要定义类似 name 的属性,可以再加个平级的 script 标签,在里面实现即可。
2.setup
script setup 是个啥?
它是 Vue3 的一个新语法糖,在 setup
函数中。所有 ES 模块导出都被认为是暴露给上下文的值,并包含在 setup() 返回对象中。相对于之前的写法,使用后,语法也变得更简单。
使用方式极其简单,仅需要在 script
标签加上 setup
关键字即可。示例:
<script setup></script>
setup是组合Api的入口,返回值是一个对象
setup执行时机
- setup是在beforeCreate生命周期之前执行
- setup在执行的时候,当前组件的实例还没有被创建出来,也就意味着:组件实例对象this根本就不能用,此时this是undefinde,不能来访问date/computed/methods/props
参数props,context
- props参数,是一个对象,里面有父级组件向子级组件传递的数据,
- context参数,
- slots 对象(插槽)
- attrs对象(获取当前标签上的所有的属性对象,但是该属性是在props中没有声明接受的所有的对象
- emits方法(分发事件)
2.1.使用 props
通过defineProps
指定当前 props 类型,获得上下文的props对象。示例:
<script setup>
import {
defineProps } from 'vue'
const props = defineProps({
title: String,
})
</script>
复制代码
2.2.使用 emits
vue3.1
子组件:
<script lang="ts">
import {
defineComponent } from 'vue'
export default defineComponent({
props:{
count:Number
},
setup(props,{
attrs,emit,slots}) {
const changeData = ()=>{
emit('plus',1)
}
return{
changeData
}
},
})
</script>
<template>
父组件传入的参数:{
{
count}}
<button v-on:click="changeData">子组件改变父组件参数</button>
</template>
父组件:
<template>
<h1>setup和ref</h1>
<div>count:{
{
count}}</div>
<Child :canshu="count" @plus="plus"></Child>
</template>
<script lang="ts">
import {
defineComponent, ref } from 'vue'
import Child from './setup-child.vue'
export default defineComponent({
components: {
Child
},
setup() {
// return 一个对象
const count = ref('0');
const plus = (num:Number) => {
count.value += num
}
return {
count,
plus
}
},
})
</script>
vue3.2
使用defineEmit
定义当前组件含有的事件,并通过返回的上下文去执行 emit。示例:
<script setup>
import {
defineEmits } from 'vue'
const emit = defineEmits(['change', 'delete'])
</script>
复制代码
2.3.slots (插槽)attrs
可以通过useContext
从上下文中获取 slots 和 attrs。不过提案在正式通过后,废除了这个语法,被拆分成了useAttrs
和useSlots
。示例:
// 新3.2
<script setup>
import {
useAttrs, useSlots } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
</script>
父组件
<template>
<Child msg="非porps传值子组件用attrs接收" >
<!-- 匿名插槽 --