国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Vue]Vue3學(xué)習(xí)筆記(尚硅谷)

這篇具有很好參考價(jià)值的文章主要介紹了[Vue]Vue3學(xué)習(xí)筆記(尚硅谷)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


?? 前言

本筆記根據(jù)如下筆記和視頻進(jìn)行整理
老師的課件筆記,不含視頻 https://www.aliyundrive.com/s/B8sDe5u56BU

筆記在線版: https://note.youdao.com/s/5vP46EPC

視頻:尚硅谷Vue2.0+Vue3.0全套教程丨vuejs從入門到精通


?? 創(chuàng)建Vue3項(xiàng)目

?? vue-cli

使用vue-cli創(chuàng)建Vue3項(xiàng)目,需要確保vue-cli版本在4.5.0以上。

## 查看@vue/cli版本,確保@vue/cli版本在4.5.0以上
vue --version
vue -V

## 安裝或者升級(jí)@vue/cli
npm install -g @vue/cli

使用vue-cli創(chuàng)建Vue3項(xiàng)目

vue create vue3_study

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? vite

vite創(chuàng)建Vue3項(xiàng)目步驟:

## 創(chuàng)建工程
npm init vite-app <project-name>
## 進(jìn)入工程目錄
cd <project-name>
## 安裝依賴
npm install
## 運(yùn)行
npm run dev
npm init vite-app vue3_study_vite

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

cd vue3_study_vite
npm i

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

npm run dev

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? 項(xiàng)目結(jié)構(gòu)

使用的為vue-cli創(chuàng)建的項(xiàng)目

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

src\main.js

// 引入的為一個(gè)名為createApp的工廠函數(shù),不再是Vue構(gòu)造函數(shù)
import { createApp } from 'vue'
import App from './App.vue'

// 創(chuàng)建應(yīng)用實(shí)例對(duì)象,類似于Vue2中的vm,但是更“輕”,并掛載根標(biāo)簽
createApp(App).mount('#app')

src\App.vue

<template>
  <!-- Vue3組件中的模板結(jié)構(gòu)可以沒有根標(biāo)簽 -->
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

?? Vue3開發(fā)者工具的安裝

可參考:[Vue]開發(fā)環(huán)境搭建

?? 初識(shí)setup

  • setup是Vue3.0中一個(gè)新的配置項(xiàng),值為一個(gè)函數(shù)。setup是所有Composition API(組合API)“ 表演的舞臺(tái) ”。組件中所用到的:數(shù)據(jù)、方法、計(jì)算屬性等等,均要配置在setup中。

  • setup函數(shù)的兩種返回值:

    • 若返回一個(gè)對(duì)象,則對(duì)象中的屬性、方法, 在模板中均可以直接使用。
      <template>
        <h1>個(gè)人介紹</h1>
        <h2>name: {{name}}</h2>
        <h2>age: {{age}}</h2>
        <button @click="sayHello">打招呼</button>
      </template>
      
      <script>
      export default {
        name: 'App',
        // 測(cè)試setup, 不考慮響應(yīng)式
        setup() {
          // 數(shù)據(jù)
          let name = 'ZS'
          let age = 22
      
          // 方法
          function sayHello() {
            alert(`my name is ${name}, I am ${age}, hello`)
          }
      
          // 返回一個(gè)對(duì)象
          return {
            name,
            age,
            sayHello
          }
        }
      }
      </script>
      
      尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
    • 若返回一個(gè)渲染函數(shù):則可以自定義渲染內(nèi)容。
      <template>
        <h1>個(gè)人介紹</h1>
        <h2>name: {{name}}</h2>
        <h2>age: {{age}}</h2>
        <button @click="sayHello">打招呼</button>
      </template>
      
      <script>
      import {h} from 'vue' // 導(dǎo)入渲染函數(shù)
      
      export default {
        name: 'App',
        // 測(cè)試setup, 不考慮響應(yīng)式
        setup() {
          // 數(shù)據(jù)
          let name = 'ZS'
          let age = 22
      
          // 方法
          function sayHello() {
            alert(`my name is ${name}, I am ${age}, hello`)
          }
      
          // 返回一個(gè)對(duì)象
          // return {
          //   name,
          //   age,
          //   sayHello
          // }
      
          // 返回一個(gè)函數(shù)(渲染函數(shù))
          // h1為渲染到頁面的標(biāo)簽,hello world為渲染內(nèi)容
          // h1為渲染到頁面的標(biāo)簽,hello world為渲染內(nèi)容
          return ()=>{ return h('h1', 'hello world') }
        }
      }
      </script>
      
      尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
  • 在Vue3中仍然可以使用Vue2的配置項(xiàng)

    <template>
      <h1>個(gè)人介紹</h1>
      <h2>name: {{name}}</h2>
      <h2>age: {{age}}</h2>
      <h2>sex: {{sex}}</h2>
      <button @click="sayHello">打招呼 vue3</button>
      <button @click="sayWelcome">打招呼 vue2</button>
    </template>
    
    <script>
    export default {
      name: 'App',
      data() {
        return {
          sex: 'male'
        }
      },
      methods: {
        sayWelcome() {
          alert('hello world vue2')
        }
      },
      // 測(cè)試setup, 不考慮響應(yīng)式
      setup() {
        // 數(shù)據(jù)
        let name = 'ZS'
        let age = 22
        // 方法
        function sayHello() {
          alert(`my name is ${name}, I am ${age}, hello`)
        }
        // 返回一個(gè)對(duì)象
        return {
          name,
          age,
          sayHello
        }
      }
    }
    </script>
    

    尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

  • setup盡量不要與Vue2.x配置混用。Vue2.x配置(data、methos、computed…)中可以訪問到setup中的屬性、方法。但在setup中不能訪問到Vue2.x配置(data、methos、computed…)。

    <template>
      <h1>個(gè)人介紹</h1>
      <h2>name: {{name}}</h2>
      <h2>age: {{age}}</h2>
      <h2>sex: {{sex}}</h2>
      <button @click="sayHello">打招呼 vue3</button>
      <button @click="sayWelcome">打招呼 vue2</button>
      <button @click="test1">vue2配置項(xiàng)讀取setup屬性方法</button>
      <button @click="test2">setup配置項(xiàng)讀取vue2配置項(xiàng)屬性方法</button>
    </template>
    
    <script>
    export default {
      name: 'App',
      data() {
        return {
          sex: 'male'
        }
      },
      methods: {
        sayWelcome() {
          alert('hello world vue2')
        },
        test1() {
          console.log(this.name)
          console.log(this.age)
          console.log(this.sayHello)
        }
      },
      // 測(cè)試setup, 不考慮響應(yīng)式
      setup() {
        // 數(shù)據(jù)
        let name = 'ZS'
        let age = 22
        // 方法
        function sayHello() {
          alert(`my name is ${name}, I am ${age}, hello`)
        }
        function test2() {
          console.log(this.sex)
          console.log(this.sayWelcome)
        }
        // 返回一個(gè)對(duì)象
        return {
          name,
          age,
          sayHello,
          test2,
        }
      }
    }
    </script>
    

    尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

  • Vue2配置項(xiàng)如果與setup中的屬性或方法沖突,setup優(yōu)先。即發(fā)生沖突時(shí),以Vue3為主。

    <template>
      <h1>a: {{a}}</h1>
    </template>
    
    <script>
    export default {
      name: 'App',
      data() {
        return {
          a: 100
        }
      },
      // 測(cè)試setup, 不考慮響應(yīng)式
      setup() {
        // 數(shù)據(jù)
        let a = 200
        // 返回一個(gè)對(duì)象
        return {
          a
        }
      }
    }
    </script>
    

    尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

  • setup不能是一個(gè)async函數(shù),因?yàn)榉祷刂挡辉偈莚eturn的對(duì)象, 而是promise, 模板看不到return對(duì)象中的屬性。(后期也可以返回一個(gè)Promise實(shí)例,但需要Suspense和異步組件的配合)

