亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

VUE兩大核心之響應式與組件化開發實例分析

發布時間:2022-08-08 17:42:01 來源:億速云 閱讀:207 作者:iii 欄目:編程語言

這篇“VUE兩大核心之響應式與組件化開發實例分析”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“VUE兩大核心之響應式與組件化開發實例分析”文章吧。

VUE兩大核心之響應式與組件化開發實例分析

vue2.0 響應式

1. 對象的響應式

1.1 Object.defineProperty

Object.defineProperty(obj, prop, descriptor)方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,并返回此對象。

obj——要定義屬性的對象
prop——要定義或修改的屬性的名稱或Symbol
descriptor——對象,要定義或修改的屬性描述符

// descriptor{
  value: undefined, // 屬性的值
  get: undefined,   // 獲取屬性值時觸發的方法
  set: undefined,   // 設置屬性值時觸發的方法
  writable: false,  // 屬性值是否可修改,false不可改
  enumerable: false, // 屬性是否可以用for...in 和 Object.keys()枚舉
  configurable: false  // 該屬性是否可以用delete刪除,false不可刪除,為false時也不能再修改該參數}

通過賦值操作添加的普通屬性是可枚舉的,在枚舉對象屬性時會被枚舉到(for…in 或 Object.keys 方法),可以改變這些屬性的值,也可以刪除這些屬性。這個方法允許修改默認的額外選項(或配置)。
而默認情況下,使用 Object.defineProperty() 添加的屬性值是不可修改(immutable)的。
示例:

const a = {b : 1}console.log(Object.getOwnPropertyDescriptor(a, 'b'))// {value: 1, writable: true, enumerable: true, configurable: true}Object.defineProperty(a, 'c', {value: '2'})console.log(Object.getOwnPropertyDescriptor(a, 'c'))// {value: '2', writable: false, enumerable: false, configurable: false}a.c = 3console.log(a.c)// 2Object.defineProperty(a, 'c', {value: '4'})console.log(a.c)// error: Uncaught TypeError: Cannot redefine property: c
1.2 set和get
// 模擬vue響應式過程const app = document.getElementById('app')const data = {
	a: {
	  b: {
	    c: 1
	  }
	}}function render () {
  const virtualDom = `這是我的內容${data.a.b.c}`		
  app.innerHTML = virtualDom}function observer (obj) {
  let value  for (const key in obj) {  // 遞歸設置set和get
    value = obj[key]
    if (typeof value === 'object'){
      arguments.callee(value)
    } else {
      Object.defineProperty(obj, key, {
        get: function(){
          return value        },
        set: function(newValue){
          value = newValue          render()
        }
      })
    }
  }}render()observer(data)setTimeout(() => {
  data.a.b.c = 22}, 2000)setTimeout(() => {
  data.a.b.c = 88}, 5000)

上述方法實現了數據的響應,但存在很大的問題,我們觸發一次set,就需要整個頁面重新渲染,然而這個值可能只在某一個組件中使用了。
VUE兩大核心之響應式與組件化開發實例分析

所以將get和set優化:

Object.defineProperty(data, key, {
  get: function(){
    dep.depend() // 這里進行依賴收集
    return value  },
  set: function(newValue){
    value = newValue    // render()
    dep.notify()  // 這里進行virtualDom更新,通知需要更新的組件render
  }});

dep是Vue負責管理依賴的一個類

補充: Vue 無法檢測 property 的添加或移除。由于 Vue 會在初始化實例時對 property 執行 getter/setter 轉化,所以 property 必須在 data 對象上存在才能讓 Vue 將它轉換為響應式的

const vm = new Vue({
	data: {
		a: 1
	}})// vm.a是響應式的vm.b = 2// vm.b是非響應式的

2. 數組的響應式

vue 中處理數組的變化,直接通過下標觸發視圖的更改,只能使用push、shift等方法,而數組不能使用Object.defineProperty()
其實 Vue用裝飾者模式來重寫了數組這些方法

Object.create(proto,[propertiesObject]) 方法是創建一個新對象,使用現有的對象來提供新創建的對象的__proto__

