Vue3 basic + advanced (two, vue3 commonly used combination api basic use)

Table of contents

Chapter 2, Composite API

2.1 Entry: setup

2.1.1 The writing method and execution timing of the setup option

2.1.2 Features of writing code in setup

2.1.3 script setup syntactic sugar

2.1.4 The point of this in setup

2.2 Generate responsive data: reactive and ref functions

2.2.1 reactive function

2.2.2 ref function

2.2.3 reactive versus ref

2.3 Calculated properties: computed

2.4 Data monitoring: watch

2.4.1 Listening to a single data

2.4.2 Listening to Multiple Data

2.4.3 immediate listen immediately

2.4.4 deep monitoring

2.5 Lifecycle hooks

2.6 Parent-child communication

2.6.1 Father-child communication

2.6.2 Child-father communication

2.7 Template reference

2.8 provide and inject


Chapter 2, Composite API

2.1 Entry: setup

2.1.1 The writing method and execution timing of the setup option

  • wording
<script>
  export default {
    setup(){
      
    },
    beforeCreate(){
      
    }
  }
</script>
  • Timing: Executed before the beforeCreate hook
<script>
  export default {
     beforeCreate(){
         console.log("beforeCreate生命钩子执行了-------------")
     },
     setup(){
          console.log("setup生命钩子执行了-------------")
     },
  }
</script>

  

2.1.2 Features of writing code in setup

The data and methods written in the setup function need to be returned as objects at the end before they can be used in the template

<script>
  export default {
    setup(){
      const message = 'this is message'
      const logMessage = ()=>{
        console.log(message)
      }
      // 必须return才可以
      return {
        message,
        logMessage
      }
    }
  }
</script>

2.1.3 script setup syntactic sugar

The script tag adds a setup tag, no need to write an export statement, and the export statement will be added by default

<script setup>
  const message = '关注我!!!'
  const logMessage = ()=>{
    console.log(message)
  }
</script>

<template>
  <h2>内容:{
   
   {message}}</h2>
  <br>
  <button @click="logMessage">输出消息</button>
</template>

2.1.4 The point of this in setup

this will no longer point to the component instance, it will point to undefined

<script setup>
  const logThis = ()=>{
    console.log("Vue3中this的指向",this)
  }
</script>

<template>
  <button @click="logThis">this</button>
</template>

2.2 Generate responsive data: reactive and ref functions

2.2.1 reactive function

Accept parameters of object type data and return a responsive object

<script setup>
 // 导入
import {reactive} from 'vue'
    // 执行函数 传入参数 变量接收
  const message = reactive({
    name:'关注我!!!'
  })
  const logMessage = ()=>{
    // 修改数据更新视图
    message.name += '!'
  }
</script>

<template>
  <h2>内容:{
   
   {message.name}}</h2>
  <br>
  <button @click="logMessage">输出消息+!</button>
</template>

 Make sure that the object defined by reactive is a reactive object

2.2.2 ref function

Receive data of simple type or object type and return a responsive object. Use ref to get the first-level object and remember to add .value

<script setup>
 // 导入
 import { ref } from 'vue'
 // 执行函数 传入参数 变量接收
 const count = ref(0)
 const setCount = ()=>{
   // 修改数据更新视图必须加上.value
   count.value++
 }
</script>

<template>
  <button @click="setCount">{
   
   {count}}</button>
</template>

 Make sure that the ref definition is also a responsive object:

2.2.3 reactive versus ref

  • 1. The same point: both are used to generate responsive data
  • 2. Differences

        --reactive cannot handle simple types of data

        -- The ref parameter type supports better, but it must be modified through .value

        -- The internal implementation of the ref function depends on the reactive function

  • 3. Recommendations in practice

       -- It is recommended to use the ref function to reduce memory burden

2.3 Calculated properties: computed

The basic idea of ​​calculated properties is consistent with that of Vue2. The calculated properties under the combined API only modify the API writing method; there cannot be asynchronous requests or DOM modifications, etc.

Core steps:

       1. Import the computed function
        2. The execution function returns the calculated value based on the responsive data in the callback parameter , and receives it with a variable

<script setup>
// 导入
import {ref, computed } from 'vue'
// 原始数据
const count = ref(1)
// 计算属性
const doubleCount = computed(()=>count.value * 2)

