Vue3组件详情

一、父组件向子组件传值 ref、props

// 父组件
<Son :showDialogVisible="showDialogVisible" />
<script>
import {defineComponent,ref} from 'Vue';
setup(){
  const showDialogVisible=ref(true);
  return {showDialogVisible}
}
</script>
<script>
// 子组件
import {defineComponent,ref} from 'Vue';
export default defineComponent({
  name:"",
  props:{showDialogVisible:Boolean},
  setup(props){
    return {props}
  }
})
</script>

二、子组件向父组件传值 emit

子组件中:
由于Vue数据传递时单向数据流,子组件没有权利修改父组件传递过来的数据,只能用emit通知父组件去修改。

<script>
 // 子组件
  setup(props,context){
    context.emit('setShow',false)
    return;
  }
  ...或者...
  setup(props,{emit}){
    emit('setShow',false)
    return;
  }
</script>
// 父组件
<Son :showDialogVisible="showDialogVisible"
 @setShow="setShowDialogVisible" />
<script>
import {defineComponent,ref} from 'Vue';
setup(){
  const showDialogVisible=ref(true);
  const setShowDialogVisible=(bool)=>{
    showDialogVisible=bool;
  }
  return {showDialogVisible,setShowDialogVisible}
}

三、子组件向父组件传值 v-model

如果子组件向父组件传的值正好是父组件向子组件传的值,可以直接在该属性上进行双向绑定。

// 子组件
// 直接修改从props中拿到的数据;
 context.emit('update:showDialogVisible',false)
</script>
// 父组件
<Son v-model:showDialogVisible="showDialogVisible"/>
<script>

四、setup语法糖

在vue2.0时期,组件里定义的各类变量,方法,计算属性等是分别放到data,methods,computed选项里。

setup是vue3.0后推出的语法糖,按需引入computed,watch,directive等,一个业务逻辑可以编写在一起,让代码更加简洁便于浏览。

1、基本用法

<script setup>
	console.log('Hello World');
</script>

只需在 < script > 里添加一个setup属性,编译时会把 < script setup> < / script >里的代码编译成一个setup函数。
普通的 < script > 只会在组件被首次引入的时候执行一次,< script setup> 里的代码会在每次组件实例被创建的时候执行。

2、data和methods

< script setup> 里声明的变量和函数,不需要return暴露出去,就可以直接在template使用。

<script setup>
  import {ref,reactive} from 'vue';
  const msg = "Hello World";//普通变量
  // 响应式变量
  let num = ref(11); //ref 声明基本变量类型
  const obj = reactive({//reactive 声明对象类型变量:Object,Array,Date
    key:"this is a object"
  })
  function getName(){}
</script>

3、计算属性 computed

<script setup>
  import {ref,computed} from 'vue';
  let num = ref(0); 
  const countPlus = computed(()=>{
    return num.value+1;
  })
</script>

4、监听器 watch、watchEffect

// watch
<script setup>
  import {ref,reactive,watch} from 'vue';
  // 监听ref
  let num = ref(0); 
  watch(num,(newval,oldval)={
    // ...
  })
  // 监听reactive
  const obj = reactive({
    key:"this is a object"
  })
  watch(obj.key,(newval,oldval)={
    // ...
  },{
    immediate:true,// 立即执行,默认false
    deep:true,//深度监听,默认false
  })
  
  const onChange = function () {
    num.value++;
    obj.key="this change"
  }
</script>

watchEffect :Vue3.0新增的监听属性的方法,与watch的区别在于,watchEffect不需要指定监听对象,回调函数里可直接获取到修改后的属性的值。

<script setup>
  import {ref,reactive,watchEffect} from 'vue';
  let num = ref(0); 
  const obj = reactive({
    key:"this is a object"
  })
  setTimeout( ()=> {
    num.value++;
    obj.key="this change"
  })
  watchEffect((newval,oldval)=>{
    console.log("修改后的count",count.value);
    console.log("修改后的obj",obj.key);
  })
</script>

5、自定义指令 directive

以vNameDirective的形式来命名本地自定义指令,可以直接在模板中使用。

<template>
 <h1 v-my-directive>今天的日记</h1>
</template>
<script setup>
// 导入指令可重命名
// import {myDirective as vMyDirective} from './MyDirective.js'
// 自定义指令
const vMyDirective={
  beforeMount:(el)=>{
    // 元素上做一些操作
  }
}
</script>

6、import导入的内容可以直接使用

导入的模快内容,不需要通过method来暴露它;
导入外部组件,不需要通过components注册使用;

7、声明props和emit

// Child.vue
<template>
  <h1>信息:{{info}}</h1>
  <el-button @click="onChange">点击</el-button>
