使用Vue3.0,我收穫了哪些知識點(一)

前端發展百花放,一技未熟百技出。
茫然不知何下手,關注小編勝百書。

近期工做感受很忙,都沒有多少時間去寫文章,今天這篇文章主要是將本身前期學習Vue3.0時候整理的一些筆記內容進行了彙總,經過對本文的閱讀,你將能夠本身完成Vue3.0環境搭建,同時還會對Vue3.0的一些新的特性進行了解,方便本身進行Vue3.0的學習。本文首發於公衆號【前端有的玩】,關注===會了,還有更多面試題等你來刷哦。javascript

本文全部的示例均使用 ant design vue2.0實現,關於 ant design vue2.0請參考 https://2x.antdv.com/docs/vue/introduce-cn/

初始化環境

在前面的文章中,咱們經過vite搭建了一個開發環境,可是實際上如今vite並無完善到支撐一個完整項目的地步,因此本文咱們依然選擇使用vue-cli腳手架進行環境搭建。css

小編使用的 vue-cli版本是 4.5.4,若是您的版本比較舊能夠經過 npm update @vue/cli來升級腳手架版本,若是沒有安裝能夠經過 npm install @vue/cli -g進行安裝

使用腳手架新建項目

  1. 在工做空間打開終端(cmd),而後經過vue create my-vue3-test 命令初始化項目
  2. 在第一步先選擇Manually select features,進行手動選擇功能
  3. 而後經過Space和上下鍵依次選擇html

    Choose Vue version
    Babel
    TypeScript
    Router
    Vuex
    CSS Pre-processors
    Linter/Formatter

    而後回車前端

    1. 而後提示選擇Vue版本,選擇3.x(Preview)
    2. Use class-style component syntax?選擇n,即輸入n而後回車
    3. 而後提示Use Babel alongside TypeScript,輸入y`
    4. Use history mode for router輸入n
    5. 而後css預處理器選擇Less
    6. eslint選擇ESLint + Prettier
    7. 而後是Lint on saveIn dedicater config files
    8. 最後一路回車便可完成項目搭建

啓動項目

新建完項目以後,進入到項目中cd my-vue3-test,而後執行 yarn serve便可啓動項目vue

啓動以後便可經過訪問 http://localhost:8080/ 訪問項目java

配置ant design vue

在當前Vue3.0正式版還未發佈之際,國內比較出名的前端UI庫中率先將Vue3.0集成到自家的UI庫中的,PC端主要是ant-design-vue,移動端主要是vant, 本文全部示例代碼都會基於ant-design-vue來進行,首先咱們先安裝ant-design-vuereact

  1. 安裝依賴es6

    yarn add ant-design-vue@2.0.0-beta.6
    yarn add babel-plugin-import -D
  2. 配置ant-design-vue按需加載面試

    進入項目根目錄,而後打開babel.config.js文件,將裏面的內容修改成vue-cli

    module.exports = {
      presets: ["@vue/cli-plugin-babel/preset"],
      plugins: [
        // 按需加載
        [
          "import",
          // style 爲 true 加載 less文件
          { libraryName: "ant-design-vue", libraryDirectory: "es", style: "css" }
        ]
      ]
    };
  3. 嘗試使用vue3 + antdv來添加一個小頁面, 咱們直接將views/Home.vue文件裏面的代碼替換爲
<template>
  <a-form layout="inline" :model="state.form">
    <a-form-item>
      <a-input v-model:value="state.form.user" placeholder="Username">
        <template v-slot:prefix
          ><UserOutlined style="color:rgba(0,0,0,.25)"
        /></template>
      </a-input>
    </a-form-item>
    <a-form-item>
      <a-input
        v-model:value="state.form.password"
        type="password"
        placeholder="Password"
      >
        <template v-slot:prefix
          ><LockOutlined style="color:rgba(0,0,0,.25)"
        /></template>
      </a-input>
    </a-form-item>
    <a-form-item>
      <a-button
        type="primary"
        :disabled="state.form.user === '' || state.form.password === ''"
        @click="handleSubmit"
      >
        登陸
      </a-button>
    </a-form-item>
  </a-form>
</template>
<script>
import { UserOutlined, LockOutlined } from "@ant-design/icons-vue";
import { Form, Input, Button } from "ant-design-vue";
import { reactive } from "vue";

export default {
  components: {
    UserOutlined,
    LockOutlined,
    [Form.name]: Form,
    [Form.Item.name]: Form.Item,
    [Input.name]: Input,
    [Button.name]: Button
  },
  setup() {
    const state = reactive({
      form: {
        user: "",
        password: ""
      }
    });

    function handleSubmit() {
      console.log(state.form);
    }

    return {
      state,
      handleSubmit
    };
  }
};
</script>

而後重啓一下項目,就能夠發現已經能夠正常使用ant-design-vue了。

Vue3.0新體驗之setup

對於Vue3.0的問世,最吸引你們注意力的即是Vue3.0Composition API,對於Componsition API,能夠說是兩極分化特別嚴重,一部分人特別喜歡這個新的設計與開發方式,而另外一部分人則感受使用Composition API很容易寫出來意大利麪式的代碼(可能這部分人不知道蘭州拉麪吧)。到底Composition API是好是壞,小編不作評論,反正我只是一個搬磚的。而本小節介紹的setup就是Composition API的入口。

setup介紹

setupVue3.0提供的一個新的屬性,能夠在setup中使用Composition API,在上面的示例代碼中咱們已經使用到了setup,在上文代碼中咱們在setup中經過reactive初始化了一個響應式數據,而後經過return返回了一個對象,對象中包含了聲明的響應式數據和一個方法,而這些數據就能夠直接使用到了template中了,就像上文代碼中的那樣。關於reactive,我將會在下一小節爲你帶來講明。

setup 的參數說明

setup函數有兩個參數,分別是propscontext

  1. props

    propssetup函數的第一個參數,是組件外部傳入進來的屬性,與vue2.0props基本是一致的,好比下面代碼

    export default {
      props: {
        value: {
          type: String,
          default: ""
        }
      },
      setup(props) {
        console.log(props.value)
      }
    }

    可是須要注意的是,在setup中,props是不能使用解構的,即不能將上面的代碼改寫成

    setup({value}) {
        console.log(value)
     }

    雖然template中使用的是setup返回的對象,可是對於props,咱們不須要在setup中返回,而是直接能夠在template使用,好比上面的value,能夠直接在template寫成

    <custom-component :value="value"></custom-component>
  2. context

    contextsetup函數的第二個參數,context是一個對象,裏面包含了三個屬性,分別是

    • attrs

      attrsVue2.0this.$attrs是同樣的,即外部傳入的未在props中定義的屬性。對於attrsprops同樣,咱們不能對attrs使用es6的解構,必須使用attrs.name的寫法

    • slots

      slots對應的是組件的插槽,與Vue2.0this.$slots是對應的,與propsattrs同樣,slots也是不能解構的。

    • emit

      emit對應的是Vue2.0this.$emit, 即對外暴露事件。

setup 返回值

setup函數通常會返回一個對象,這個對象裏面包含了組件模板裏面要使用到的data與一些函數或者事件,可是setup也能夠返回一個函數,這個函數對應的就是Vue2.0render函數,能夠在這個函數裏面使用JSX,對於Vue3.0中使用JSX,小編將在後面的系列文章中爲您帶來更多說明。

最後須要注意的是,不要在 setup中使用 this,在 setup中的 this和你真正要用到的 this是不一樣的,經過 propscontext基本是能夠知足咱們的開發需求的。

瞭解Composition API,先從reactiveref開始

在使用Vue2.0的時候,咱們通常聲明組件的屬性都會像下面的代碼同樣

export default {
  data() {
    return {
      name: '子君',
      sex: '男'
    }
  }
}

而後就能夠在須要用到的地方好比computed,watch,methods,template等地方使用,可是這樣存在一個比較明顯的問題,即我聲明data的地方與使用data的地方在代碼結構中可能相距很遠,有一種君住長江頭,我住長江尾,日日思君不見君,共飲一江水的感受。而Composition API的誕生的一個很重要的緣由就是解決這個問題。在尤大大在關於Composition API的動機中是這樣描述解決的問題的:

  1. 隨着功能的增加,複雜組件的代碼變得愈來愈難以閱讀和理解。這種狀況在開發人員閱讀他人編寫的代碼時尤其常見。根本緣由是 Vue 現有的 API 迫使咱們經過選項組織代碼,可是有的時候經過邏輯關係組織代碼更有意義。
  2. 目前缺乏一種簡潔且低成本的機制來提取和重用多個組件之間的邏輯。

如今咱們先了解一下Compositon API中的reactiveref

介紹reactive

Vue2.6中, 出現了一個新的api,Vue.observer,經過這個api能夠建立一個響應式的對象,而reactive就和Vue.ovserver的功能基本是一致的。首先咱們先來看一個例子

<template>
  <!--在模板中經過state.name使用setup中返回的數據-->
  <div>{{ state.name }}</div>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
    // 經過reactive聲明一個可響應式的對象
    const state = reactive({
      name: "子君"
    });
    // 5秒後將子君修改成 前端有的玩
    setTimeout(() => {
      state.name = "前端有的玩";
    }, 1000 * 5);
    // 將state添加到一個對象中而後返回
    return {
      state
    };
  }
};
</script>

上面的例子就是reactive的一個基本的用法,咱們經過上面的代碼能夠看到reactiveVue.observer聲明可響應式對象的方法是很像的,可是他們之間仍是存在一些差異的。咱們在使用vue2.0的時候,最多見的一個問題就是常常會遇到一些數據明明修改了值,可是界面卻並無刷新,這時候就須要使用Vue.set來解決,這個問題是由於Vue2.0使用的Object.defineProperty沒法監聽到某些場景好比新增屬性,可是到了Vue3.0中經過Proxy將這個問題解決了,因此咱們能夠直接在reactive聲明的對象上面添加新的屬性,一塊兒看看下面的例子

<template>
  <div>
    <div>姓名:{{ state.name }}</div>
    <div>公衆號:{{ state.gzh }}</div>
  </div>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
    const state = reactive({
      name: "子君"
    });
    // 5秒後新增屬性gzh 前端有的玩
    setTimeout(() => {
      state.gzh = "前端有的玩";
    }, 1000 * 5);
    return {
      state
    };
  }
};
</script>

上面的例子雖然在state中並無聲明gzh屬性,可是在5s後咱們能夠直接給state添加gzh屬性,這時候並不須要使用Vue.set來解決新增屬性沒法響應的問題。

在上面的代碼中,reactive經過傳入一個對象而後返回了一個state,須要注意的是state與傳入的對象是不用的,reactive對原始的對象並無進行修改,而是返回了一個全新的對象,返回的對象是Proxy的實例。須要注意的是在項目中儘可能去使用reactive返回的響應式對象,而不是原始對象。

const obj = {}
const state = reactive(obj)
// 輸出false
console.log(obj === state)

介紹ref

假如如今咱們須要在一個函數裏面聲明用戶的信息,那麼咱們可能會有兩種不同的寫法

// 寫法1
let name = '子君'
let gzh = '前端有的玩'
// 寫法2
let userInfo = {
  name: '子君',
  gzh: '前端有的玩'
}

上面兩種不一樣的聲明方式,咱們使用的時候也是不一樣的,對於寫法1咱們直接使用變量就能夠了,而對於寫法2,咱們須要寫成userInfo.name的方式。咱們能夠發現userInfo的寫法與reactive是比較類似的,而Vue3.0也提供了另外一種寫法,就像寫法1同樣,即ref。先來看一個例子。

<template>
  <div>
    <div>姓名:{{ name }}</div>
  </div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
    const name = ref("子君");
    console.log('姓名',name.value)
    // 5秒後修改name爲 前端有的玩
    setTimeout(() => {
      name.value = "前端有的玩";
    }, 1000 * 5);
    return {
      name
    };
  }
};
</script>

經過上面的代碼,能夠對比出來reactiveref的區別

  1. reactive傳入的是一個對象,返回的是一個響應式對象,而ref傳入的是一個基本數據類型(其實引用類型也能夠),返回的是傳入值的響應式值
  2. reactive獲取或修改屬性能夠直接經過state.prop來操做,而ref返回值須要經過name.value的方式來修改或者讀取數據。可是須要注意的是,在template中並不須要經過.value來獲取值,這是由於template中已經作了解套。

Vue3.0優雅的使用v-model

v-model並非vue3.0新推出的新特性,在Vue2.0中咱們已經大量的到了v-model,可是V3V2仍是有很大的區別的。本節咱們將主要爲你們帶來如何在Vue3.0中使用v-model,Vue3.0中的v-model提供了哪些驚喜以及如何在Vue3.0中自定義v-model

Vue2.0Vue3.0中使用v-model

Vue2.0中如何實現雙向數據綁定呢?經常使用的方式又兩種,一種是v-model,另外一種是.sync,爲何會有兩種呢?這是由於一個組件只能用於一個v-model,可是有的組件須要有多個能夠雙向響應的數據,因此就出現了.sync。在Vue3.0中爲了實現統一,實現了讓一個組件能夠擁有多個v-model,同時刪除掉了.sync。以下面的代碼,分別是Vue2.0Vue3.0使用v-model的區別。

  1. Vue2.0中使用v-model

    <template>
      <a-input v-model="value" placeholder="Basic usage" />
    </template>
    <script>
    export default {
      data() {
        return {
          value: '',
        };
      },
    };
    </script>
  2. Vue3.0中使用v-model

    <template>
      <!--在vue3.0中,v-model後面須要跟一個modelValue,即要雙向綁定的屬性名-->
      <a-input v-model:value="value" placeholder="Basic usage" />
    </template>
    <script>
    export default {
      // 在Vue3.0中也能夠繼續使用`Vue2.0`的寫法
      data() {
        return {
          value: '',
        };
      },
    };
    </script>

    vue3.0中,v-model後面須要跟一個modelValue,即要雙向綁定的屬性名,Vue3.0就是經過給不一樣的v-model指定不一樣的modelValue來實現多個v-model。對於v-model的原理,下文將經過自定義v-model來講明。

自定義v-model

使用Vue2.0自定義一個v-model示例
  1. 組件代碼
<template>
  <div class="custom-input">
    <input :value="value" @input="$_handleChange" />
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  methods: {
    $_handleChange(e) {
      this.$emit('input', e.target.value)
    }
  }
}
</script>
  1. 在代碼中使用組件

    <template>
        <custom-input v-model="value"></custom-input>
    </template>
    <script>
        export default {
        data() {
          return {
            value: ''
          }
        }
      }
    </script>

    Vue2.0中咱們經過爲組件設置名爲value屬性同時觸發名爲input的事件來實現的v-model,固然也能夠經過model來修改屬性名和事件名,能夠看我之前的文章中有詳解。

使用Vue3.0自定義一個v-model示例
  1. 組件代碼

    <template>
      <div class="custom-input">
        <input :value="value" @input="_handleChangeValue" />
      </div>
    </template>
    <script>
    export default {
      props: {
        value: {
          type: String,
          default: ""
        }
      },
      name: "CustomInput",
      setup(props, { emit }) {
        function _handleChangeValue(e) {
          // vue3.0 是經過emit事件名爲 update:modelValue來更新v-model的
          emit("update:value", e.target.value);
        }
        return {
          _handleChangeValue
        };
      }
    };
    </script>
    1. 在代碼中使用組件

      <template>
        <!--在使用v-model須要指定modelValue-->
        <custom-input v-model:value="state.inputValue"></custom-input>
      </template>
      <script>
      import { reactive } from "vue";
      import CustomInput from "../components/custom-input";
      export default {
        name: "Home",
        components: {
          CustomInput
        },
        setup() {
          const state = reactive({
            inputValue: ""
          });
          return {
            state
          };
        }
      };
      </script>

到了Vue3.0中,由於一個組件支持多個v-model,因此v-model的實現方式有了新的改變。首先咱們不須要使用固定的屬性名和事件名了,在上例中由於是input輸入框,屬性名咱們依然使用的是value,可是也能夠是其餘任何的好比name,data,val等等,而在值發生變化後對外暴露的事件名變成了update:value,即update:屬性名。而在調用組件的地方也就使用了v-model:屬性名來區分不一樣的v-model

總結

在本文中咱們主要講解了開發環境的搭建,setup,reactive,ref,v-model等的介紹,同時經過對比Vue3.0Vue2.0的不一樣,讓你們對Vue3.0有了必定的瞭解,在下文中咱們將爲你們帶來更多的介紹,好比技術屬性,watch,生命週期等等,敬請期待。本文首發於公衆號【前端有的玩】,學習Vue,面試刷題,盡在【前端有的玩】,`乘興裸辭心甚爽,面試工做屢遭難。
幸得每日一題伴,點擊關注莫偷懶。`,下週一新文推送,不見不散。

結語

不要吹滅你的靈感和你的想象力; 不要成爲你的模型的奴隸。 ——文森特・梵高
相關文章
相關標籤/搜索