proto——新創建對象的原型對象;
propertiesObject ——選填,類型是對象,如果該參數被指定且不為 undefined,該傳入對象的自有可枚舉屬性(即其自身定義的屬性,而不是其原型鏈上的枚舉屬性)將為新創建的對象添加指定的屬性值和對應的屬性描述符

const a = {}// 相當于const a = Object.create(Object.prototype)const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }};const me = Object.create(person);me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"me.isHuman = true; // inherited properties can be overwrittenme.printIntroduction();// expected output: "My name is Matthew. Am I human? true"
const o = Object.create(Object.prototype, {
  foo: { // foo會成為所創建對象的數據屬性
    writable:true,
    configurable:true,
    value: "hello"
  },
  bar: { // bar會成為所創建對象的訪問器屬性
    configurable: false,
    get: function() { return 10 },
    set: function(value) {
      console.log("Setting `o.bar` to", value);
    }
  }});console.log(o) // {foo: 'hello'}

vue中的裝飾者模式

const arraypro = Array.prototype    // 獲取Array的原型const arrob = Object.create(arraypro) // 用Array的原型創建一個新對象,arrob.__proto__ === arraypro,免得污染原生Array;const arr=['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']   // 需要重寫的方法arr.forEach(function(method) {
  arrob[method] = function () {
    arraypro[method].apply(this, arguments) // 重寫時先調用原生方法
    dep.notify() // 并且同時更新
  }})// 對于用戶定義的數組,手動將數組的__proto__指向我們修改過的原型const a = [1, 2, 3]a.__proto__ = arrob

上面對于新對象arrob的方法,我們是直接賦值的,這樣會有一個問題,就是用戶可能會不小心改掉我們的對象,所以我們可以用到我們前面講到的Object.defineProperty來規避這個問題,我們創建一個公用方法def專門來設置不能修改值的屬性

function def (obj, key, value) {
  Object.defineProperty(obj, key, {
    // 這里我們沒有指定writeable,默認為false,即不可修改
    enumerable: true,
    configurable: true,
    value: value,
  });}// 數組方法重寫改為arr.forEach(function(method){
  def(arrob, method, function () {
    arraypro[method].apply(this, arguments)  // 重寫時先調用原生方法
    dep.notify()// 并且同時更新
  })})

3. 補充:對象的數據屬性和訪問器屬性

數據屬性: 它包含的是一個數據值的位置,在這可以對數據值進行讀寫

數據屬性的四個描述符:


含義
configurable表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或能否把屬性修改為訪問器屬性,默認為true
enumerable表示能否通過for-in循環返回屬性,默認為true
writable表示能否修改屬性的值,默認為true
value包含該屬性的數據值,默認為undefined

訪問器屬性: 這個屬性不包含數據值,包含的是一對get和set方法,在讀寫訪問器屬性時,就是通過這兩個方法來進行操作處理的。

訪問器屬性的四個描述符:


含義
configurable表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或能否把屬性修改為訪問器屬性,默認為false
enumerable表示能否通過for-in循環返回屬性,默認為false
get在讀取屬性時調用的函數,默認值為undefined
set在寫入屬性時調用的函數,默認值為undefined

vue3.0數據響應

vue3.0的響應式和vue2.0響應式原理類似,都是在get中收集依賴,在set中通知依賴更新視圖,但vue3.0使用了es6新增的proxy來代替Object.defineProperty()

proxy相對于Object.defineProperty()的好處:

  1. Object.defineProperty需要指定對象和屬性,對于多層嵌套的對象需要遞歸監聽,Proxy可以直接監聽整個對象,不需要遞歸;

  2. Object.defineProperty的get方法沒有傳入參數,如果我們需要返回原值,需要在外部緩存一遍之前的值,Proxy的get方法會傳入對象和屬性,可以直接在函數內部操作,不需要外部變量;

  3. set方法也有類似的問題,Object.defineProperty的set方法傳入參數只有newValue,也需要手動將newValue賦給外部變量,Proxy的set也會傳入對象和屬性,可以直接在函數內部操作;

  4. new Proxy()會返回一個新對象,不會污染源原對象

  5. Proxy可以監聽數組,不用單獨處理數組

proxy劣勢: vue3.0將放棄對低版本瀏覽器的兼容(兼容版本ie11以上)

這樣上邊的observe方法就可以優化成:

function observer () {
  var self = this;
  data = new Proxy(data, {
    get: function(target, key){
      dep.depend() // 這里進行依賴收集
      return target[key]
    },
    set: function(target, key, newValue){
      target[key] = newValue;
      // render()
	  dep.notify()  // 這里進行virtualDom更新,通知需要更新的組件render
    }
  });}

模塊化(組件化)開發

按照功能(或按照復用性)把一個頁面拆成各個板塊(模塊),每一個模塊都是一個單獨的文件(單獨的組件),最后把各個模塊(組件)拼在一起即可!!

目的 :方便團隊協作開發 實現復用

組件分類

功能型組件「UI組件庫中提供的一般都是功能型組件:element/iview/antdv/vant/cube..」

  • + 一般UI組件庫提供的功能組件就夠用了

  • + 偶爾UI組件庫中不存在的,才需要自己封裝「難點」

  • + 我們經常會把功能型組件進行二次封裝(結合自己項目的業務邏輯)「特殊亮點」

業務型組件

  • + 通用業務型組件「好多頁面都需要用到的,我們把其封裝成為公共的組件」

  • + 普通組件

以后開發項目,拿到設計稿的第一件事情:劃分組件「按照功能版塊劃分、本著復用性原則,拆的越細越好(這樣才能更好的實現復用)」

組件的創建及使用

創建一個 Xxx.vue 就是創建一個vue組件{局部組件、私有組件},組件中包含:結構、樣式、功能

結構:基于template構建        

+ 只能有一個根元素節點(vue2)
     + vue的視圖就是基于template語法構建的(各種指令&小胡子...),最后vue會把其編譯為真實的DOM插入到頁面指定的容器中
      首先基于 vue-template-compiler 插件把template語法編譯為虛擬DOM「vnode」
      其次把本次編譯出來的vnode和上一次的進行對比,計算出差異化的部分「DOM-DIFF」
      最后把差異化的部分變為真實的DOM放在頁面中渲染
 

樣式:基于style來處理

  • + lang="less" 指定使用的CSS預編譯語言「需要提前安裝對應的loader」

  • + scoped 指定當前編寫的樣式是私有的,只對當前組件中的結構生效,后期組件合并在一起,保證樣式之間不沖突

功能:通過script處理

   + 導出的這個對象是VueComponent類的實例(也是Vue的實例):對象 -> VueComponent.prototype -> Vue.prototype
    + 在對象中基于各種 options api 「例如:data、methods、computed、watch、filters、生命周期函數...」實現當前組件的功能
       + 在組件中的data不再是一個對象,而是一個“閉包”
       + 各個組件最后會合并在一起渲染,為了保證組件中指定的響應式數據是“私有的”,組件之間數據即使名字相同,也不會相互污染...所以需要基于閉包來管理

注意;App.vue頁面入口相當于首頁,寫好的組件都導入到這個里面

<template>
  <p class="box">
    {{ msg }}
  </p>
</template>

<script>
export default {
  name: "Test",
  data() {
    return {
      //編寫響應式數據
      msg: "你好,世界",
    };
  },
};
</script>

<style lang="less" scoped>
.box {
  font-size: 20px;
  color: red;
}
</style>

私有組件(使用的時候首先進行導入,然后注冊,這樣視圖中就可以調用組件進行渲染了)

  • 需要使用私有組件的時候,需要先導入import Test from "./Test.vue";

  • 然后注冊:這樣就可以調用組件進行渲染了

<template>
  <p id="app">
      //3.使用組件:可以使用單閉合或雙閉合
      
    <Test></Test>
      <Test>
  </p>
</template>


<script>
//1、導入組件
import Test from "./Test.vue";
export default {
  name: "App",
  components:{
    //2、注冊使用的組件
    Test,
  }
};
</script>

創建全局組件

1. 創建一個局部組件

<template>
  <p>{{ msg }}</p>
</template>

<script>
export default {
  name: "Vote",
  data() {
    return {
      msg: "今夜陽光明媚",
    };
  },
};
</script>

@2 在main.js入口中,導入局部組件Vote,把其注冊為全局組件

import Vote from './Vote.vue';
Vue.component('Vote', Vote)

@3 這樣在任何組件(視圖中),無需基于components注冊,直接可以在視圖中調用