</template>
<script setup>
import {defineProps,defineEmits} from 'vue';
// 声明Props
const props =defineProps({
  info:{type:String,default:""}
})
// 声明Emits
const $emit = defineEmits(['changeInfo']);
const onChange=function(){
  $emit('changeInfo','child返回值')
}
</script>
// Parent.vue
<template>
  <Child :info="msg" @changeInfo="onAction"></Child>
</template>
<script setup>
import {ref} from 'vue';
import Child from './Child.vue'
const onAction=function(event){
  console.log(event);
}
</script>

8、父组件获得子组件的数据(等同于Vue2.0中的$ref)

父组件想要通过ref获取子组件的变量或函数,子组件须使用defineExpose暴露出去。

// Child.vue
<script setup>
 import {ref,define} from 'vue';
 const info = ref('I am child');
 const onChange = function(){console.log('')};
 defineExpose({info,onChange})
</script>
// Parent.vue
<template>
  <Child ref="childRef"></Child>
  <el-button @click="onAction">点击</el-button>
</template>
<script setup>
 import {ref} from 'vue';
 import Child from './Child.vue'
 const childRef = ref();
 const onAction = function(){
   console.log(childRef.value.info)
   console.log(childRef.value.onChange());
 };
</script>

9、provide和inject传值

无论组件层次结构有多深,父组件都可以通过provide选项来为其所有子组件提供数据。

// Parent.vue
<template>
  <Child></Child>
</template>
<script setup>
 import {ref,provide} from 'vue';
 import Child from './Child.vue'
const msg = ref('Hello,my son');
const onShow = function(){...};
provide('myprovide',{msg,onShow})
</script>
// Child.vue
<template>
  <el-button @click="getDate">点击获取父组件的值</el-button>
</template>
<script setup>
 import {inject} from 'vue';
 const provideState = inject('myProvide');
 const getDate = function(){
  console.log(provideState.msg);
  console.log(provideState.onShow());
 }
</script>

10、对await异步支持

< script setup>中可以使用顶层await,结果代码会被编译成async setup()。例子:

<script setup>
  const post = await fetch('/api/post/tabledata').then(res=>{
    
  })
</script>

11、nextTick

//方式一
<script setup>
import {nextTick} from 'vue';
nextTick(()=>{});// Dom已更新
</script>
//方式二
<script setup>
import {nextTick} from 'vue';
await nextTick();// nextTick是一个异步函数,返回一个Promise实例
</script>

12、全局属性 globalProperties

// main.js
import {createApp} from 'vue';
import App from './App.vue';
const app = createApp(App);
// 定义一个全局属性
app.config.globalProperties.global="全局属性";
app.$mount("#app");
<script setup>
//组件内使用
import {getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();//获取Vue实例
console.log(proxy.$global);//输出
</script>

13、与普通< script >标签一起使用

可以与普通< script>标签一起使用,但是以下一些情况不会使用到:
①无法在<script setup>声明的选项 ,例如inheritAttrs 或通过插件启用的自定义的选项;
②声明命名导出,< script setup >定义的组件果默认以文件各作为组件名.
③运行副作用或者创建只需要执行一次的对象

< script >
//普通< script >,在模块范围下执行(只执行一次)
 runSideEffectOnce();
// 声明额外的选项
export default {
 name :'ComponentName ',//组件重命名
 inberitAttrs:false ,
 customOptons:{}
}
</ script >

<script setup )
//在 setup ()作用域中执行(对每个实例皆如此)
<script)

14、v-memo新指令

该指令与 v - once 类似, v - once 是只渲染一次之后的更新不再渲染,而 v - memo 是根据条件来渲染。该指令接收一个固定长度的数组作为依赖值进行记忆对比,如果数组中的每个值都和上次渲染的时候相同,则该元素(含子元素)不刷新。
①应用于普通元素或组件

< template >
< div v-meno ="[valueA ,valueB]"></ div >//普通元素
< component v-memo ="[valueA , valueB]"></ component >//组件
< /template >

< script setup )
 import component from ".../components/component.vne "
< /script >```

当组件重新渲染的时候,如果 valueA 与 valueB 都维持不变,那么对这个< div >以及它的所有子节点的更新都将被跳过。
②结合 v - for 使用
v - memo 仅供性能敏感场景的针对性优化,会用到的场景应该很少。渲染 v - for 长列表(长度大于1000)可能它是最有用的场景:

< template >
	< div v-for =" item in list " :key =" item.id " v-memo ="[ item.id == selected ]">
	< p > ID : {{item.id}}-selected : {{item.id == selected}}< /p >
	< / div>
</ template >

当 selected 发生变化时,只有 item . id === selected 的该项重新渲染,其余不刷新。

五、Vue3生命周期

请添加图片描述

  • 29
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值