// 原始数据
const list = ref([1,2,3,4,5,6,7,8])
// 计算属性list
const filterList = computed(()=>{
  return list.value.filter ( item=>item > 2)
})
</script>

<template>
  <div>初始数据ref基本类型:{
   
   { count }} </div>
  <div>计算属性数据:{
   
   { doubleCount }} </div>
  <div>原始数据ref引用类型:{
   
   { list }}</div>
  <div>计算属性数据:{
   
   { filterList }}</div>
</template>

2.4 Data monitoring: watch

Listen to one or more data changes, execute the callback function when the data changes, the third parameter of watch (two additional parameters immediate control immediate execution, deep enables deep listening)

2.4.1 Listening to a single data

Core steps:

        1. Import the watch function
        2. Execute the watch function to pass in the responsive data (ref object) and callback function to be listened to

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const setCount =  ()=>{
    count.value++
  }
  // 2. 调用watch 侦听变化
  watch(count, (newValue, oldValue)=>{
    console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)
  })
</script>

<template>
  <button @click="setCount">{
   
   { count }}</button>
</template>

2.4.2 Listening to Multiple Data

Listen to multiple data, the first parameter can be rewritten as an array, and the old and new values ​​obtained are also in the form of an array

Description: Listen to multiple responsive data changes at the same time, no matter which data changes, you need to execute the callback

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const name = ref('cp')
  const setCount = ()=>{
    count.value++
  }
  const setName = ()=>{
    name.value += 'p'
  }
  // 2. 调用watch 侦听变化
  watch([count, name], ([newCount, newName],[oldCount,oldName])=>{
    console.log(`count或者name变化了`,[newCount, newName],[oldCount,oldName])
  })
</script>

<template>
  <button @click="setCount">{
   
   { count }}</button>
  <button @click="setName">{
   
   { name }}</button>
</template>

2.4.3 immediate listen immediately

The third parameter, triggers the callback immediately when the listener is created, and continues to execute the callback after the responsive data changes

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const setCount = ()=>{
    count.value++
  }
  // 2. 调用watch 侦听变化
  watch(count, (newValue, oldValue)=>{
    console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)
  },{
    immediate: true
  })
</script>

<template>
  <button @click="setCount">{
   
   { count }}</button>
</template>

2.4.4 deep monitoring

The third parameter, the ref object monitored by watch is shallow listening by default, directly modifying the nested object properties will not trigger callback execution, you need to enable deep

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const state = ref({ count: 0 })
  // 2. 监听对象state
  watch(state, ()=>{
    console.log('数据变化了')
  },{
    immediate:true,
    deep:true
  })
  const changeStateByCount = ()=>{
    // 直接修改不会引发回调执行
    state.value.count++
  }
</script>

<template>
  <button @click="changeStateByCount">{
   
   { state.count }}</button>
</template>

 1. The deeper value of the object has changed, but it is not detected

2. The deeper value of the object has changed, and it is also monitored

2.5 Lifecycle hooks

Basic use:

        1. Import the life cycle function
        2. Execute the life cycle function and pass in the callback

<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
    // 自定义逻辑
    console.log('组件挂载完毕mounted执行了')
})
</script>

  

Execute multiple times:

The callbacks passed in during multiple executions will be executed sequentially when the time is right

<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
    // 自定义逻辑
    console.log('组件挂载完毕mounted执行了2')
})
onMounted(()=>{
    // 自定义逻辑
    console.log('组件挂载完毕mounted执行了1')
})
</script>

  

2.6 Parent-child communication

2.6.1 Father-child communication

Basic idea:

        1. Bind attributes to child components in the parent component

        2. The subcomponent receives data through the props option

parent component:

<script setup> //引入子组件
    import sonComVue from './son.vue'
</script>
<template>
    <!-- 1.绑定属性message -->
    <div>父组件</div><br>
    <sonComVue message="this is app message "/>
</template>

Subassembly:

<script setup>
//2.通过defineProps"编译器宏"接收子组件传递的数据
const props = defineProps({
    message: String
})
</script>

<template>
    <div>
        子组件:{
   
   { message }}
    </div>
</template>

 

2.6.2 Child-father communication

