最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue2?this直接獲取data和methods原理解析

 更新時間:2022年12月25日 15:20:22   作者:codeniu  
這篇文章主要為大家介紹了Vue2?this直接獲取data和methods原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

學習目標

本篇文章將通過閱讀 vue 的源碼,來回答 [為什么 Vue2 this 能夠直接獲取到 data 和 methods?]

倉庫地址:Github

  • 如何學習調試 vue2 源碼
  • data 中的數據為什么可以用 this 直接獲取到
  • methods 中的方法為什么可以用 this 直接獲取到
  • 學習源碼中優(yōu)秀代碼和思想,投入到自己的項目中

如何學習調試 vue2 源碼

通過去改源碼的方式來學習代碼,就是看到一段代碼,你可能不是太懂它具體的作用是什么,那就嘗試去改其中幾行代碼,猜測他們可能會造成那些影響,然后執(zhí)行代碼去驗證你的猜想。

使用 Github Workspace 克隆一份代碼,定位到源碼位置,如下圖:

安裝完依賴后執(zhí)行命令:

pnpm run dev

編譯器會實時的將代碼打包到 dist 目錄下,如圖:

我們引入打包后的代碼,就可以實時的調試源碼了,在example文件夾下新建一個html文件,并放入如下內容:

<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>Document</title>
 </head>
 <body>
   <div id="app">
     <h2 @click="changeMsg">hello {{msg}}</h2>
   </div>
   <script src="../dist/vue.js"></script>
   <script>
     const vm = new Vue({
       el: '#app',
       data: {
         msg: 'world'
       },
       methods: {
         changeMsg() {
           this.msg = 'codeniu'
         }
       }
     })
   </script>
 </body>
</html>

使用 vscode 拓展 Live Server,打開文件:

Github Workspace 會生成一個在線預覽的地址,所有的操作都是在瀏覽器中完成的,非常便捷。

使用瀏覽器的調試工具在 new Vue() 這行打上斷點,開始調試:

分析源碼

調試

我們在斷點調試的時候要帶著一下兩個問題,看看vue實例化的步驟是什么:

  • data 中的數據為什么可以用 this 直接獲取到
  • methods 中的方法為什么可以用 this 直接獲取到

也就是關注data 與 methods 兩個關鍵詞,果不其然,在 mergeOptions 方法中發(fā)現了我們想要尋找的關鍵字。

找到源碼中 mergeOptions 的位置:

export function initMixin(Vue: typeof Component) {
  Vue.prototype._init = function (options?: Record<string, any>) {
  ...
  
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options as any)
    } else {
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor as any),
        options || {},
        vm
      )
    }
    
  ...
  }
}

initState

這一步操作是將所有選項合并,為下一步 initState 做準備,在 initState 處打上斷點, F8 跳到這個斷點處,F10 進入到這個函數內部。

export function initState(vm: Component) {
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)

  // Composition API
  initSetup(vm)

  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else {
    const ob = observe((vm._data = {}))
    ob && ob.vmCount++
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

從代碼上看這個函數的功能是進行一些初始化操作

  • initMethods 初始化 methods
  • initData 初始化 data
  • initComputed 初始化 computed

在 initMethods 與 initData 處分別打斷點進入。

initMethods

function initMethods(vm: Component, methods: Object) {
  const props = vm.$options.props
  for (const key in methods) {
    if (__DEV__) {
      if (typeof methods[key] !== 'function') {
        warn(
          `Method "${key}" has type "${typeof methods[
            key
          ]}" in the component definition. ` +
            `Did you reference the function correctly?`,
          vm
        )
      }
      if (props && hasOwn(props, key)) {
        warn(`Method "${key}" has already been defined as a prop.`, vm)
      }
      if (key in vm && isReserved(key)) {
        warn(
          `Method "${key}" conflicts with an existing Vue instance method. ` +
            `Avoid defining component methods that start with _ or $.`
        )
      }
    }
    vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm)
  }
}

這個函數看起來像是用來初始化組件實例的方法的。它接收兩個參數:vm 和 methods,其中 vm 是組件實例,methods 是包含組件方法的對象。

首先,這個函數檢查組件是否定義了 props 屬性。如果定義了,它會警告用戶,如果方法名和已有的 prop 名稱相同,給出警告。

然后檢查函數名是否包含 $ 與 _ ,如果方法名包含這兩個符號,給出警告。

最后使用bind函數將this指向為vm,因此我們才得以使用this訪問到vm實例中的所有選項。

initData

