目录
1.defineProps defineEmits defineExpose/ref
2.v-model 组件标签可同时写多个v-model 不再支持 .sync
4.attrs 会包含父组件的props 属性的集合 一旦用props接收,attrs
基于vue 3.2
1.defineProps defineEmits defineExpose/ref
<template>
<div>
<button @click="changeSonValue">changeNum</button>
<h1>{{ n }}</h1>
<h1 v-for="(item, index) in obj">{{ item }}</h1>
</div>
</template>
<script setup>
import { ref, watch } from "vue";
// let props = defineProps(["num", "obj","changeNum"]); //简单
let props = defineProps({num:{type:Number},obj:{type:Object}}) //限制类型
let n = ref(props.num); //props 获取所有props的对象
// console.log(n);
const changeSonValue = () => {
n.value++;
};
let changeNumFromFather = ()=>{
props.changeNum()
}
watch(n,(n,o)=>{
console.log(n);
},{immediate:true,deep:true});
watch(props.obj,(n,o)=>{
console.log(n);
},{deep:true,immediate:true})
watch([n,props.obj],()=>{}) //多个监视用数组
</script>
<style scoped></style>
defineEmits
//father
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-04
* father.vue
-->
<template>
<div>
<h1>
{{num}}
<son @changeNum="getNum"></son>
</h1>
</div>
</template>
<script setup>
import { ref } from 'vue';
import son from './son.vue'
let num = ref(666);
let getNum = (v)=>{
num.value+=v
}
</script>
<style lang="scss" scoped>
</style>
//son
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-04
* son.vue
-->
<template>
<div>
<button @click="changeNumFromFather">changeNumFromFather</button>
</div>
</template>
<script setup>
let emits = defineEmits(['changeNum']);
let changeNumFromFather =()=>{
emits('changeNum',1)
}
</script>
<style lang="scss" scoped></style>
defineExpose 父组件需要借助ref
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-04
* father.vue
-->
<template>
<div >
<son ref="son1"></son>
<button @click="test">test</button>
</div>
</template>
<script setup >
import son from './son.vue';
import { ref } from 'vue';
const son1 = ref(null)
console.log(son1);
let test = ()=>{
console.log(son1.value.num);
son1.value.changeNum()
}
</script>
<style lang="scss" scoped>
</style>
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-04
* son.vue
-->
<template>
<div>
<h1>{{num}}</h1>
</div>
</template>
<script setup>
import { ref } from 'vue';
let num = ref(666);
let changeNum = ()=>{
num.value ++
}
defineExpose ({num,changeNum});
</script>
<style lang="scss" scoped>
</style>
ts写法
defineProps 三种写法
let props= defineProps(['str'])
console.log(props);
let props = defineProps({
str:String,
arr:{
type:Object,
default:()=>[1,2]
}
})
let props = defineProps<{
str:string,
arr:number[]
}>()
withDefaults(defineProps<{ //设置默认值
str:string,
arr:number[]
}>(),{
arr:()=>[666]
})
defineEmit
let emit = defineEmits(['ca'])
let emit = defineEmits<{ // 可以对每一个参数进行限制
(e:'ca',a:string,b:number,c:string):void
}>()
let changeArr = ()=>{
emit('ca','999',88,'jjj')
}
defineExpose
defineExpose<{n:string,s:Function}>({
n:'999',
s:()=>console.log('999'),
})
let wf = ref<InstanceType<typeof sVue>>();
onMounted(()=>{
wf.value?.s();
console.log(wf.value?.n);
})
2.v-model 组件标签可同时写多个v-model 不再支持 .sync
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-04
* father.vue
-->
<template>
<div >
<h1>father {{num1}}</h1>
<sonVue v-model:value1="num1" v-model:value2="num2" ></sonVue>
</div>
</template>
<script setup >
import { ref } from 'vue';
import sonVue from './son.vue';
let num1 = ref(666);
let num2 = ref(888)
</script>
<style lang="scss" scoped>
</style>
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-04
* son.vue
-->
<template>
<div>
<input type="text" v-model="num" @change="changeFatherValue1">
<button @click="changeFatherValue1">46546546</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
let props = defineProps({value1:{},value2:{}}) //{value:{}}
let emits = defineEmits(['value1'])
let num = ref(props.value1)
let changeFatherValue1 = ()=>{
emits('update:value1',num.value)
}
</script>
<style lang="scss" scoped>
</style>
3.provide inject
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-05
* grand.vue
-->
<template>
<div >
<h1>grand</h1>
<father></father>
</div>
</template>
<script setup >
import { getCurrentInstance, provide, ref } from 'vue';
import father from './father.vue'
let num = ref(10);
provide('num',num.value);
provide('test',99999999)
</script>
<style lang="scss" scoped>
</style>
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-05
* father.vue
-->
<template>
<div >
<son></son>
</div>
</template>
<script setup >
import son from './son.vue'
</script>
<style lang="scss" scoped>
</style>
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-05
* son.vue
-->
<template>
<div >
</div>
</template>
<script setup >
import { inject } from 'vue';
let num = inject('num');
console.log(num);
let test = inject('test');
console.log(test);
</script>
<style lang="scss" scoped>
</style>
4.attrs 会包含父组件的props 属性的集合 一旦用props接收,attrs
就接收不到了
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-05
* father.vue
-->
<template>
<div >
<son :m1="m1" :m2="m2"></son>
</div>
</template>
<script setup >
import { ref } from 'vue';
import son from './son.vue'
let m1 = ref(10);
let m2 = ref(100);
</script>
<style lang="scss" scoped>
</style>
<!--
* new page
* @author: keepCoding-gyk
* @since: 2022-12-05
* son.vue
-->
<template>
<div >
</div>
</template>
<script setup >
import { useAttrs } from 'vue';
let props = defineProps(['m1']);
let attrs = useAttrs();
console.log(attrs);
</script>
<style lang="scss" scoped>
</style>
5.插槽
vue2 | |
匿名插槽 | <slot/> |
具名 | <slot name="xxx"/> 模版标签 v-slot:xxx 或 #xxx |
作用域 | <slot :name="xxx"/> 模版 slot-scope="{name}" |
vue3 | 匿名 具名不变 |
作用域 | <slot :name="xxx"/> 模版 v-slot="{name}" 或者 #default="{name}" 或者 v-slot:default="slotProps" |
动态插槽
<template #[dyniamic]>
<h1>{{ dyniamic }}</h1>
</template>
import { ref } from 'vue';
let dyniamic = ref('dyniamic')
let dyniamicChange = ()=>{
dyniamic.value = 'test'
}
<slot name="dyniamic"></slot>
<slot name="test"></slot>
具名插槽也可以 当作用域 用
<template v-slot:app="scope">
{{ scope }}
</template>
<slot name="app" :msg="arr"></slot>