<template> <Vote></Vote></template>

插槽

調用組件的方式

調用組件的時候,可以使用:

雙閉合 <Test></Test>

雙閉合的方式可以使用插槽slot

@1 在封裝的組件中,基于 <slot> 標簽預留位置
 @2 調用組件的時候,基于雙閉合的方式,把要插入到插槽中的內容寫在雙閉合之間

單閉合 <Test/>

組件的名字可以在“kebab-case”和“CamelCase”來切換:官方建議組件名字基于CamelCase命名,渲染的時候基于kebab-case模式使用!

VUE兩大核心之響應式與組件化開發實例分析

插槽的作用

  • 讓組件具備更高的復用性(或擴展性)

  • 我們封裝好一個組件,把核心部分都實現了,但是我們期望用戶調用組件的時候,可以自定義一些內容,防止在已經封裝好的組件內部:

插槽分為了默認插槽、具名插槽、作用域插槽

默認插槽:只需要在調用組件<Test><Test>內插入我們想要的插入的html代碼,會默認放到組件源代碼的<slot name="default"></slot>插槽中

組件內部
slot預留位置  默認name:default
<slot></slot>
調用組件的時候
//只有一個的時候可以不用template包裹
<Test>
<p class="top">頭部導航</p>
</Test>

具名插槽:組件中預設好多插槽位置,為了后期可以區分插入到哪,我們把插槽設置名字

  • 在調用組件<Test><Test>內自己寫的代碼,我們用template包裹代碼,并把v-slot:xxx寫在template上,這時就會將xxx里面的代碼,包裹到組件源代碼的<slot name=”xxx“></slot>的標簽中

  • ==組件內部:== <slot name="xxx"> 默認名字是default

  • ==調用組件:==需要把v-slot寫在template上

  組件內部
      <slot name="xxx">
      默認名字是default
    調用組件:需要把v-slot寫在template上
      <template v-slot:xxx>
         ...
      </template>
      <template>
         ...
      </template>
    v-slot可以簡寫為#:#xxx

VUE兩大核心之響應式與組件化開發實例分析

  作用域插槽:把組件內部定義的數據,拿到調用組件時候的視圖中使用

組件中data內的數據只能在本模塊中使用,如果想讓調用組件的插槽也能獲取數據,就需要對組件內對的slot做bind綁定數據,調用組件的template標簽做#top="AAA",獲取數

   ==組件內部==:
 <slot name="top" :list="list" :msg="msg"></slot>
  • 把組件中的list賦值給list屬性,把msg賦值給msg屬性,插槽中提供了兩個作用域屬性:list/msg

==調用組件==:
 <template #top="AAA"></template>
  • 定義一個叫做AAA的變量,來接收插槽中綁定的所有數據(對象格式)

  • 如果插槽名是default則使用v-slot="AAA":default="AAA"獲取數據

 組件內部
      <slot name="top" :list="list" :msg="msg"></slot>
      把組件中的list賦值給list屬性,把msg賦值給msg屬性,插槽中提供了兩個作用域屬性:list/msg

    調用組件
      <template #top="AAA"></template>
      定義一個叫做AAA的變量,來接收插槽中綁定的數據
      AAA={
        list:[...],
        msg:...
      }

VUE兩大核心之響應式與組件化開發實例分析

組件傳參

調用組件的時候

每創建一個組件其實相當于創建一個自定義類,而調用這個組件就是創建VueCommponent(或者Vue)類的實例

  • 實例(this)->VueComponent.prototype->Vue.prototype->Object.prototype

  • 當前實例可以訪問Vue.prototype上的一些公共屬性和方法

組件中的script中存在的狀態值和屬性值?

  • ==狀態值==:data中的數據值稱為狀態值

  • ==屬性值==:props中的數據值稱為屬性值

  • 狀態值和屬性值是直接掛載到_vode對象的私有屬性中(所以狀態值和屬性值名字不能重復)

  • 我們在視圖template標簽中調用狀態值和屬性值,不需要加this,直接調用狀態名或屬性名

  • 我們在功能script標簽中調用狀態值和屬性值,需要加this調用

  • ==computed(計算屬性)==:也是掛載實例上的,所以他們三個都不能重名