?? ref 函數(shù)

  • 作用: 定義一個(gè)響應(yīng)式的數(shù)據(jù)
  • 語法: const xxx = ref(initValue)
    • 創(chuàng)建一個(gè)包含響應(yīng)式數(shù)據(jù)的引用對(duì)象(reference對(duì)象,簡稱ref對(duì)象)。
    • JS中操作數(shù)據(jù): xxx.value
    • 模板中讀取數(shù)據(jù): 不需要.value,直接:<div>{{xxx}}</div>
  • 備注:
    • 接收的數(shù)據(jù)可以是:基本類型、也可以是對(duì)象類型。
    • 基本類型的數(shù)據(jù):響應(yīng)式依然是靠Object.defineProperty()getset完成的。
    • 對(duì)象類型的數(shù)據(jù):內(nèi)部 “ 求助 ” 了Vue3.0中的一個(gè)新函數(shù)—— reactive函數(shù)。
<template>
  <h1>個(gè)人信息</h1>
  <p>name: {{name}}</p>
  <p>age: {{age}}</p>
  <p>job: {{job.type}}</p>
  <p>salary: {{job.salary}}</p>
  <button @click="changeInfo">修改信息</button>
</template>

<script>
import {ref} from 'vue'

export default {
  name: 'App',
  setup() {
    // 數(shù)據(jù)
    let name = ref('ZS')
    let age = ref(22)
    let job = ref({
      type: '前端工程師',
      salary: '30k'
    })

    // 方法
    function changeInfo() {
      name.value = 'LS'
      age.value = 30
      job.value.type = 'Java開發(fā)工程師'
      job.value.salary = '40k'
    }

    // 返回一個(gè)對(duì)象
    return {
      name,
      age,
      job,
      changeInfo
    }
  }
}
</script>

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? reactive函數(shù)

  • 作用: 定義一個(gè)對(duì)象類型的響應(yīng)式數(shù)據(jù)(基本類型不要用它,要用ref函數(shù))
  • 語法:const 代理對(duì)象= reactive(源對(duì)象)接收一個(gè)對(duì)象(或數(shù)組),返回一個(gè)代理對(duì)象(Proxy的實(shí)例對(duì)象,簡稱proxy對(duì)象)
  • reactive定義的響應(yīng)式數(shù)據(jù)是“深層次的”。
  • 內(nèi)部基于 ES6 的 Proxy 實(shí)現(xiàn),通過代理對(duì)象操作源對(duì)象內(nèi)部數(shù)據(jù)進(jìn)行操作。
<template>
  <h1>個(gè)人信息</h1>
  <p>name: {{name}}</p>
  <p>age: {{age}}</p>
  <p>job: {{job.type}}</p>
  <p>salary: {{job.salary}}</p>
  <p>hobby: {{hobby}}</p>
  <p>測(cè)試數(shù)據(jù):{{job.a.b.c}}</p>
  <button @click="changeInfo">修改信息</button>
</template>

<script>
import {ref, reactive} from 'vue'

export default {
  name: 'App',
  setup() {
    // 數(shù)據(jù)
    let name = ref('ZS')
    let age = ref(22)
    let job = reactive({
      type: '前端工程師',
      salary: '30k',
      a: {
        b: {
          c: 1000
        }
      }
    })
    let hobby = reactive(['football', 'basketball'])

    // 方法
    function changeInfo() {
      name.value = 'LS'
      age.value = 30
      job.type = 'Java開發(fā)工程師'
      job.salary = '40k'
      job.a.b.c = 2000
      hobby[0] = 'reading'
    }

    // 返回一個(gè)對(duì)象
    return {
      name,
      age,
      job,
      hobby,
      changeInfo
    }
  }
}
</script>

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

??Vue3.0中的響應(yīng)式原理

?? vue2.x的響應(yīng)式

  • 實(shí)現(xiàn)原理:

    • 對(duì)象類型:通過Object.defineProperty()對(duì)屬性的讀取、修改進(jìn)行攔截(數(shù)據(jù)劫持)。

    • 數(shù)組類型:通過重寫更新數(shù)組的一系列方法來實(shí)現(xiàn)攔截。(對(duì)數(shù)組的變更方法進(jìn)行了包裹)。

      Object.defineProperty(data, 'count', {
          get () {}, 
          set () {}
      })
      
  • 存在問題:

    • 新增屬性、刪除屬性, 界面不會(huì)更新。
      • 使用this.$set(對(duì)象, '新屬性名', '新屬性值')Vue.set(對(duì)象, '新屬性名', '新屬性值')新增屬性,使用this.$delete(對(duì)象, '屬性名')Vue.$delete(對(duì)象, '屬性名')刪除屬性。
    • 直接通過下標(biāo)修改數(shù)組, 界面不會(huì)自動(dòng)更新。
      • 使用this.$set(數(shù)組, 數(shù)組下標(biāo), ‘新值’)數(shù)組.splice(下標(biāo), 下標(biāo)+1, ‘新值’)實(shí)現(xiàn)修改數(shù)組元素值。