Basic idea:

        1. In the parent component, label the child component through @binding custom events

        2. Events are triggered inside the subcomponent through the $emit method

parent component:

<script setup>
    //引入子组件
    import sonComVue from './son-com.vue '
    //自定一函数方法
    const getMessage = (msg)=→> {
        console.log(msg)
    }
</script>
<template>
    <!--1.绑定自定义事件-->
    <sonComVue @get-message="getMessage">
</template>

Subassembly:

<script setup>
// 2.通过 defineEmits编译器宏生成emit方法
    const emit = definEmits(['get-message'])
    const sendMsg =() {
        // 3.触发自定义事件并传递参数
        emit(' get-message ', 'this is son msg ')
    }
</script>
<template>
    <button @click="sendMsg">sendMsg</button>
</template>

Before sending:

After sending:

2.7 Template reference

Get the real dom object or component instance object through ref identification

Core steps:

        1. Call the ref function to generate a ref object

        2. Bind the ref object to the label through the ref identifier

<script setup>
    import { onMounted, ref } from 'vue'// 1.调用ref函数得到ref对象
    const h1Ref = ref(null)

    onMounted(()=>{
      console.log("hiRef",h1Ref)
    })
</script>
<template>
    <!--2.通过ref标识绑定ref对象-->
    <h1 ref="h1Ref">我是dom标签h1</h1>
</template>

defineExpose()
By default, the properties and methods inside the component under the syntactic sugar of <script setup> are not open to the parent component for access. You can specifywhich properties and methods are allowed to be accessed through the defineExpose compilation macro

<script setup>
    import { ref } from 'vue'
    const testMessage = ref('this is test msg ')
    defineExpose({ //向外暴露该组件的方法
        testMessage
    })
</script>

 When the macro is not compiled with defineExpose, the output ref has no method in the subcomponent:

 After use, you can see the corresponding method:

2.8 provide and inject

Role and scenario: Top-level components transfer data and methods to any underlying components to achieve cross-layer component communication

Provide: The top-level component provides data through the provide function

inject : The underlying component obtains data through the inject function

Remarks: When the top-level component provides data to the bottom-level component, the bottom-level component only renders the value; if the bottom-level component wants to change the passed value, the top-level component needs to provide a method to change the data again, and the bottom-level component gets the method and calls it Can change the value passed by the top-level component

parent component:

<script setup>
    import { provide, ref } from 'vue'// 1.调用ref函数得到ref对象
    import son from './son.vue'
    //1、顶层组件提供数据
    provide("data-key","this is data 关注关注!!")
    //传递响应式数据
    const count = ref(0)
    provide('count-key',count)

    setTimeout(()=>{
        count.value++
    },3000)

    //传递方法
    const setCount = () =>{
        count.value ++ 
    }
    provide('setCount-key',setCount)

    const name = ref('*VE*')
    provide('name-key',name)

    setTimeout(()=>{
        name.value += '关注我!!'
    },3000)
</script>
<template>
    <!--2.通过ref标识绑定ref对象-->
    <div style="background-color: red; padding: 20px;">
        <h1>顶层父组件</h1><br>
        <son ref="sonRef"></son>
    </div>
</template>

Intermediate components:

<script setup>
    import grandson from './grandson.vue'
</script>

<template>
    <div style="background-color: gold; padding: 20px;">
        <div>中间子组件</div><br>
        <grandson/>
    </div>
</template>

Low-level components:

<script setup>
import { inject } from "vue";

//2、接收数据
const data = inject('data-key')
//接收响应式数据
const count = inject('count-key')
const name = inject('name-key')
//接收方法
const setCount = inject('setCount-key')
</script>

<template>
  <div style="background-color: skyblue;">
    <div>底层孙组件——</div>
    <div>
      来自顶层父组件的数据为:{
   
   { data }}<br />
      来自顶层父组件的响应式数据为:{
   
   { count }}<br />
      来自顶层父组件的响应式数据为:{
   
   { name }}<br />
      <button @click="setCount">修改顶层组件的数据</button>
    </div>
  </div>
</template>

First render:

 Pass responsive data rendering:

 Transfer method: click the button, and the number modification indicates that the value of the top-level component has been modified

Guess you like

Origin blog.csdn.net/qq_45796592/article/details/131799066