Vue.js refs

在 Vue.js 中,refs 是对 DOM 元素或其它组件的引用。这是通过编程发生的。

refs 的一个重要用例是直接 DOM 操作以及与基于 DOM 的库的集成(通常采用它们应该挂载的 DOM 节点)。

引用(Refs)是在模板中的原生元素或子组件上使用 ref="name" 定义的。在以下实例中,输入将存储在 theInput ref 中:

<template>
    <div id="app">
        <input ref="theInput" />
    </div>
</template>

可以通过 this.$refs[name] 从 Vue.js 组件实例访问 Refs。因此,在前面的示例中,我们将 ref 定义为 ref="theInput",我们可以通过 this.$refs.theInput 访问它。

要在单击按钮时聚焦输入,我们可以编写以下内容:

<template>
    <div id="app">
        <input ref="theInput" />
        <button @click="focus()">Focus Input</button>
    </div>
</template>

<script>
export default {
    methods: {
        focus() {
            this.$refs.theInput.focus()
        }
    }
}
</script>

当点击焦点输入按钮时,输入将获得焦点,如下图所示:

image 2023 10 13 16 20 33 069
Figure 1. Figure 4.28: Input focused on a button click

这样,我们就学会了如何使用 $refs 在 Vue.js 组件中抽象 DOM 操作逻辑。如果需要直接在 Vue.js 中选择 DOM 节点,建议使用 ref 而不是使用 DOM 选择 API (querySelector/querySelectorAll)。

在下面的练习中,我们将了解 Countable 库如何帮助提高项目的交互性。

练习 4.06:用 Vue.js 包装 Countable.js

Countable 是一个库,给定一个元素(通常是 HTML textarea 或 input),它将添加段落、单词和字符的实时计数。所捕获文本的实时指标对于提高以编辑文本为核心问题的项目中的交互性非常有用。

在 Vue.js 中使用 ref 的一大用例是能够与直接作用于 DOM 的库集成。

在本练习中,我们将使用 Countable.js 和 Vue.js refs 创建一个对文本区域中的内容进行段落/单词/字符计数的组件。

要访问本练习的代码文件,请参阅 https://packt.live/36oOuGz

请按照以下步骤完成本练习:

  1. 从 npm 安装 countable。我们将在此处运行 npm install --save countable,这会将其添加到我们的依赖项中。

  2. 接下来,我们将创建一个新的 src/components/TextEditorWithCount.vue 组件,其中包含我们将 ref 的 textarea:

    <template>
        <div>
            <textarea
                ref="textArea"
                cols="50"
                rows="7"
            >
            </textarea>
        </div>
    </template>
  3. 接下来,我们将在 src/App.vue 中导入并渲染该组件:

    <template>
        <div id="app">
            <TextEditorWithCount />
        </div>
    </template>
    
    <script>
    import TextEditorWithCount from './components/TextEditorWithCount.vue'
    
    export default {
        components: {
            TextEditorWithCount
        }
    }
    </script>

    应用程序渲染一个 textarea,如下所示:

    image 2023 10 13 16 30 38 820
    Figure 2. Figure 4.29: A bare textarea, as rendered by the application
  4. 我们现在需要集成 Countable。我们将导入它并使用 this.$refs.textArea 对其进行初始化。我们还将实例上的计数存储为 this.count

    <script>
    import * as Countable from 'countable'
    
    export default {
        mounted() {
            Countable.on(this.$refs.textArea, (count) => {
                this.count = count
            })
        },
        data() {
            return {
                count: null
            }
        }
    }
    </script>
  5. 通过对模板(template)进行小幅更新,我们可以显示我们关心的计数:

    <template>
        <div id="app">
            <!-- textarea -->
            <ul v-if="count">
                <li>Paragraphs: {{ count.paragraphs }}</li>
                <li>Sentences: {{ count.sentences }}</li>
                <li>Words: {{ count.words }}</li>
            </ul>
        </div>
    </template>

    现在,我们可以看到当 textarea 为空时计数设置为 0,如下所示:

    image 2023 10 13 16 34 07 177
    Figure 3. Figure 4.30: Textarea with counts set to 0 when empty

    如果我们将一些 Lorem ipsum 放入 textarea,计数将相应更新,如下所示:

    image 2023 10 13 16 34 54 683
    Figure 4. Figure 4.31: Textarea with counts updated when filled
  6. 我们需要做的最后一件事是在组件被销毁时删除 Countable 事件监听器:

<script>
// imports
export default {
    mounted() {
        Countable.on(this.$refs.textArea, (count) => {
            this.count = count
        })
        // 注意这种用法
        this.$once('hook:beforeDestroy', function () {
            Countable.off(this.$refs.textArea)
        })
    },
    // other component properties
}
</script>

我们已经通过编程侦听器实现了这一目标,尽管我们可以通过 beforeDestroy 生命周期方法实现相同的目标。

在 Vue.js 中集成 JavaScript/DOM 库是 Vue.js Refs 的一项重要应用。Refs 允许我们从现有的库生态系统中挑选库,并将它们封装或集成到组件中。

Vue.js 引用对于集成 DOM 库或直接访问 DOM API 非常有用。

为了完善组件组合的学习,我们需要知道如何将数据从子组件传递到父组件。