?? Vue3.0的響應(yīng)式

  • 在Vue3中不存在“新增屬性、刪除屬性, 界面不會(huì)更新”與“直接通過下標(biāo)修改數(shù)組, 界面不會(huì)自動(dòng)更新”的問題。

    <template>
      <h1>個(gè)人信息</h1>
      <p v-show="person.name">name: {{person.name}}</p>
      <p>age: {{person.age}}</p>
      <p v-show="person.sex">sex: {{person.sex}}</p>
      <p>hobby: {{person.hobby}}</p>
      <button @click="changeInfo">changeInfo</button>
      <button @click="addSex">addSex</button>
      <button @click="deleteName">deleteName</button>
    </template>
    
    <script>
    import {ref, reactive} from 'vue'
    
    export default {
      name: 'App',
      setup() {
        // 數(shù)據(jù)
        const person = reactive({
          name: 'ZS',
          age: 22,
          hobby: ['apple', 'orange']
        })
    
        // 方法
        function changeInfo() {
          person.hobby[0] = 'mango'
        }
        function addSex() {
          person.sex = 'male'
        }
        function deleteName() {
          delete person.name
        }
    
        // 返回一個(gè)對(duì)象
        return {
          person,
          changeInfo,
          addSex,
          deleteName,
        }
      }
    }
    </script>
    

    尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
    尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

  • 實(shí)現(xiàn)原理:

    • 通過Proxy(代理): 攔截對(duì)象中任意屬性的變化, 包括:屬性值的讀寫、屬性的添加、屬性的刪除等。

      //源數(shù)據(jù)
      let person = {
      	name:'張三',
      	age:18
      }
      
      //模擬Vue3中實(shí)現(xiàn)響應(yīng)式
      //Proxy對(duì)屬性的增刪改查都可以監(jiān)測(cè)得到
      //#region 
      const p = new Proxy(person,{
      	//有人讀取p的某個(gè)屬性時(shí)調(diào)用
      	get(target,propName){
      		console.log(`有人讀取了p身上的${propName}屬性`)
      		return target[propName]
      	},
      	//有人修改p的某個(gè)屬性、或給p追加某個(gè)屬性時(shí)調(diào)用
      	set(target,propName,value){
      		console.log(`有人修改了p身上的${propName}屬性,我要去更新界面了!`)
      		target[propName] = value
      	},
      	//有人刪除p的某個(gè)屬性時(shí)調(diào)用
      	deleteProperty(target,propName){
      		console.log(`有人刪除了p身上的${propName}屬性,我要去更新界面了!`)
      		return delete target[propName]
      	}
      })
      //#endregion
      
    • 通過Reflect(反射): 對(duì)源對(duì)象的屬性進(jìn)行操作。

      // Reflect(反射)
      // 讀取對(duì)象指定屬性的值
      Reflect.get(object, '屬性名')
      // 修改對(duì)象指定屬性的值
      Reflect.set(object, '屬性名', '新屬性值')
      // 刪除對(duì)象指定屬性
      Reflect.deleteProperty(object, '屬性名')
      
      //模擬Vue3中實(shí)現(xiàn)響應(yīng)式
      //#region 
      const p = new Proxy(person,{
      	//有人讀取p的某個(gè)屬性時(shí)調(diào)用
      	get(target,propName){
      		console.log(`有人讀取了p身上的${propName}屬性`)
      		return Reflect.get(target,propName)
      	},
      	//有人修改p的某個(gè)屬性、或給p追加某個(gè)屬性時(shí)調(diào)用
      	set(target,propName,value){
      		console.log(`有人修改了p身上的${propName}屬性,我要去更新界面了!`)
      		Reflect.set(target,propName,value)
      	},
      	//有人刪除p的某個(gè)屬性時(shí)調(diào)用
      	deleteProperty(target,propName){
      		console.log(`有人刪除了p身上的${propName}屬性,我要去更新界面了!`)
      		return Reflect.deleteProperty(target,propName)
      	}
      })
      //#endregion
      
    • MDN文檔中描述的Proxy與Reflect:

      • Proxy:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

      • Reflect:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect

        new Proxy(data, {
        	// 攔截讀取屬性值
            get (target, prop) {
            	return Reflect.get(target, prop)
            },
            // 攔截設(shè)置屬性值或添加新屬性
            set (target, prop, value) {
            	return Reflect.set(target, prop, value)
            },
            // 攔截刪除屬性
            deleteProperty (target, prop) {
            	return Reflect.deleteProperty(target, prop)
            }
        })
        
        proxy.name = 'tom'   
        

?? reactive對(duì)比ref

  • 從定義數(shù)據(jù)角度對(duì)比:
    • ref用來定義:基本類型數(shù)據(jù)。
    • reactive用來定義:對(duì)象(或數(shù)組)類型數(shù)據(jù)
    • 備注:ref也可以用來定義對(duì)象(或數(shù)組)類型數(shù)據(jù), 它內(nèi)部會(huì)自動(dòng)通過reactive轉(zhuǎn)為代理對(duì)象。
  • 從原理角度對(duì)比:
    • ref通過Object.defineProperty()getset來實(shí)現(xiàn)響應(yīng)式(數(shù)據(jù)劫持)。
    • reactive通過使用Proxy來實(shí)現(xiàn)響應(yīng)式(數(shù)據(jù)劫持), 并通過Reflect操作源對(duì)象內(nèi)部的數(shù)據(jù)。
  • 從使用角度對(duì)比:
    • ref定義的數(shù)據(jù):操作數(shù)據(jù)需要.value,讀取數(shù)據(jù)時(shí)模板中直接讀取不需要.value。
    • reactive定義的數(shù)據(jù):操作數(shù)據(jù)與讀取數(shù)據(jù):均不需要.value。
  • 一般將數(shù)據(jù)封裝在一個(gè)data對(duì)象中,利用reactive函數(shù)將該對(duì)象變?yōu)轫憫?yīng)式數(shù)據(jù)對(duì)象

