あなたのライブラリをVUE 2からVUE 3に移行する方法


Vue 3は角を曲がったところです.誇大宣伝されているので、新しいバージョンにすべての既存のプロジェクトの移行を開始する誘惑される可能性があります.それをする前に、私はあなたにこの単純な質問でいくらかの痛みを保存します:
あなたのアプリケーションは、(bootstrapvue、vuetifyなど)のようなサードパーティ製のライブラリに依存しますか?
答えがイエスであるならば、あなたは瞬間のプロセスを止めたいかもしれません.
なぜ?
Vueプラグインとサードパーティライブラリのほとんどは、グローバルAPI上での壊れた変更のためにsee reference .
Vue貢献者は、これで述べましたgithub thread :

ここではVue 2の移行方法を紹介します.XライブラリVue 3に.あなたがライブラリの所有者か、あなたの好きなカルーセルプラグインにVUE 3に移行することに貢献したいユーザだけであるならば、このチュートリアルはあなたのためです.

新しいグローバルAPI


Vue 3で導入された主要な破壊的変化の一つ.Xは、アプリケーションが作成される方法です
イン2.x グローバルAPIと構成は、Vueの振る舞いをグローバルに変異させる
// main.js
import Vue from 'vue';
import App from './App.vue';

new Vue({
  render: h => h(App),
}).$mount('#app');
例えば、あなたはvue-toasted あなたのプロジェクトにライブラリを使用するVue.use オプションを指定してライブラリオブジェクトを渡します.
// main.js
import Vue from 'vue';
import VueToasted from 'vue-toasted';

Vue.use(VueToasted, { ...options });
フードの下でVueToasted Vueインスタンスを拡張し、いくつかのコンポーネント( vue . component )とグローバルオブジェクトをそれに宣言します( vue .プロトタイプ).
// vue-toasted/src/index.js

const Toasted = {
  install(Vue, options) {
    if (!options) {
      options = {};
    }

    const Toast = new T(options);
    Vue.component('toasted', ToastComponent);
    Vue.toasted = Vue.prototype.$toasted = Toast;
  },
};
3で.xアプリケーションインスタンスはトラフを生成しますcreateApp :
// main.js

import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);
Appインスタンスは現在のグローバルAPIのサブセットを公開します.親指のルールは、グローバルな変異のVueの動作をすぐにこのようなアプリケーションのインスタンスに移動されます任意のAPIです
const app = createApp(App);

app.component('button-counter', {
  data: () => ({
    count: 0,
  }),
  template: '<button @click="count++">Clicked {{ count }} times.</button>',
});

app.directive('blur', {
  mounted: el => el.blur(),
});
それで、あなたはするように誘惑されるかもしれません:
const app = createApp(App);

app.use(VueToasted, { ...options });
Uncaught TypeError: Cannot set property '\$toasted' of undefined
なぜ?何故ならvue-toasted ライブラリのプロパティを' Vue 'に追加されます:Vue.toasted = Vue.prototype.$toasted = Toast;

解決策


