ホームページ > 記事 > ウェブフロントエンド > [VuePress の動作] コード コピー プラグインを開発するためのステップバイステップ
この記事では、VuePressの実戦を理解し、VuePressプラグイン(コードコピープラグイン)をゼロから開発する方法を紹介しますので、皆様のお役に立てれば幸いです!
VuePress ブログを構築するプロセスでは、すべてのプラグインがニーズを満たすことができるわけではないため、この記事ではコード コピー プラグインの実装を次のように取り上げます。 VuePress プラグインを最初から実装する方法を説明する例。
プラグインを開発するときに解決すべき最初の問題は、プラグインをローカルで開発する方法です。 VuePress 1.0 公式ドキュメントを参照しても見つかりませんでした。解決策ですが、VuePress 2.0 公式ドキュメントの「Local Plug-in」に次のように書かれています。構成ファイルをプラグインとして直接使用することをお勧めします。これは、ほとんどすべてのプラグイン API を構成ファイルで使用でき、ほとんどのシナリオでその方が便利だからです。
#ただし、設定ファイルで行うべきことが多すぎる場合は、それらを別のプラグインに抽出し、絶対パスを設定するか require :# を使用して使用することをお勧めします。 ##プロジェクトの初期化module.exports = { plugins: [ path.resolve(__dirname, './path/to/your-plugin.js'), require('./another-plugin'), ], }それでは始めましょう!
フォルダーの下に新しいフォルダープラグインを保存するために、
.vuepress
vuepress-plugin-code-copy
を作成します。関連するコードを入力し、コマンド ラインでフォルダーに入り、package.json を作成します。このとき、ファイルのディレクトリは
.vuepress ├─ vuepress-plugin-code-copy │ └─ package.json └─ config.jsです。
「
vuepress-plugin-code-copy に新しい
index.js ファイルを作成します。
公式ドキュメント プラグインの例#」の記述方法を参照してください。 ##、返されたオブジェクトの関数形式を使用します。この関数は、プラグイン構成オプションを最初のパラメータとして受け入れ、コンパイル時のコンテキストを含む ctx オブジェクトを 2 番目のパラメータとして受け入れます: module.exports = (options, ctx) => { return { // ... } }
Refer公式ドキュメントのオプション API の name
と、ライフサイクル関数の ready フック
に対して、初期テスト コードを書きます: module.exports = (options, ctx) => {
return {
name: 'vuepress-plugin-code-copy',
async ready() {
console.log('Hello World!');
}
}
}
現時点では
を実行します。これは実行プロセス中に使用できます。プラグイン名を参照して結果を出力します。
Plug-設計中# これで、プラグインをコピーするコードの効果を想像できます。達成される効果は次のとおりだと思います。
mounted
またはupdated の場合は、
document.querySelector を使用します。VuePress プラグインには、ルート コンポーネントのライフサイクルを制御する方法がありますか? VuePress 公式ドキュメントの Option API
を確認すると、VuePress が clientRootMixin メソッドを提供していることがわかります。 は、ミックスイン ファイルへのパスを指し、これによりライフタイムを制御できます。
サンプル コードを見てください: // 插件的入口
const path = require('path')
module.exports = {
clientRootMixin: path.resolve(__dirname, 'mixin.js')
}
// mixin.js
export default {
created () {},
mounted () {}
}
これが必要ではないでしょうか?それでは、
の内容を次のように変更します。vuepress-plugin-code-copy## の下に新しいconst path = require('path'); module.exports = (options, ctx) => { return { name: 'vuepress-plugin-code-copy', clientRootMixin: path.resolve(__dirname, 'clientRootMixin.js') } }
clientRootMixin.js# を作成します。
ファイル、コードの記述:export default { updated() { setTimeout(() => { document.querySelectorAll('div[class*="language-"] pre').forEach(el => { console.log('one code block') }) }, 100) } }
ブラウザでページを更新し、印刷結果を表示します:
<p>接下来就要思考如何写入按钮元素了。</p>
<p>当然我们可以使用原生 JavaScript 一点点的创建元素,然后插入其中,但我们其实是在一个支持 Vue 语法的项目里,其实我们完全可以创建一个 Vue 组件,然后将组件的实例挂载到元素上。那用什么方法挂载呢?</p>
<p>我们可以在 Vue 的<a href="vuepress.vuejs.org" target="_blank" rel="nofollow noopener noreferrer" ref="nofollow noopener noreferrer">全局 API </a>里,找到 <code>Vue.extend
API,看一下使用示例:
// 要挂载的元素 <div id="mount-point"></div>
// 创建构造器 var Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point')
结果如下:
// 结果为: <p>Walter White aka Heisenberg</p>
那接下来,我们就创建一个 Vue 组件,然后通过 Vue.extend
方法,挂载到每个代码块元素中。
在 vuepress-plugin-code-copy
下新建一个 CodeCopy.vue
文件,写入代码如下:
<template> <span class="code-copy-btn" @click="copyToClipboard">{{ buttonText }}</span> </template> <script> export default { data() { return { buttonText: 'Copy' } }, methods: { copyToClipboard(el) { this.setClipboard(this.code, this.setText); }, setClipboard(code, cb) { if (navigator.clipboard) { navigator.clipboard.writeText(code).then( cb, () => {} ) } else { let copyelement = document.createElement('textarea') document.body.appendChild(copyelement) copyelement.value = code copyelement.select() document.execCommand('Copy') copyelement.remove() cb() } }, setText() { this.buttonText = 'Copied!' setTimeout(() => { this.buttonText = 'Copy' }, 1000) } } } </script> <style scoped> .code-copy-btn { position: absolute; bottom: 10px; right: 7.5px; opacity: 0.75; cursor: pointer; font-size: 14px; } .code-copy-btn:hover { opacity: 1; } </style>
该组件实现了按钮的样式和点击时将代码写入剪切版的效果,整体代码比较简单,就不多叙述了。
我们修改一下 clientRootMixin.js
:
import CodeCopy from './CodeCopy.vue' import Vue from 'vue' export default { updated() { // 防止阻塞 setTimeout(() => { document.querySelectorAll('div[class*="language-"] pre').forEach(el => { // 防止重复写入 if (el.classList.contains('code-copy-added')) return let ComponentClass = Vue.extend(CodeCopy) let instance = new ComponentClass() instance.code = el.innerText instance.$mount() el.classList.add('code-copy-added') el.appendChild(instance.$el) }) }, 100) } }
这里注意两点,第一是我们通过 el.innerText
获取要复制的代码内容,然后写入到实例的 code
属性,在组件中,我们是通过 this.code
获取的。
第二是我们没有使用 $mount(element)
,直接传入一个要挂载的节点元素,这是因为 $mount()
的挂载会清空目标元素,但是这里我们需要添加到元素中,所以我们在执行 instance.$mount()
后,通过 instance.$el
获取了实例元素,然后再将其 appendChild
到每个代码块中。关于 $el
的使用可以参考官方文档的 el 章节 。
此时,我们的文件目录如下:
.vuepress ├─ vuepress-plugin-code-copy │ ├─ CodeCopy.vue │ ├─ clientRootMixin.js │ ├─ index.js │ └─ package.json └─ config.js
至此,其实我们就已经实现了代码复制的功能。
有的时候,为了增加插件的可拓展性,会允许配置可选项,就比如我们不希望按钮的文字是 Copy,而是中文的「复制」,复制完后,文字变为 「已复制!」,该如何实现呢?
前面讲到,我们的 index.js
导出的函数,第一个参数就是 options 参数:
const path = require('path'); module.exports = (options, ctx) => { return { name: 'vuepress-plugin-code-copy', clientRootMixin: path.resolve(__dirname, 'clientRootMixin.js') } }
我们在 config.js
先写入需要用到的选项:
module.exports = { plugins: [ [ require('./vuepress-plugin-code-copy'), { 'copybuttonText': '复制', 'copiedButtonText': '已复制!' } ] ] }
我们 index.js
中通过 options
参数可以接收到我们在 config.js
写入的选项,但我们怎么把这些参数传入 CodeCopy.vue
文件呢?
我们再翻下 VuePress 提供的 Option API,可以发现有一个 define API,其实这个 define 属性就是定义我们插件内部使用的全局变量。我们修改下 index.js
:
const path = require('path'); module.exports = (options, ctx) => { return { name: 'vuepress-plugin-code-copy', define: { copybuttonText: options.copybuttonText || 'copy', copiedButtonText: options.copiedButtonText || "copied!" }, clientRootMixin: path.resolve(__dirname, 'clientRootMixin.js') } }
现在我们已经写入了两个全局变量,组件里怎么使用呢?答案是直接使用!
我们修改下 CodeCopy.vue
的代码:
// ... <script> export default { data() { return { buttonText: copybuttonText } }, methods: { copyToClipboard(el) { this.setClipboard(this.code, this.setText); }, setClipboard(code, cb) { if (navigator.clipboard) { navigator.clipboard.writeText(code).then( cb, () => {} ) } else { let copyelement = document.createElement('textarea') document.body.appendChild(copyelement) copyelement.value = code copyelement.select() document.execCommand('Copy') copyelement.remove() cb() } }, setText() { this.buttonText = copiedButtonText setTimeout(() => { this.buttonText = copybuttonText }, 1000) } } } </script> // ...
最终的效果如下:
完整的代码查看:https://github.com/mqyqingfeng/Blog/tree/master/demos/VuePress/vuepress-plugin-code-copy
【相关推荐:vue.js视频教程】
以上が[VuePress の動作] コード コピー プラグインを開発するためのステップバイステップの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。