vue中的單向數據流

父子組件傳遞數據時,只能由父組件流向子組件,不能由子組件流向父組件。這樣會防止從子組件意外改變父級組件的狀態,從而導致你的應用的數據流向難以理解。

組件傳參的分類7種:

  • 父組件向子組件傳參:props

  • 子組件向父組件傳參:發布訂閱(@xxx給子組件標簽自定義事件、$emit)

  • 組件相互傳參(兄弟):發布訂閱(on、emit)【2和3傳參是一種】

  • 祖先向后代傳參(provide[提供],inject[接收])

  • vue實例屬性傳參(parent、children[n]、root、refs)

  • vuex

  • localStorage sessionStorage

1.父組件向子組件傳參

父組件向子組件傳參:props

  • 我們傳給組件的值,默認是==字符串類型==的,比如msg

  • 如果想傳==數字類型==的,則需要調用v-bind或冒號的形式傳值

  • 我們每調用一次coma,都會生成一個獨立的VueComponent的實例

第一步:父組件在組件調用標簽中自定義屬性

//如果想把data中的狀態值傳遞過去需要v-bind綁定
<coma msg="hello" :num="num"></coma>

注意 如果想把data中的狀態值傳遞過去需要v-bind綁定

第二步:子組件通過props接收(數組,對象)

  • props中的屬性是只讀的,子組件不能修改這些值,否則會報錯

  • 解決只讀問題:用自定義變量接收傳遞過來的值,頁面使用自定義變量

  • props可以是對象或數組類型,對象可以對數據做校驗,數組不能

    // props的值是只讀的 能改,會報錯
    <input type="text" v-model="num" />
    //數組格式
    props:["msg","num"]
    //對象格式
     props: {
    msg: {
      //傳參類型必須是字符串
      type: String,
      //必須傳參
      required: true,
    },
    num: {
      type: Number,
      //如果不傳參默認是102
      default: 102,
    },
  },
    //----------------------------------------
    //用自定義變量numa接收num,然后頁面使用numa(解決只讀問題)
    <h2>我是子組件 coma------{{ msg }}----{{ numa }}</h2>
    <input type="text" v-model="numa" />
    props: ["msg", "num"],
      data() {
        return {
        numa: this.num,
       };
     },

2.子組件向父組件傳參

子組件向父組件傳參,基于==發布訂閱(@xxx給子組件標簽自定義事件、$emit)==

第一步:父組件在調用子組件的標簽上需要自定義一個事件,這個事件及綁定的方法就會添加到子組件的事件池中:底層實質上是調用了this.$on("myEvent",fn)

<Coma @myEvent="getData"></Coma>
 methods: {
    getData() {},
  },