?? setup的兩個(gè)注意點(diǎn)

  • setup執(zhí)行的時(shí)機(jī)
    • 在beforeCreate之前執(zhí)行一次,this是undefined,在setup無法使用this。
  • setup的參數(shù)
    • props:值為對(duì)象,包含:組件外部傳遞過來,且組件內(nèi)部聲明接收了的屬性。
    • context:上下文對(duì)象
      • attrs: 值為對(duì)象,包含:組件外部傳遞過來,但沒有在props配置中聲明接收的屬性, 相當(dāng)于 this.$attrs。存放沒有被組件props配置項(xiàng)接收的數(shù)據(jù),如果組件外部傳遞過來的數(shù)據(jù)都被組件props配置項(xiàng)接收,則該對(duì)象為空。
      • slots: 收到的插槽內(nèi)容, 相當(dāng)于 this.$slots。Vue3中具名插槽使用v-slot:插槽名
      • emit: 分發(fā)自定義事件的函數(shù), 相當(dāng)于 this.$emit。Vue3綁定的自定義事件在組件中需要使用emits配置項(xiàng)接收。

App.vue

<template>
	<Demo @hello="showHelloMsg" msg="你好啊" school="尚硅谷">
		<!-- Vue3中具名插槽使用 `v-slot:插槽名` -->
		<template v-slot:qwe>
			<span>尚硅谷</span>
		</template>
		<template v-slot:asd>
			<span>尚硅谷</span>
		</template>
	</Demo>
</template>

<script>
	import Demo from './components/Demo'
	export default {
		name: 'App',
		components:{Demo},
		setup(){
			// 自定義事件的處理函數(shù)
			function showHelloMsg(value){
				alert(`你好啊,你觸發(fā)了hello事件,我收到的參數(shù)是:${value}!`)
			}
			return {
				showHelloMsg
			}
		}
	}
</script>

Demo.vue

<template>
	<h1>一個(gè)人的信息</h1>
	<h2>姓名:{{person.name}}</h2>
	<h2>年齡:{{person.age}}</h2>
	<button @click="test">測(cè)試觸發(fā)一下Demo組件的Hello事件</button>
</template>

<script>
	import {reactive} from 'vue'
	export default {
		name: 'Demo',
		props:['msg','school'],
		emits:['hello'], // 綁定的自定義事件在組件中需要使用emits配置項(xiàng)接收
		setup(props,context){
			// console.log('---setup---',props)
			// console.log('---setup---',context)
			// console.log('---setup---',context.attrs) //相當(dāng)與Vue2中的$attrs
			// console.log('---setup---',context.emit) //觸發(fā)自定義事件的。
			console.log('---setup---',context.slots) //插槽
			//數(shù)據(jù)
			let person = reactive({
				name:'張三',
				age:18
			})

			//方法
			function test(){
				// 觸發(fā)自定義事件
				context.emit('hello',666)
			}

			//返回一個(gè)對(duì)象(常用)
			return {
				person,
				test
			}
		}
	}
</script>

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? computed函數(shù)

  • 與Vue2.x中computed配置功能一致,在Vue3中可以使用Vue2中的寫法(向下兼容)。在Vue3中計(jì)算屬性使用computed函數(shù)。

  • 寫法

    import {computed} from 'vue'
    
    setup(){
        ...
    	//計(jì)算屬性——簡寫
        let fullName = computed(()=>{
            return person.firstName + '-' + person.lastName
        })
        //計(jì)算屬性——完整
        let fullName = computed({
            get(){
                return person.firstName + '-' + person.lastName
            },
            set(value){
                const nameArr = value.split('-')
                person.firstName = nameArr[0]
                person.lastName = nameArr[1]
            }
        })
    }
    
<template>
	<h1>一個(gè)人的信息</h1>
    姓: <input type="text" v-model="person.firstName"><br/>
    名: <input type="text" v-model="person.lastName"><br/>
    <p>全名: {{person.fullName}}</p>
</template>

<script>
	import {reactive, computed} from 'vue'
	export default {
		name: 'Demo',
		setup(){
			//數(shù)據(jù)
			let person = reactive({
				firstName: '張',
        		lastName: '三'
			})

	      // 計(jì)算屬性
	      person.fullName = computed(()=>{
	        return person.firstName + '-' + person.lastName
	      })

			//返回一個(gè)對(duì)象
			return {
				person,
			}
		 }
	}
</script>

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? watch函數(shù)

  • 與Vue2.x中watch配置功能一致,在Vue3中可以使用Vue2中的寫法(向下兼容)。

  • 兩個(gè)小“坑”:

    • 監(jiān)視r(shí)eactive定義的響應(yīng)式數(shù)據(jù)時(shí):oldValue無法正確獲取、強(qiáng)制開啟了深度監(jiān)視(deep配置失效)。
    • 監(jiān)視r(shí)eactive定義的響應(yīng)式數(shù)據(jù)中某個(gè)屬性時(shí):deep配置有效。
	//數(shù)據(jù)
 let sum = ref(0)
   let msg = ref('你好啊')
   let person = reactive({
   	name:'張三',
   	age:18,
   	job:{
   		j1:{
   			salary:20
   		}
   	}
   })

//情況一:監(jiān)視r(shí)ef定義的響應(yīng)式數(shù)據(jù)
// 第一個(gè)參數(shù)為監(jiān)視的數(shù)據(jù),第二個(gè)參數(shù)為回調(diào)函數(shù),第三個(gè)參數(shù)為配置屬性
watch(sum,(newValue,oldValue)=>{
	console.log('sum變化了',newValue,oldValue)
},{immediate:true})

//情況二:監(jiān)視多個(gè)ref定義的響應(yīng)式數(shù)據(jù)
// newValue,oldValue為數(shù)組類型數(shù)據(jù)
watch([sum,msg],(newValue,oldValue)=>{
	console.log('sum或msg變化了',newValue,oldValue)
}) 

/* 情況三:監(jiān)視r(shí)eactive定義的響應(yīng)式數(shù)據(jù)
			若watch監(jiān)視的是reactive定義的響應(yīng)式數(shù)據(jù),則無法正確獲得oldValue??!
			如果需要獲取監(jiān)視對(duì)象中某個(gè)屬性的oldValue,可以采用將該屬性單獨(dú)取出使用ref的形式
			若watch監(jiān)視的是reactive定義的響應(yīng)式數(shù)據(jù),則強(qiáng)制開啟了深度監(jiān)視 
*/
// 如果監(jiān)視的對(duì)象為使用ref函數(shù)實(shí)現(xiàn)響應(yīng)式,則需要監(jiān)視`變量.value`,對(duì)于對(duì)象類型數(shù)據(jù)ref借助了reactive
watch(person,(newValue,oldValue)=>{
	console.log('person變化了',newValue,oldValue)
},{immediate:true,deep:false}) //此處的deep配置不再奏效