function initData(vm: Component) {
  let data: any = vm.$options.data
  data = vm._data = isFunction(data) ? getData(data, vm) : data || {}
  if (!isPlainObject(data)) {
    data = {}
    __DEV__ &&
      warn(
        'data functions should return an object:\n' +
          'https://v2.vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
        vm
      )
  }
  // proxy data on instance
  const keys = Object.keys(data)
  const props = vm.$options.props
  const methods = vm.$options.methods
  let i = keys.length
  while (i--) {
    const key = keys[i]
    if (__DEV__) {
      if (methods && hasOwn(methods, key)) {
        warn(`Method "${key}" has already been defined as a data property.`, vm)
      }
    }
    if (props && hasOwn(props, key)) {
      __DEV__ &&
        warn(
          `The data property "${key}" is already declared as a prop. ` +
            `Use prop default value instead.`,
          vm
        )
    } else if (!isReserved(key)) {
      proxy(vm, `_data`, key)
    }
  }
  // observe data
  const ob = observe(data)
  ob && ob.vmCount++
}

InitData 函數初始化 Vue.js 組件的數據:

  • 如果 data 屬性是一個函數,則使用 Vue 實例作為參數調用它以獲取數據。
  • 檢查數據是否為普通對象。如果不是,則使用空對象作為數據,并給出警告。
  • 循環(huán)訪問數據對象,使用 Object.defineProperty 設置對象的get與set函數,為下一步響應式做鋪墊。
  • 使用觀察函數觀察數據。在數據發(fā)生改變時響應到頁面,或者在頁面發(fā)生變化時,響應到數據。

總結

通過本次課程的學習,加深了在瀏覽器中調試代碼的方法,并且通過閱讀源碼對vue2的響應式原理有了進一步的了解。

以上就是Vue2 this直接獲取data和methods原理解析的詳細內容,更多關于Vue2 this獲取data methods的資料請關注腳本之家其它相關文章!

相關文章

  • vue數據雙向綁定原理解析(get & set)

    vue數據雙向綁定原理解析(get & set)

    這篇文章主要為大家詳細解析了vue.js數據雙向綁定原理,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 詳解Vue3中Teleport的使用

    詳解Vue3中Teleport的使用

    門戶(Portal)的概念是Vue3的新功能之一,也就是將模板 HTML 移至 DOM 的不同部分的方法。Portal 是 React 中的常見功能,Vue2 的 portal-vue &nbsp;庫也提供了相似的功能。在 Vue3 中用 Teleport 對這個概念提供了原生支持。本文將介紹Teleport的相關用法
    2021-05-05
  • vue中輪訓器的使用

    vue中輪訓器的使用

    今天小編就為大家分享一篇關于vue中輪訓器的使用,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Vue基礎之偵聽器詳解

    Vue基礎之偵聽器詳解

    這篇文章主要為大家介紹了Vue基礎之偵聽器,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • vue+element下拉列表默認值問題

    vue+element下拉列表默認值問題

    這篇文章主要介紹了vue+element下拉列表默認值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 寫一個Vue loading 插件

    寫一個Vue loading 插件

    這篇文章主要介紹了如何寫一個Vue loading 插件,幫助大家更好的理解和學習vue 插件的相關知識,感興趣的朋友可以了解下
    2020-11-11
  • vue解決跨域問題的幾種常用方法(CORS)

    vue解決跨域問題的幾種常用方法(CORS)

    在Vue中解決跨域問題有多種方法,今天通過本文給大家介紹幾種比較常見的方法,對vue解決跨域問題感興趣的朋友跟隨小編一起看看吧
    2023-05-05
  • VueJS實現用戶管理系統(tǒng)

    VueJS實現用戶管理系統(tǒng)

    這篇文章主要為大家詳細介紹了VueJS實現用戶管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Vue?Router如何刷新當前頁面

    Vue?Router如何刷新當前頁面

    Vue項目,?在實際工作中,?有些時候需要在?加載完某些數據之后對當前頁面進行刷新,?這篇文章主要為大家介紹了三種常用方法,需要的可以參考一下
    2023-10-10
  • Vue渲染器如何對節(jié)點進行掛載和更新

    Vue渲染器如何對節(jié)點進行掛載和更新

    這篇文章主要介紹了Vue 的渲染器是如何對節(jié)點進行掛載和更新的,文中通過代碼示例給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-05-05

最新評論

平昌县| 昌都县| 武山县| 汝阳县| 唐河县| 沙河市| 牡丹江市| 湘乡市| 崇文区| 汉源县| 娱乐| 湘阴县| 屏东市| 确山县| 青冈县| 宾阳县| 吉木乃县| 桐乡市| 穆棱市| 津市市| 江西省| 凤山县| 临高县| 宜丰县| 吉水县| 祁门县| 大连市| 基隆市| 洱源县| 方城县| 阿荣旗| 永济市| 蒲江县| 海门市| 曲靖市| 丹棱县| 贵溪市| 环江| 金乡县| 桃园市| 清流县|