第二步:子組件用this.$emit()接受(this.$emit(myEvent,參數1,參數2)), 參數可以是子組件的,順便傳給父組件,實現子組件向父組件傳值

  <button @click="goParentData">向父組件發送數據</button>
 data() {
    return {
      flag: "你很美",
      n: 101,
    };
  methods: {
    goParentData() {
      //執行父組件自定義的事件
      this.$emit("myEvent", this.flag, this.n);
    },
  },

第三步:父組件使用傳遞過來的數據

 data() {
    return {
      n: 0,
      flag: "",
    };
  },
  methods: {
    getData(...parans) {
      console.log(parans);
      //傳遞過來的是數組
      this.n = parans[0];
      this.flag = parans[1];
    },
  },

3.組件之間相互傳參    原生事件法  (發布訂閱)

b--->c發送數據

  • c向事件池中添加方法(自定義方法):$on

  • b執行方法把參數傳過去:$emit

第一步:全局的main.js中創建一個全局的EventBus,掛載 vue的原型上  this.$bus

  • 作用:將EventBus看作定義在公有屬性上的事件池(事件公交),之后基于這個$bus.$on()綁定的事件函數,在哪個vue實例上都可以基于$bus.$empty()執行,還可以傳值

//創建一個全局的 Eventbus
let Eventbus=new Vue();
//掛載 vue的原型上  后期基于this.$bus
Vue.prototype.$bus=Eventbus;

第二步:comc向事件池中綁定事件:this.$bus.$on("事件名",函數)

  created() {
    //向事件池中添加方法
    this.$bus.$on("myEvent", () => {});
  },

第三步:comb從事件池中獲取事件函數并執行:this.$bus.$emit("事件名",想傳的參數)

    <button @click="send">發送數據給comc</button>
      data() {
        return {
          msg: "我是comb",
    };
    methods: {
    send() {
      //執行事件池中的方法,并且傳參
      this.$bus.$emit("myEvent", this.msg);
    },

第四步 comc使用傳遞過來的數據

   <h2>組件 comc----{{ msg }}</h2>
     data() {
        return {
          msg: "",
      };
  //創建之后的鉤子函數向事件池中添加方法
 created() {
    //向事件池中添加方法
    this.$bus.$on("myEvent", (value) => {
      console.log(value);
      this.msg = value;
    });
  },

4.祖先和后代相互傳參

  • 第一步:祖先要使用provide方法傳參,不是寫在methods里面,與methods同級

 data() {
    return {
      title: "我是about祖先",
    };
  },
  provide() {
    return {
      title: this.title,
    };
  },

第二步:后代使用inject屬性接受祖先中的參數,inject是data中的數據,是數組類型

inject: ["title"],因為inject是數組類型,所以它符合如果數據項不是對象類型,則不做劫持,如果數據項是對象,則這個對象中的屬性會做劫持。

  data() {
    return {
      title: "我是about祖先",
    };
  },
//祖先 傳遞的title是非響應式
  provide() {
    return {
      title: this.title,
    };
  },
//------------------------------
  data() {
    return {
      //obj非響應式
      obj: {
        //title是響應式
        title: "我是about祖先",
      },
    };
  },
  //祖先 傳遞的參數失去響應式,但里面的值會是響應式
  provide() {
    return {
      obj: this.obj,
    };
  },

vue實例屬性傳參

vue的實例中存在一些屬性能夠獲取不同關系的元素,獲取之后就可以基于這個元素獲取其中的數據或方法了:

  • $parent 獲取父元素的數據/方法  獲取父元素的整個vm實例

  • 子組件可以在任何生命周期函數中獲取父元素【父子組件的生命周期

  created() {
    console.log(this.$parent.title);
  },
  • $children  獲取子元素的數據/方法(mounted鉤子函數,要有下標)

  • this.$children[n]:獲取第n個子元素的vm實例

  • 父組件只能在mounted生命周期函數里或之后獲取子元素【父子組件的生命周期

  mounted() {
    console.log(this.$children[0].msg);
  },
  • $root獲取根組件的數據/方法

  • this.$root:獲取根元素的vm實例(main.js中new 的Vue實例)

et mv = new Vue({
  router,
  data() {
    return {
      rootmsg: "我是草根"
    }
  },
  render: h => h(App)
}).$mount('#app')
---------------------
  mounted() {
    console.log(this.$root.rootmsg);
  },
  • this.$refs:this的子元素中需要定義ref屬性:比如ref="xxx"

  • ==如果ref定義在DOM標簽中==:this.$refs.xxx獲取的是DOM對象

  • ==如果ref定義在子組件標簽中==:this.$refs.xxx獲取的是子組件的vm實例

  //獲取的是dom元素
  <p ref="one">11111</p>
   mounted() {
    console.log(this.$refs.one);
  },
-----------------------------------
獲取的是組件
  <comb ref="b"></comb>
  mounted() {
    console.log(this.$refs.b);
  },
//如果不是組件獲取的就是dom元素,如果是組件,獲取的就是組件的實例

父子組件的生命周期

重點:父組件更新默認不會觸發子組件更新,但是**==如果子組件中綁定調用了父組件的數據aaa,父組件的aaa數據更新觸發重新渲染時,使用aaa數據{{$parent.aaa}}的子組件也會觸發更新==**

一、父子組件生命周期執行過程

  • 父->beforeCreated

  • 父->created

  • 父->beforeMount

  • 子->beforeCreate

  • 子->created

  • 子->beforeMount

  • 子->mounted

  • 父->mounted

二、子組件更新過程:

  • 父->berforeUpdate

  • 子->berforeUpdate

  • 子->updated

  • 父->updated

三、父組件更新過程:

  • 父->berforeUpdate

  • 父->updated

四、父組件銷毀過程:

  • 父->beforeDestory

  • beforeDestory

  • destoryed

  • 父->destoryed

VUE兩大核心之響應式與組件化開發實例分析

擴展------------------------

父組件綁定在子組件標簽中的事件,是無法觸發的,如何解決?

@xxx.native: 監聽組件根元素的原生事件。

  • 例子<my-component @click.native="onClick"></my-component>

  • 原理:在父組件中給子組件綁定一個==原生(click/mouseover...)==的事件,就將子組件變成了普通的HTML標簽,不加'. native'父組件綁定給子組件標簽的事件是無法觸發的

虛擬DOM

虛擬DOM對象:_vnode,作用:

第一步:vue內部自己定義的一套對象,基于自己規定的鍵值對,來描述視圖中每一個節點的特征:

  • tag標簽名

  • text文本節點,存儲文本內容

  • children:子節點

  • data:屬性

  • 第二步:基于vue-template-compiler去渲染解析 template 視圖,最后構建出上述的虛擬DOM對象

  • 第三步:組件重新渲染,又重新生成一個 _vnode

  • 第四步:對比兩次的 _vnode. 獲取差異的部分

  • 第五步:把差異的部分渲染為真實的DOM

組件庫

  • element-ui:餓了么

  • antdv :螞蟻金服

  • iview :京東

  • Element - The world's most popular Vue UI framework

  • ==vue2.xx==:elemnetui

  • ==vue3.xx==:element plus

如何在項目中使用功能性組件?

==第一步==:安裝element-ui:$npm i element-ui -s

==第二步==:導入:

完整導入:整個組件庫都導入進來,想用什么直接用Vue.use(xxx)即可

缺點:如果我們只用幾個組件,則無用的導入組件會造成項目打包體積變大[不好],所以項目中推薦使用按需導入

按需導入

1、需要安裝依賴$ npm install babel-plugin-component

樣式私有化

在Vue中我們基于scoped設置樣式私有化之后:

  • 會給組件創建一個唯一的ID(例如:data-v-5f109989)

  • 在組件視圖中,我們編寫所有元素(包含元素調用的UI組件),都設置了這個ID屬性;但是我們調用的組件內部的元素,并沒有設置這個屬性!!

   <p data-v-5f1969a9 class="task-box">
      <button data-v-5f1969a9 type="button" class="el-button el-button--primary">
        <span>新增任務</span>
      </button>
    </p>

而我們編寫的樣式,最后會自動加上屬性選擇器:

 .task-box {
      box-sizing: border-box;
      ...
    }
---------編譯后成為:---------
    .task-box[data-v-5f1969a9]{
      box-sizing: border-box;
    }
  • ==組件樣式私有化的原理==:設置唯一的屬性(組件ID)、組件內部給所有樣式后面都加上該屬性選擇器

  • ==問題==:組件內部的元素沒有設置這個屬性,但是我們編寫的樣式是基于這個屬性選擇器在css設置的選擇器,

  • ==解決==:在組件內部的元素選擇器前加/deep/:

    /deep/.el-textarea__inner,
    	/deep/.el-input__inner{
   		 border-radius: 0;
 		 }

API

  • 在真實項目中,我們會把數據請求和axios的二次封裝,都會放到src/api路徑下進行管理

//main.js
	import api from '@/api/index';
	// 把存儲接口請求的api對象掛載搭配Vue的原型上:
    后續在各個組件基于this.$api.xxx()就可以發送請求了,無需在每個組件中再單獨導入這個api對象。
	Vue.prototype.$api=api;

以上就是關于“VUE兩大核心之響應式與組件化開發實例分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

宜君县| 新邵县| 乐平市| 通州市| 大关县| 鄄城县| 宜章县| 和林格尔县| 商南县| 龙岩市| 喀什市| 诸城市| 侯马市| 仁怀市| 平遥县| 广饶县| 集安市| 德安县| 泾源县| 樟树市| 黄冈市| 玉田县| 泽普县| 刚察县| 桓台县| 玉环县| 嵊泗县| 东宁县| 张家界市| 蒙城县| 闽清县| 大丰市| 丰城市| 塔城市| 噶尔县| 通城县| 黔南| 荆门市| 拜城县| 无棣县| 赤水市|