vue3新语法

setup

script标签中添加setup,组件只需引入不用注册,属性和方法也不用返回,也不用写setup函数,也不用写export default,甚至是自定义指令也可以在我们的template中自动获得。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div class="home">
显示的值{{flag }}
<button @click="changeHander">改变值</button>
</div>
</template>
<!-- 只需要在script上添加setup -->
<script lang="ts" setup>
import { ref } from 'vue';

<!-- flag变量不需要在 return出去了 -->
let flag=ref("开端-第一次循环")

<!-- 函数也可以直接引用,不用在return中返回 -->
let changeHander=():void=>{
flag.value='开端-第二次循环'
}

</script>

组件不需要在注册

script setup中,引入的组件可以直接使用无需再通过components进行注册,并且无法指定当前组件的名字,它会自动以文件名为主,也就是不用再写name属性了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 这个是组件 -->
<template>
<div>
<h2> 你好-我是肖鹤云</h2>
</div>
</template>


使用的页面
<template>
<div class="home">
<test-com></test-com>
</div>
</template>
<script lang="ts" setup>
// 组件命名采用的是大驼峰,引入后不需要在注册,是不是爽歪歪呀!
//在使用的使用直接是小写和横杠的方式连接 test-com
import TestCom from "../components/TestCom.vue"
</script>

defineProps

子组件接受父组件传递过来的值,代替props

1
2
3
4
5
6
7
8
9
10
11
父组件传递参数
<template>
<div class="home">
<test-com :info="msg" time="42分钟"></test-com>
</div>
</template>
<script lang="ts" setup>
// 组件命名采用的是大驼峰,引入后不需要在注册,是不是爽歪歪呀!
import TestCom from "../components/TestCom.vue"
let msg='公交车-第一次循环'
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
子组件接受参数
<template>
<div>
<h2> 你好-我是肖鹤云</h2>
<p>信息:{{ info}}</p>
<p>{{ time }}</p>
</div>
</template>
<script lang="ts" setup>
import {defineProps} from 'vue'
defineProps({
info:{
type:String,
default:'----'
},
time:{
type:String,
default:'0分钟'
},
})
</script>

defineEmits

子组件向父组件抛出事件,代替$emit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
子组件
<template>
<div>
<h2> 你好-我是肖鹤云</h2>
<button @click="hander1Click">新增</button>
<button @click="hander2Click">删除</button>
</div>
</template>

<script lang="ts" setup>
import {defineEmits} from 'vue'
// 使用defineEmits创建名称,接受一个数组
let $myemit=defineEmits(['myAdd','myDel'])
let hander1Click=():void=>{
$myemit('myAdd','新增的数据')
}

let hander2Click=():void=>{
$myemit('myDel','删除的数据')
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
父组件
<template>
<div class="home">
<test-com @myAdd="myAddHander" @myDel='myDelHander'></test-com>
</div>
</template>
<script lang="ts" setup>
// 组件命名采用的是大驼峰,引入后不需要在注册,是不是爽歪歪呀!
//在使用的使用直接是小写和横杠的方式连接 test-com
import TestCom from "../components/TestCom.vue"
let myAddHander=(mess):void=>{
console.log('新增==>',mess);
}

let myDelHander=(mess):void=>{
console.log('删除==>', mess);
}
</script>

获取子组件中的属性值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
子组件
<template>
<div>
<h2> 你好-我是肖鹤云</h2>
<p>性别:{{ sex}}</p>
<p>其他信息:{{ info}}</p>
</div>
</template>

<script lang="ts" setup>
import { reactive, ref,defineExpose } from "vue";
let sex=ref('男')
let info=reactive({
like:'喜欢李诗晴',
age:27
})
// 将组件中的属性暴露出去,这样父组件可以获取
defineExpose({
sex,
info
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
父组件
<template>
<div class="home">
<test-com @myAdd="myAddHander" @myDel='myDelHander' ref="testcomRef"></test-com>
<button @click="getSonHander">获取子组件中的数据</button>
</div>
</template>
<script lang="ts" setup>
import TestCom from "../components/TestCom.vue"
import {ref} from 'vue'
const testcomRef = ref()
const getSonHander=()=>{
console.log('获取子组件中的性别', testcomRef.value.sex );
console.log('获取子组件中的其他信息', testcomRef.value.info );
}
</script>

style v-bind

我们可以在style中去使用变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<span> 有开始循环了-开端 </span>
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
color: 'red'
})
</script>
<style scoped>
span {
/* 使用v-bind绑定state中的变量 */
color: v-bind('state.color');
}
</style>

生命周期的变化

整体来看,变化不大,只是名字大部分需要+on,功能上类似。使用上 Vue3 组合式 API 需要先引入;Vue2 选项 API 则可直接调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// vue3
<script setup>
import { onMounted } from 'vue'

onMounted(() => {
...
})
// 可将不同的逻辑拆开成多个onMounted,依然按顺序执行,不被覆盖
onMounted(() => {
...
})
</script>

// vue2
<script>
export default {
mounted() {
...
},
}
</script>
Vue2.x Vue3
beforeCreate Not needed*
created Not needed*
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount
destroyed onUnmounted

setup是围绕beforeCreatecreated生命周期钩子运行的,所以不需要显式地去定义。

多根节点

Vue3 支持了多根节点组件。

1
2
3
4
5
<template>
<header>...</header>
<main>...</main>
<footer>...</footer>
</template>

异步组件

Vue3 提供Suspense组件,允许程序在等待异步组件时渲染兜底的内容,如loading,使用户体验更平滑。使用它,需在模板中声明,并包括两个命名插槽:default和fallback。Suspense确保加载完异步内容时显示默认插槽,并将fallback插槽用作加载状态。

1
2
3
4
5
6
7
8
9
10
11
12
<tempalte>
<suspense>
<template #default>
<todo-list />
</template>
<template #fallback>
<div>
Loading...
</div>
</template>
</suspense>
</template>

Teleport

Vue3 提供Teleport组件可将部分 DOM 移动到 Vue app之外的位置。比如项目中常见的Dialog组件。

1
2
3
4
5
<button @click="dialogVisible = true">点击</button>
<teleport to="body">
<div class="dialog" v-if="dialogVisible">
</div>
</teleport>

组合式API

Vue2 是选项式API(Option API),一个逻辑会散乱在文件不同位置(data、props、computed、watch、生命周期函数等),导致代码的可读性变差,需要上下来回跳转文件位置。

Vue3 组合式API(Composition API)则很好地解决了这个问题,可将同一逻辑的内容写到一起。

除了增强了代码的可读性、内聚性,组合式API 还提供了较为完美的逻辑复用性方案,举个🌰,如下所示公用鼠标坐标案例。

1
2
3
4
5
6
7
8
9
10
11
12
13
// main.vue
<template>
<span>mouse position {{x}} {{y}}</span>
</template>

<script setup>
import { ref } from 'vue'
import useMousePosition from './useMousePosition'

const {x, y} = useMousePosition()

}
</script>
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
26
// useMousePosition.js
import { ref, onMounted, onUnmounted } from 'vue'

function useMousePosition() {
let x = ref(0)
let y = ref(0)

function update(e) {
x.value = e.pageX
y.value = e.pageY
}

onMounted(() => {
window.addEventListener('mousemove', update)
})

onUnmounted(() => {
window.removeEventListener('mousemove', update)
})

return {
x,
y
}
}
</script>

解决了 Vue2 Mixin的存在的命名冲突隐患,依赖关系不明确,不同组件间配置化使用不够灵活。

打赏
  • Copyrights © 2017-2023 WSQ
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信