vue3.0单文件组件api的使用

升级vue版本到3.2以上

npm i vue -S
npm i @vue/compiler-sfc -D

引入组件时的注意事项

  • 你可能会在引入组件时遇到下面的报错问题,并且组件不能正确显示出来
    引入组件报错
  • 导入组件时,首字母必须大写,如果修改后还报警告,重启即可解决

defineProps

  • 父组件
<template>
  <div class="index">
    <child-com :num="num"></child-com>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import ChildCom from './components/childCom.vue';
const num = ref<number>(0);
</script>

<style scoped lang="scss">

</style>
  • 子组件
<template>
  <div class="child-com">
    {{num}}
  </div>
</template>

<script lang="ts" setup>
const props = defineProps({
  num:{
    type: Number,// 如果有复杂类型请使用PropType,如Object as PropType<复杂类型声明>
    default: 10
  }
})
console.log(props);
</script>

<style lang="scss" scoped>

</style>

defineEmits

  • 父组件
<template>
  <div class="index">
    <child-com :num="num" @childClickAdd='addNum'></child-com>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import ChildCom from './components/childCom.vue';
const num = ref<number>(0);
const addNum = (val: number) => {
  num.value = val;
}
</script>

<style scoped lang="scss">

</style>
  • 子组件
<template>
  <div class="child-com">
    <div>{{num}}</div>
    <button @click="addNum">子组件点击+1</button>
  </div>
</template>

<script lang="ts" setup>
const props = defineProps({
  num:{
    type: Number,
    default: 10
  }
});
const emits = defineEmits(['childClickAdd'])
const addNum = () => {
  emits('childClickAdd', props.num + 1);
}
</script>

<style lang="scss" scoped>

</style>

defineExpose

  • 父组件
<template>
  <div class="index">
    <child-com ref="childCom"></child-com>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import ChildCom from './components/childCom.vue';
const childCom = ref<HTMLElement | null>(null);
onMounted(() => {
  console.log(childCom.value);
});
</script>

<style scoped lang="scss">

</style>
  • 子组件
<template>
  <div class="child-com">
    子组件内容
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref } from 'vue';

const a = ref<number>(0);
const b = reactive({
  name: '张三',
  age: 18
});
defineExpose({
  a,
  b
})
</script>

<style lang="scss" scoped>

</style>
  • 输出内容如下
    输出详细

useSlots

  • 父组件
<template>
  <div class="index">
    <child-com>
      <template #header>
        <div>我是头部信息</div>
      </template>
      <template v-slot:main="{str}">
        {{str}}
      </template>
    </child-com>
  </div>
</template>

<script lang="ts" setup>
import ChildCom from './components/childCom.vue';
</script>

<style scoped lang="scss">

</style>
  • 子组件
<template>
  <div class="child-com">
    <slot name="header">如果不传内容,默认展示我</slot>
    <slot name="main" :str="str"></slot>
    <slot name="foot"></slot>
  </div>
</template>

<script lang="ts" setup>
import { ref, useSlots } from 'vue';
const str = ref<string>('传递过去的数据信息');
const slots = useSlots();
console.log(slots);
</script>

<style lang="scss" scoped>

</style>

useAttrs

  • 父组件
<template>
  <div class="index">
    <child-com :a="1" :b="2" class="child"></child-com>
  </div>
</template>

<script lang="ts" setup>
import ChildCom from './components/childCom.vue';
</script>
  • 子组件
<template>
  <div class="child-com">
    <p :class="$attrs['class']">子组件内容</p>
  </div>
</template>

<script lang="ts">
  export default {
    name: 'childCom',
    inheritAttrs: false
  }
</script>

<script lang="ts" setup>
import { useAttrs } from 'vue';
const attrs = useAttrs();
console.log(attrs);
</script>

style的新特性之global

  • 如果需要声明全局样式,可以使用一下方式
<style scoped lang="scss">
:global(.p){ //声明了一个全局类型p
  color: red;
}
</style>

// 使用
<h2 class="p"></h2>

style的新特性之deep

  • 父组件
<template>
  <div class="index">
    <child-com></child-com>
  </div>
</template>

<script lang="ts" setup>
import ChildCom from './components/childCom.vue';
</script>

<style scoped lang="scss">
.index{
  :deep(.p){
    color: blue;
  }
}
</style>
  • 子组件
<template>
  <div class="child-com">
    <p class="p">子组件内容</p>
  </div>
</template>

style的新特性之module

  • 注意css不能有类似scss的嵌套,否则会失效
<template>
  <div class="child-com">
    <p :class="$style.p">红色文本内容</p>
    <div :class="css['div']">蓝色文本内容</div>
    <span :class="Agwenbi['span']">绿色文本内容</span>
  </div>
</template>

<script lang="ts" setup>
import { useCssModule } from 'vue';
const css = useCssModule();
console.log(css);
const Agwenbi = useCssModule('Agwenbi');
console.log(Agwenbi);
</script>

<style scoped lang="scss" module>
.p{
  color:red
}
.div{
  color: green;
}
</style>

<style scoped lang="scss" module="Agwenbi">
.span{
  color: blue
}
</style>

style的新特性之v-bind

<template>
  <div class="child-com">
    <p class="red">红色内容</p>
    <p class="green">绿色内容</p>
    <p class="blue">蓝色内容</p>
  </div>
</template>

<script lang="ts" setup>
import { reactive } from 'vue';
const theme = reactive({
  red: 'red',
  green: 'green',
  blue: 'blue'
})
</script>


<style scoped lang="scss">
.child-com{
  .red{
    color: v-bind('theme.red');
  }
  .green{
    color: v-bind('theme.green');
  }
  .blue{
    color: v-bind('theme.blue');
  }
}
</style>

参考文档vue官方地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Agwenbi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值