//情況四:監(jiān)視r(shí)eactive定義的響應(yīng)式數(shù)據(jù)中的某個(gè)屬性
watch(()=>person.job,(newValue,oldValue)=>{
	console.log('person的job變化了',newValue,oldValue)
},{immediate:true,deep:true}) 

//情況五:監(jiān)視r(shí)eactive定義的響應(yīng)式數(shù)據(jù)中的某些屬性
watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
	console.log('person的job變化了',newValue,oldValue)
},{immediate:true,deep:true})

//特殊情況
// 監(jiān)視r(shí)eactive所定義的對(duì)象中的某個(gè)屬性,且該屬性也為對(duì)象類型
watch(()=>person.job,(newValue,oldValue)=>{
    console.log('person的job變化了',newValue,oldValue)
},{deep:true}) //此處由于監(jiān)視的是reactive所定義的對(duì)象中的某個(gè)屬性,所以deep配置有效
  • 對(duì)于使用ref函數(shù)定義的數(shù)據(jù),如果為基本數(shù)據(jù)類型,則使用watch監(jiān)視時(shí),不使用變量.value的形式,因?yàn)椴荒鼙O(jiān)視一個(gè)字面量,監(jiān)視的需要為一個(gè)存放數(shù)據(jù)的結(jié)構(gòu);如果為對(duì)象類型,此時(shí)value的值為Proxy對(duì)象,如果沒有開啟深度監(jiān)視,只要value對(duì)應(yīng)的對(duì)象的引用沒有改變相當(dāng)于值沒有修改,解決方法:
    1. 開啟深度監(jiān)視,監(jiān)視Proxy對(duì)象中屬性的變化
    2. 監(jiān)視變量.value,由于Proxy對(duì)象時(shí)ref函數(shù)借助reactive函數(shù)生成的,監(jiān)視變量.value相當(dāng)于監(jiān)視r(shí)eactive函數(shù)生成的Proxy對(duì)象

?? watchEffect函數(shù)

  • watch的套路是:既要指明監(jiān)視的屬性,也要指明監(jiān)視的回調(diào)。
  • watchEffect的套路是:不用指明監(jiān)視哪個(gè)屬性,監(jiān)視的回調(diào)中用到哪個(gè)屬性,那就監(jiān)視哪個(gè)屬性。
  • watchEffect有點(diǎn)像computed:
    • 兩個(gè)函數(shù)中所依賴的數(shù)據(jù)發(fā)生變化,都會(huì)重新執(zhí)行一次回調(diào)。
    • 但computed注重的計(jì)算出來的值(回調(diào)函數(shù)的返回值),所以必須要寫返回值。
    • 而watchEffect更注重的是過程(回調(diào)函數(shù)的函數(shù)體),所以不用寫返回值。
    //watchEffect所指定的回調(diào)中用到的數(shù)據(jù)只要發(fā)生變化,則直接重新執(zhí)行回調(diào)。
    watchEffect(()=>{
        const x1 = sum.value
        const x2 = person.age
        console.log('watchEffect配置的回調(diào)執(zhí)行了')
    })
    

?? 生命周期

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

  • Vue3.0中可以繼續(xù)使用Vue2.x中的生命周期鉤子,但有有兩個(gè)被更名:

    • beforeDestroy改名為 beforeUnmount

    • destroyed改名為 unmounted

      App.vue

      <template>
      	<button @click="isShowDemo = !isShowDemo">切換隱藏/顯示</button>
      	<Demo v-if="isShowDemo"/>
      </template>
      
      <script>
      	import {ref} from 'vue'
      	import Demo from './components/Demo'
      	export default {
      		name: 'App',
      		components:{Demo},
      		setup() {
      			let isShowDemo = ref(true)
      			return {isShowDemo}
      		}
      	}
      </script>
      

      Demo.vue

      <template>
        <h2>當(dāng)前求和為:{{sum}}</h2>
        <button @click="sum++">點(diǎn)我+1</button>
      </template>
      
      <script>
      import { ref } from 'vue'
      export default {
        name: 'Demo',
        setup() {
          //數(shù)據(jù)
          let sum = ref(0)
      
          //返回一個(gè)對(duì)象(常用)
          return { sum }
        },
        //通過配置項(xiàng)的形式使用生命周期鉤子
        //#region
        beforeCreate() {
          console.log('---beforeCreate---')
        },
        created() {
          console.log('---created---')
        },
        beforeMount() {
          console.log('---beforeMount---')
        },
        mounted() {
          console.log('---mounted---')
        },
        beforeUpdate() {
          console.log('---beforeUpdate---')
        },
        updated() {
          console.log('---updated---')
        },
        beforeUnmount() {
          console.log('---beforeUnmount---')
        },
        unmounted() {
          console.log('---unmounted---')
        }
        //#endregion
      }
      </script>
      

      尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
      尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

  • Vue3.0也提供了 Composition API 形式的生命周期鉤子,與Vue2.x中鉤子對(duì)應(yīng)關(guān)系如下:

    • beforeCreate===>setup()

    • created=======>setup()

    • beforeCreatecreated沒有對(duì)應(yīng)組合式API,setup()相當(dāng)于beforeCreatecreated,對(duì)于配置項(xiàng)setup()的執(zhí)行時(shí)機(jī)早于配置項(xiàng)beforeCreatecreated

    • beforeMount ===>onBeforeMount

    • mounted=======>onMounted

    • beforeUpdate===>onBeforeUpdate

    • updated =======>onUpdated

    • beforeUnmount ==>onBeforeUnmount

    • unmounted =====>onUnmounted

    • 如果組合式API的生命周期與配置項(xiàng)形式的生命周期一起寫,組合式API的生命周期的執(zhí)行時(shí)機(jī)優(yōu)先于配置項(xiàng)形式的生命周期。

    • 一般情況下統(tǒng)一使用組合式API的生命周期,或者統(tǒng)一使用配置項(xiàng)形式的生命周期

      <template>
      	<h2>當(dāng)前求和為:{{sum}}</h2>
      	<button @click="sum++">點(diǎn)我+1</button>
      </template>
      
      <script>
      	import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
      	export default {
      		name: 'Demo',
      		
      		setup(){
      			console.log('---setup---')
      			//數(shù)據(jù)
      			let sum = ref(0)
      
      			//通過組合式API的形式去使用生命周期鉤子
      			onBeforeMount(()=>{
      				console.log('---onBeforeMount---')
      			})
      			onMounted(()=>{
      				console.log('---onMounted---')
      			})
      			onBeforeUpdate(()=>{
      				console.log('---onBeforeUpdate---')
      			})
      			onUpdated(()=>{
      				console.log('---onUpdated---')
      			})
      			onBeforeUnmount(()=>{
      				console.log('---onBeforeUnmount---')
      			})
      			onUnmounted(()=>{
      				console.log('---onUnmounted---')
      			})
      
      			//返回一個(gè)對(duì)象(常用)
      			return {sum}
      		},
      		//通過配置項(xiàng)的形式使用生命周期鉤子
      		//#region 
      		beforeCreate() {
      			console.log('---beforeCreate---')
      		},
      		created() {
      			console.log('---created---')
      		},
      		beforeMount() {
      			console.log('---beforeMount---')
      		},
      		mounted() {
      			console.log('---mounted---')
      		},
      		beforeUpdate(){
      			console.log('---beforeUpdate---')
      		},
      		updated() {
      			console.log('---updated---')
      		},
      		beforeUnmount() {
      			console.log('---beforeUnmount---')
      		},
      		unmounted() {
      			console.log('---unmounted---')
      		},
      		//#endregion
      	}
      </script>
      

      尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
      尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? 自定義hook函數(shù)

  • 什么是hook?—— 本質(zhì)是一個(gè)函數(shù),把setup函數(shù)中使用的Composition API進(jìn)行了封裝。

  • 類似于vue2.x中的mixin。

  • 自定義hook的優(yōu)勢(shì): 復(fù)用代碼, 讓setup中的邏輯更清楚易懂。

