目录
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>









