vue3 新属性
setup script就是vue3新出的一个语法糖,使用方法就是在书写script标签的时候在其后面加上一个setup修饰。
作用:简化代码,大大提高开发效率。
1、自动注册子组件(不需要在compontents中注册)
2、属性和方法无需返回(setup函数中return的东西)
useContext/defineProps/defineEmit
Before
<script lang="ts">
import { defineComponent, reactive, ref, Ref } from "vue";
import { Button, Calendar } from 'vant'
export default defineComponent({
components: { Button },
props: {
title:{
String,
default: () => '标题'
}
},
setup(props, ctx) {
const subtitle: Ref<string> = ref('副标题')
return {
subtitle
}
}
})
After
<script setup lang="ts">
import { defineComponent, reactive, ref, Ref, defineProps } from "vue";
const props = defineProps({
title:{
String,
default: () => '标题'
}
})
const subtitle: Ref<string> = ref('副标题')
总结
import { useContext, defineProps, defineEmit } from 'vue'
const emit = defineEmit(['child-click'])
const ctx = useContext()
const props = defineProps({
msg: String
})
const handleClick = () => {
emit('child-click', ctx)
}
// 对事件进行验证
const emit = defineEmit({
onHeaderClick: ({title}) => {
if(!title) {
console.warn('Invalid title')
return false
}
return true
}
})
//使用TS的注解的方式:
defineProps<{
title?: string
content: string
}>();
其中defineProps用来接收父组件传来的值props。defineEmit用来声明触发的事件表。useContext用来获取组件上下文context。
调用子组件的方法&属性
Before
/*父组件*/
<ChildComp ref="childRef" />
setup() {
const childRef: Ref<any> = ref(null)
/**获取子组件的属性和方法 */
childRef.value.count
childRef.value.addFunc
return {
childRef
}
}
/*子组件*/
setup() {
const count = ref<number>(0)
const addFunc =():void => {
count.value++
}
return {
count,
addFunc
}
}
After
/**子组件变化*/
<script setup lang="ts">
import { ref, useContext } from "vue";
const count = ref<number>(0)
const addFunc =():void => {
count.value++
}
/*此时,直接在父组件调用子组件的属性和方法会报错。childRef.value打印结果为空。*/
/**解决方案如下:*/
const { expose } = useContext()
expose({
count
})
</script>
/**此时父组件只能调用count属性,addFunc方法不能被调用**/
总结
expose接收一个对象,里面包含了所有想从当前组件实例导出的内容,就像封装一个模块一样,只向外暴露一些必要的方法和数据。
expose函数作用:来控制组件被ref时向外暴露的对象内容,借此来维护组件的封装性。
全局方法的定义与使用
全局属性
// 定义
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App);
// 设置全局--属性
app.config.globalProperties.$xxx = 'xxx';
// 使用
setup(props, ctx) {
console.log(ctx.$xxx) // xxx
}
全局方法
// 设置全局--方法
app.config.globalProperties.hello = ()=>{
console.log("hello,world");
}
// 使用
import { getCurrentInstance } from "vue";
//在setup中这样写
setup() {
let {ctx} = getCurrentInstance()
ctx.hello()
return{
}
}
问题:是在开发环境中确实是这样没错,一旦build之后崩了找不到hello方法!,于是便打印出开发环境中和生产环境中ctx的不同。
// 解决方案
//然后在vue文件中通过getCurrentInstance解构出appContext进行获取比如:
let {appContext} = getCurrentInstance()
let {hello} = appContext.config.globalProperties
hello()
CSS:v-bind(变量)
// JS
setup() {
const listHeight: Ref<string> = ref('100px')
listHeight.value = '50px'
return {
listHeight
}
}
// CSS
.demo{
// 简单
height: v-bind(listHeight);
// 复杂
height: calc(100% - v-bind(listHeight));
}
script setup 标签中不需要return,可以在css中直接使用变量。
defineAsyncComponent 异步组件加载
// 引入
import { defineAsyncComponent } from 'vue'
// 使用
const ACom= defineAsyncComponent(() => import('@/components/common/ACom.vue'))