src\hooks\usePoint.js

import {reactive,onMounted,onBeforeUnmount} from 'vue'

export default function() {
	//實(shí)現(xiàn)鼠標(biāo)“打點(diǎn)”相關(guān)的數(shù)據(jù)
	let point = reactive({
		x:0,
		y:0
	})

	//實(shí)現(xiàn)鼠標(biāo)“打點(diǎn)”相關(guān)的方法
	function savePoint(event){
		point.x = event.pageX
		point.y = event.pageY
		console.log(event.pageX,event.pageY)
	}

	//實(shí)現(xiàn)鼠標(biāo)“打點(diǎn)”相關(guān)的生命周期鉤子
	onMounted(()=>{
		window.addEventListener('click',savePoint)
	})

	onBeforeUnmount(()=>{
		window.removeEventListener('click',savePoint)
	})

	return point
}

Demo.vue

<template>
	<h2>當(dāng)前求和為:{{sum}}</h2>
	<button @click="sum++">點(diǎn)我+1</button>
	<hr>
	<h2>當(dāng)前點(diǎn)擊時(shí)鼠標(biāo)的坐標(biāo)為:x:{{point.x}},y:{{point.y}}</h2>
</template>

<script>
	import {ref} from 'vue'
	import usePoint from '../hooks/usePoint'
	export default {
		name: 'Demo',
		setup(){
			//數(shù)據(jù)
			let sum = ref(0)
			let point = usePoint()
			

			//返回一個(gè)對(duì)象(常用)
			return {sum,point}
		}
	}
</script>

?? toRef

  • 作用:創(chuàng)建一個(gè) ref 對(duì)象,其value值指向另一個(gè)對(duì)象中的某個(gè)屬性。
  • 語法:const name = toRef(person,'name')
  • 應(yīng)用: 要將響應(yīng)式對(duì)象中的某個(gè)屬性單獨(dú)提供給外部使用時(shí)。
  • 擴(kuò)展:toRefstoRef功能一致,但可以批量創(chuàng)建多個(gè) ref 對(duì)象,創(chuàng)建一個(gè)對(duì)象中所有屬性對(duì)應(yīng)的 ref 對(duì)象,語法:toRefs(person)
<template>
	<h4>{{person}}</h4>
	<h2>姓名:{{name}}</h2>
	<h2>年齡:{{age}}</h2>
	<h2>薪資:{{job.j1.salary}}K</h2>
	<button @click="name+='~'">修改姓名</button>
	<button @click="age++">增長年齡</button>
	<button @click="job.j1.salary++">漲薪</button>
</template>

<script>
	import {ref,reactive,toRef,toRefs} from 'vue'
	export default {
		name: 'Demo',
		setup(){
			//數(shù)據(jù)
			let person = reactive({
				name:'張三',
				age:18,
				job:{
					j1:{
						salary:20
					}
				}
			})

			// const name1 = person.name
			// console.log('%%%',name1)

			// const name2 = toRef(person,'name')
			// console.log('####',name2)

			const x = toRefs(person)
			console.log('******',x)

			//返回一個(gè)對(duì)象(常用)
			return {
				person,
				// name:toRef(person,'name'),
				// age:toRef(person,'age'),
				// salary:toRef(person.job.j1,'salary'),
				...toRefs(person)
			}
		}
	}
</script>

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? shallowReactive 與 shallowRef

  • shallowReactive:只處理對(duì)象最外層屬性的響應(yīng)式(淺響應(yīng)式)。
  • shallowRef:只處理基本數(shù)據(jù)類型的響應(yīng)式, 不進(jìn)行對(duì)象的響應(yīng)式處理,對(duì)于對(duì)象類型數(shù)據(jù)直接將該對(duì)象作為ref對(duì)象的value的值。
  • 什么時(shí)候使用?
    • 如果有一個(gè)對(duì)象數(shù)據(jù),結(jié)構(gòu)比較深, 但變化時(shí)只是最外層屬性變化 ===> shallowReactive。
    • 如果有一個(gè)對(duì)象數(shù)據(jù),后續(xù)功能不會(huì)修改該對(duì)象中的屬性,而是生成新的對(duì)象來替換,即對(duì)于該對(duì)象數(shù)據(jù)在后續(xù)功能中不會(huì)修改其屬性,而是會(huì)將該對(duì)象整個(gè)進(jìn)行替換 ===> shallowRef。