実際には、かなり簡単ですplugin/index.js プラグインオブジェクトを作成します.
const VueToastedPlugin = {
  install(app, options) {
    if (!options) {
      options = {};
    }
    const Toast = new T(options);
    app.component('toasted', ToastComponent);
    app.config.globalProperties.$toasted = Toast;
  },
};
export default VueToastedPlugin;
次の2つの微妙な変更点がわかります.
  • APPインスタンスは、インストールメソッドのパラメータとして渡されますVue.component 私たちはapp.component
  • グローバルプロパティを追加するにはVue.prototype なるapp.config.globalProperties
  • 今、あなたは使用できるようになりますapp.use(VueToasted, {...options}); . の場合はvue-toasted ライブラリは、通常、新しいトーストにアクセスするメッセージを作成します$toasted on this :
    methods: {
       showToast() {
          this.$toasted.show('How you doing?');
       }
    }
    
    

    構成APIで


    それで、我々はVue 3なしでランダムなVueライブラリを取ることができます.新しい標準にXのサポート.前のコードは、オプションAPIで完全に動作しますが、VUE 3、組成APIの最も興味深いと新機能の1つに沿ってそれについてはどうですか?
    はい.this は、setup() メソッドは、今日の多くのライブラリをthis . 別の例を挙げましょう.Vue Router 注射するthis.$route and this.$router , and Vuex 注射するthis.$store .
    構成APIを使用する場合、this . プラグインはprovide and inject 内部的に、構成関数を公開します.使い続けましょうvue-toasted 例として:
    // useApi.js
    import { inject } from 'vue';
    
    export const VueToastedSymbol = Symbol();
    
    export function useToasted() {
      const VueToasted = inject(VueToastedSymbol);
      if (!VueToasted) throw new Error('No VueToasted provided!!!');
      return VueToasted;
    }
    
    次に、アプリケーションインスタンスに提供しますapp.provide(VueToastedSymbol, Toast);
    import { Toasted as T } from './js/toast';
    import ToastComponent from './toast.vue';
    import { VueToastedSymbol } from './useApi';
    export * from './useApi';
    
    const VueToastedPlugin = {
      install(app, options) {
        if (!options) {
          options = {};
        }
        const Toast = new T(options);
        app.component('toasted', ToastComponent);
        app.config.globalProperties.$toasted = Toast;
        app.provide(VueToastedSymbol, Toast);
      },
    };
    
    export default VueToastedPlugin;
    
    したがって、任意のセットアップメソッドや構成関数では、次のようにします.
    
    import { useToasted }  from 'vue-toasted`;
    
    const Component = {
      setup() {
        const toasted = useToasted();
    
        toasted.success('Composition API BABYYY!', {
          position: 'bottom-right',
          duration: 5000,
        });
      },
    };
    

    結論


    プラグイン作者がなぜこれをしていないのか🤔? コアライブラリのほとんどはVue-router and Vuex 既に持っている/next ブランチとベータ版は、VuE 3のサポートとデフォルトとしてTypesScriptでも、サードパーティ製のライブラリの残りのオープンソースであり、信じて、自分のライブラリ(私たちは1日あたりの限られた時間)を他の開発者に貢献せずに更新を維持するのは難しいです.
    それで、あなたはあなたのトーストメッセージのために働いていた素晴らしいライブラリを見つけたのは、vue 3のために働いていませんか?私のようにPRを作るhere あなたが今日学ぶものとライブラリに.だけでなく、それは非常にプラグインの作者によって高く評価されるが、また、Vueの知識のより高いレベルを与える.あなたはコミュニティに貢献する😊.

    WIP:新しいグローバルAPIのインストール+組成を提供+更新deps 菅180年



    alvarosaburido
    掲示される
    こんにちは
    このPRはVue 3で使用するライブラリの移行を意味します.X (進行中の作業中です)master しかし、それは/next 両方のベースに分岐2.x and 3.x 解決は同じrepoに共存します.このブランチが作成されたらPRの宛先を変更します
    基本的な変更点vue-toasted/index.js :
    import { Toasted as T } from './js/toast';
    import ToastComponent from './toast.vue';
    import { VueToastedSymbol } from './useApi';
    export * from './useApi';
    
    const VueToastedPlugin = {
      install(app, options) {
        if (!options) {
          options = {};
        }
        const Toast = new T(options);
        app.component('toasted', ToastComponent);
        app.config.globalProperties.$toasted = Toast;
        app.provide(VueToastedSymbol, Toast);
      },
    };
    
    export default VueToastedPlugin;

    Now instead of Vue, the app instance is passed so it will work with the new createApp, and the global property will be available on this by using app.config.globalProperties.$toasted reference

    const app = createApp(App);
    
    app.use(VueToasted, { ...options });

    In Vue 3.x plugins will leverage provide and inject internally and expose a composition function.

    To do that I add a useApi.js for the use of the library along with the Composition API reference:

    // useApi.js
    
    export const VueToastedSymbol = Symbol();
    
    export function useToasted() {
      const VueToasted = inject(VueToastedSymbol);
      if (!VueToasted) throw new Error('No VueToasted provided!!!');
    
      return VueToasted;
    }

    So now, in any setup method or composition function we can do:

    import { useToasted }  from 'vue-toasted`;
    
    const Component = {
      setup() {
        const toasted = useToasted();
    
        toasted.success('Composition API BABYYY!', {
          position: 'bottom-right',
          duration: 5000,
        });
      },
    };

    To support the last release candidate vue 3.0.0-rc.9 I needed to update several packages from the package.json, this is causing errors in the webpack build process, especially with the uglify plugin:

    cross-env NODE_ENV=production webpack --config ./build/webpack.release.js --progress --hide-modules
    
    /Users/alvarosaburido/as/github/as-vue-toasted/node_modules/webpack-cli/bin/cli.js:93
                                    throw err;
                                    ^
    
    Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.
        at Object.get [as UglifyJsPlugin] (/Users/alvarosaburido/as/github/as-vue-toasted/node_modules/webpack/lib/webpack.js:189:10)
      
    
    コアチームからの誰かが私がこれを利用するのを手伝って利用可能であるならば、私は使用される準備ができていると思います(すでに個人的なプロジェクトでサブモジュールとしてテストされます).
    必要に応じて直接私に連絡してください.
    ハッピーコーディング
    View on GitHub
    それはすべての人々、それロッキン'保つ.