?? readonly 與 shallowReadonly

  • readonly 與 shallowReadonly 均接收一個(gè)響應(yīng)式數(shù)據(jù)為參數(shù)。
  • readonly: 讓一個(gè)響應(yīng)式數(shù)據(jù)變?yōu)橹蛔x的(深只讀),傳入的響應(yīng)式數(shù)據(jù)不管有幾層,都不能進(jìn)行修改。
  • shallowReadonly:讓一個(gè)響應(yīng)式數(shù)據(jù)變?yōu)橹蛔x的(淺只讀),傳入的響應(yīng)式數(shù)據(jù)只有最外層數(shù)據(jù)不能進(jìn)行修改。
  • 應(yīng)用場景: 不希望數(shù)據(jù)被修改時(shí)。將數(shù)據(jù)交給其他組件并且不希望這個(gè)組件對(duì)數(shù)據(jù)進(jìn)行更改。

?? toRaw 與 markRaw

  • toRaw:
    • toRaw 接收一個(gè)響應(yīng)式對(duì)象為參數(shù),只能接收reactive生成的響應(yīng)式對(duì)象,不能處理ref生成的響應(yīng)式數(shù)據(jù)
    • 作用:將一個(gè)由reactive生成的響應(yīng)式對(duì)象轉(zhuǎn)為普通對(duì)象
    • 使用場景:用于讀取響應(yīng)式對(duì)象對(duì)應(yīng)的普通對(duì)象,對(duì)這個(gè)普通對(duì)象的所有操作,不會(huì)引起頁面更新。
  • markRaw:
    • 接收一個(gè)對(duì)象類型數(shù)據(jù)為參數(shù)
    • 作用:標(biāo)記一個(gè)對(duì)象,使其永遠(yuǎn)不會(huì)再成為響應(yīng)式對(duì)象。向一個(gè)已經(jīng)是響應(yīng)式對(duì)象的數(shù)據(jù)追加一個(gè)屬性,該屬性的值為對(duì)象類型數(shù)據(jù),vue會(huì)為其自動(dòng)添加響應(yīng)式,當(dāng)不希望該屬性的值為響應(yīng)式時(shí)可以使用該函數(shù),減小開銷。
    • 應(yīng)用場景:
      1. 有些值不應(yīng)被設(shè)置為響應(yīng)式的,例如復(fù)雜的第三方類庫等,如果向響應(yīng)式對(duì)象追加一個(gè)第三方類庫對(duì)象(一般屬性多且層次多),開銷會(huì)很大。
      2. 當(dāng)渲染具有不可變數(shù)據(jù)源的大列表時(shí),跳過響應(yīng)式轉(zhuǎn)換可以提高性能。

?? customRef

  • 作用:創(chuàng)建一個(gè)自定義的 ref,并對(duì)其依賴項(xiàng)跟蹤和更新觸發(fā)進(jìn)行顯式控制。

  • 實(shí)現(xiàn)防抖效果:

  <template>
  	<input type="text" v-model="keyword">
  	<h3>{{keyword}}</h3>
  </template>
  
  <script>
  	import {ref,customRef} from 'vue'
  	export default {
  		name:'Demo',
  		setup(){
  			// let keyword = ref('hello') //使用Vue準(zhǔn)備好的內(nèi)置ref
  			//自定義一個(gè)myRef
  			function myRef(value,delay){
  				let timer
  				//通過customRef去實(shí)現(xiàn)自定義
  				return customRef((track,trigger)=>{
  					return{
  						get(){ // 讀取數(shù)據(jù)時(shí)調(diào)用
  							track() //告訴Vue這個(gè)value值是需要被“追蹤”的,告訴vue追蹤數(shù)據(jù)的變化
  							return value
  						},
  						set(newValue){ // 修改數(shù)據(jù)時(shí)調(diào)用
  							clearTimeout(timer) // 觸發(fā)就清除原先的定時(shí)器不執(zhí)行之前定時(shí)器的回調(diào)
  							timer = setTimeout(()=>{
  								value = newValue // 修改數(shù)據(jù)
  								trigger() //告訴Vue去更新界面,重新解析模板
  							},delay)
  						}
  					}
  				})
  			}
  			let keyword = myRef('hello',500) //使用程序員自定義的ref
  			return {
  				keyword
  			}
  		}
  	}
  </script>

?? provide 與 inject

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

  • 作用:實(shí)現(xiàn)祖與后代組件間通信

  • 套路:父組件有一個(gè) provide 選項(xiàng)來提供數(shù)據(jù),后代組件有一個(gè) inject 選項(xiàng)來開始使用這些數(shù)據(jù)

  • 具體寫法:

    1. 祖組件中:

      setup(){
      	......
          let car = reactive({name:'奔馳',price:'40萬'})
          // 給后代組件傳遞數(shù)據(jù) 
          // 第一個(gè)參數(shù)為對(duì)傳遞數(shù)據(jù)的命名,第二個(gè)參數(shù)為傳遞的數(shù)據(jù)
          provide('car',car)
          ......
      }
      
    2. 后代組件中:

      setup(props,context){
      	......
      	// 獲取祖組件傳遞過來命名為car的數(shù)據(jù)
          const car = inject('car')
          return {car}
      	......
      }
      

?? 響應(yīng)式數(shù)據(jù)的判斷

  • isRef: 檢查一個(gè)值是否為一個(gè) ref 對(duì)象
  • isReactive: 檢查一個(gè)對(duì)象是否是由 reactive 創(chuàng)建的響應(yīng)式代理
  • isReadonly: 檢查一個(gè)對(duì)象是否是由 readonly 創(chuàng)建的只讀代理
  • isProxy: 檢查一個(gè)對(duì)象是否是由 reactive 或者 readonly 方法創(chuàng)建的代理

?? Composition API 的優(yōu)勢(shì)

?? Options API (配置式API)存在的問題

使用傳統(tǒng)OptionsAPI中,新增或者修改一個(gè)需求,就需要分別在data,methods,computed里修改 。同一個(gè)需求的數(shù)據(jù)、方法等較分散不集中。

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? Composition API (組合式API)的優(yōu)勢(shì)

我們可以更加優(yōu)雅的組織我們的代碼,函數(shù)。讓相關(guān)功能的代碼更加有序的組織在一起。

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js
尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? Fragment

  • 在Vue2中: 組件必須有一個(gè)根標(biāo)簽

  • 在Vue3中: 組件可以沒有根標(biāo)簽, 內(nèi)部會(huì)將多個(gè)標(biāo)簽包含在一個(gè)Fragment虛擬元素中

  • 好處: 減少標(biāo)簽層級(jí), 減小內(nèi)存占用

    尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? Teleport

  • 什么是Teleport?—— Teleport 是一種能夠?qū)⑽覀兊?strong>組件html結(jié)構(gòu)移動(dòng)到指定位置的技術(shù)。

    <!-- 移動(dòng)位置可以標(biāo)簽元素或標(biāo)簽選擇器 -->
    <teleport to="移動(dòng)位置">
    	<div v-if="isShow" class="mask">
    		<div class="dialog">
    			<h3>我是一個(gè)彈窗</h3>
    			<button @click="isShow = false">關(guān)閉彈窗</button>
    		</div>
    	</div>
    </teleport>
    
<template>
	<div>
		<button @click="isShow = true">點(diǎn)我彈個(gè)窗</button>
		<!-- 將html結(jié)構(gòu)移動(dòng)到body中 -->
		<teleport to="body">
			<div v-if="isShow" class="mask">
				<div class="dialog">
					<h3>我是一個(gè)彈窗</h3>
					<h4>一些內(nèi)容</h4>
					<h4>一些內(nèi)容</h4>
					<h4>一些內(nèi)容</h4>
					<button @click="isShow = false">關(guān)閉彈窗</button>
				</div>
			</div>
		</teleport>
	</div>
</template>

<script>
	import {ref} from 'vue'
	export default {
		name:'Dialog',
		setup(){
			let isShow = ref(false)
			return {isShow}
		}
	}
</script>

<style>
	.mask{
		position: absolute;
		top: 0;bottom: 0;left: 0;right: 0;
		background-color: rgba(0, 0, 0, 0.5);
	}
	.dialog{
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%,-50%);
		text-align: center;
		width: 300px;
		height: 300px;
		background-color: green;
	}
</style>

尚硅谷vue3筆記,Vue 學(xué)習(xí)筆記,vue.js,javascript,前端,vue3,js

?? Suspense

// 靜態(tài)引入只要組件不引入成功,當(dāng)前整個(gè)組件都不會(huì)進(jìn)行顯示
// import Child from './components/Child'//靜態(tài)引入
// 異步引入引入的組件等加載完成再進(jìn)行顯示,當(dāng)前組件可以不用等待引入成功即可先進(jìn)行顯示
import {defineAsyncComponent} from 'vue' 
const Child = defineAsyncComponent(()=>import('./components/Child')) //異步引入
  • 當(dāng)異步引入的組件引入完成,組件會(huì)突然顯示,造成用戶體驗(yàn)效果不佳

  • Suspense 標(biāo)簽可以在等待異步組件時(shí)渲染一些額外內(nèi)容,讓應(yīng)用有更好的用戶體驗(yàn)

  • 如果組件為異步引入且使用了Suspense,則組件的setup可以返回Promise實(shí)例對(duì)象,即當(dāng)Suspense和異步組件配合時(shí),setup可以是一個(gè)async函數(shù)。

  • 使用步驟:

    • 異步引入組件

      import {defineAsyncComponent} from 'vue'
      const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
      
    • 使用Suspense包裹組件,并配置好defaultfallback

      <template>
      	<div class="app">
      		<h3>我是App組件</h3>
      		<Suspense>
      		    <!-- 用于放置真正需要顯示的組件 -->
      			<template v-slot:default>
      				<Child/>
      			</template>
      			<!-- 用于放置等待異步組件時(shí)渲染的內(nèi)容 -->
      			<template v-slot:fallback>
      				<h3>加載中.....</h3>
      			</template>
      		</Suspense>
      	</div>
      </template>
      

?? Vue3全局API的轉(zhuǎn)移

  • Vue 2.x 有許多全局 API 和配置。

    • 例如:注冊(cè)全局組件、注冊(cè)全局指令等。

      //注冊(cè)全局組件
      Vue.component('MyButton', {
        data: () => ({
          count: 0
        }),
        template: '<button @click="count++">Clicked {{ count }} times.</button>'
      })
      
      //注冊(cè)全局指令
      Vue.directive('focus', {
        inserted: el => el.focus()
      }
      
  • Vue3.0中對(duì)這些API做出了調(diào)整:

    • 將全局的API,即:Vue.xxx調(diào)整到應(yīng)用實(shí)例(app)上

      2.x 全局 API(Vue 3.x 實(shí)例 API (app)
      Vue.config.xxxx app.config.xxxx
      Vue.config.productionTip 移除
      Vue.component app.component
      Vue.directive app.directive
      Vue.mixin app.mixin
      Vue.use app.use
      Vue.prototype app.config.globalProperties

?? Vue3其他改變

  • data選項(xiàng)應(yīng)始終被聲明為一個(gè)函數(shù)。

  • 過度類名的更改:

    • Vue2.x寫法

      .v-enter,
      .v-leave-to {
        opacity: 0;
      }
      .v-leave,
      .v-enter-to {
        opacity: 1;
      }
      
    • Vue3.x寫法

      .v-enter-from,
      .v-leave-to {
        opacity: 0;
      }
      
      .v-leave-from,
      .v-enter-to {
        opacity: 1;
      }
      
  • 移除keyCode作為 v-on 的修飾符,同時(shí)也不再支持config.keyCodes,不支持自定義按鍵別名。

  • 移除v-on.native修飾符

    • 父組件中綁定事件

      <my-component
        v-on:close="handleComponentEvent"
        v-on:click="handleNativeClickEvent"
      />
      
    • 子組件中聲明自定義事件

      <script>
        export default {
          emits: ['close'] // 子組件接收的事件為自定義事件,沒有接收的事件為原生事件
        }
      </script>
      
  • 移除過濾器(filter)

    過濾器雖然這看起來很方便,但它需要一個(gè)自定義語法,打破大括號(hào)內(nèi)表達(dá)式是 “只是 JavaScript” 的假設(shè),這不僅有學(xué)習(xí)成本,而且有實(shí)現(xiàn)成本!建議用方法調(diào)用或計(jì)算屬性去替換過濾器。

  • 文章來源地址http://www.zghlxwxcb.cn/news/detail-790916.html

到了這里,關(guān)于[Vue]Vue3學(xué)習(xí)筆記(尚硅谷)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包