一个页面 Vue 实例只能有一个吗?

Vue是一个构造函数,通常建议在一个页面中创建一个Vue实例,通过el属性指定Vue渲染的HTML模板。尽管如此,实际上可以在同一页面中创建多个Vue实例,每个实例作用于不同的模板。组件是可复用的Vue实例。本文通过示例探讨了在同一页面上创建多个Vue实例的可能性和工作原理。

使用 Vue 写项目时,最重要的是 Vue 实例,它提供了学习 Vue 的方向,逐步掌握与 Vue 实例相关的「特性」是我们的终极目标。

首先,在一个 html 文件中加载 vue.js,在 学习 Vue 从如何贡献代码开始 这节内容中我们提到过,可以通过 script 标签直接加载 vue.js 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue实例</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<body>

用浏览器打开这个页面,在 console 中输入 Vue ,你会发现 Vue 其本质是一个函数:

其实 Vue 是一个构造函数,可以被看作是一个“类”,通过 new 创建它的实例。那究竟在一个页面中能创建多少个实例呢?

通常在一个页面中只创建一个 Vue 实例:

<body>
    <div id="app">Hello {{ msg }}</div>
    <script>
        const vm = new Vue({
            el: '#app',
            data: function () {
                return {
                    msg: '前端小课'
                }
            }
        });
</script>
</body>

创建一个 Vue 实例时传入一个「定制」的对象,我们可以把上面的对象换一种写法:

<body>
    <div id="app">Hello {{ msg }}</div>
    <script>
        const obj = {
            el: '#app',
            data: function () {
                return {
                    msg: '前端小课'
                }
            }
        }
        const vm = new Vue(obj);
</script>
</body>

在 obj 这个对象中,有个属性 el,表示给 Vue 实例提供的「模板」,也就是说当你创建一个实例时,要告诉 Vue 渲染的 HTML 是什么,如何把 HTML 中要做的事情与 obj 建立某种连接。比如 HTML 模板中要显示的数据如何和 Vue 实例的数据建立关联,如何响应 HTML 模板中要触发的事件。要建立关联,必须在模板与Vue实例之间作出约定。

el 可以是一个 选择器,也可以是一个 HTMLElement (打通 DOM 的设计架构 )实例。可以把 el 写成:

el: document.getElementById('app'),

也可以是任意一个选择器:

 el: 'div',

下面这个显示结果是什么?

最终发现 title 这个值 “早上好,打卡!” 并没有被渲染到 HTML 上,这是因为 title 所在的 div 并没有在 Vue 实例的作用范围内,也就是说 Vue 实例只能作用到创建实例时所在的模板(比如通过 el 指向的 模板):

其实,一个页面可以创建多个 Vue 实例,比如下面的代码创建了 3 个 Vue 实例,发现可以正常工作:

<body>
    <div id="app">
        <h1>{{ msg }}</h1>
    </div>
    <div id="app-body">
        <h4>{{ title }}</h4>
    </div>
    <div class="app-footer">
        <h4>{{ footer }}</h4>
    </div>
    <script>
        const vm = new Vue({
            el: '#app',
            data: function () {
                return {
                    msg: "欢迎来到前端小课",
                }
            }
        });
</script>
    <script>
        const vmBody = new Vue({
            el: '#app-body',
            data: function () {
                return {
                    title: "Vue 实例讲解"
                }
            }
        });
</script>
    <script>
        const vmFooter = new Vue({
            el: '.app-footer',
            data: function () {
                return {
                    footer: "感谢阅读",
                }
            }
        });
</script>
</body>

用浏览器打开,结果如下:

这个例子让我想到了组件,「组件是可复用的 Vue 实例」,这种写法有点像组件,每一个 Vue 实例看成是一个组件。

我们再看一个例子 —— Vue 实例中再嵌套一个 Vue 实例:

<body>
    <div id="app">
        <h1>{{ msg }}</h1>
        <!-- 这里不能声明一个新的 Vue 实例 -->
        <div id="app-body">
            <h4>会渲染吗?{{ title }}</h4>
        </div>
    </div>
    <script>
        const vm = new Vue({
            el: '#app',
            data: function () {
                return {
                    msg: "欢迎来到前端小课",
                    title: "#app - Vue 实例讲解"
                }
            }
        });
</script>
    <script>
        const vmBody = new Vue({
            el: '#app-body',
            data: function () {
                return {
                    title: "#app-body - Vue 实例讲解"
                }
            }
        });
</script>
</body>

渲染结果为,发现结果使用的是 #app 实例中的数据:

Vue 实例中还有很多 API,每一个 API 都需要我们逐步学习。比如生命周期函数,计算属性,定义方法,过滤器:


大家加油,打卡学习。


推荐阅读:

创建第一个 Vue 项目

学习 Vue 从如何贡献代码开始

学习与实践相结合 · Vue 虚拟实验室近况

Vue中处理一个页面多个表单的`rules`时,可根据不同情况采用不同方法。 若遇到多表单切换校验规则混乱的问题,可给表单添加`v-if`属性,使表单的开关与对话框一致,同时给`form`添加唯一的`key`属性,避免多表单校验规则混乱。示例如下: ```vue <template> <!--表单A,v-if值与dialog的:visible.sync一致 --> <el-form ref="form" :model="form" :rules="rules" label-width="90px" key="add" v-if="open"> <!-- 表单内容 --> </el-form> <!--表单B --> <el-form ref="form" :model="form" :rules="updateRules" label-width="90px" key="update" v-if="updateOpen"> <!-- 表单内容 --> </el-form> <!--表单C --> <el-form ref="form" :model="form" :rules="DateRules" label-width="90px" key="date" v-if="isOpen"> <!-- 表单内容 --> </el-form> </template> <script> export default { data() { return { form: {}, rules: { // 表单A的校验规则 }, updateRules: { // 表单B的校验规则 }, DateRules: { // 表单C的校验规则 }, open: false, updateOpen: false, isOpen: false }; } }; </script> ``` 此方法能确保表单在不显示时,其校验规则不生效,避免校验规则混乱的问题[^2]。 若在Vue3中使用`ref`绑定表单元素,要保证不同表单使用不同的`ref`值,因为`ref`是唯一标识符,不同的`ref`值对应不同的元素或组件实例。若给两个不同的表单元素都绑定相同的`ref`,访问`formRef.value`时,只能引用到最后一个具有相同`ref`的表单元素,会导致只有部分表单进行校验。所以要为每个表单设置不同的`ref`,以正确处理各表单的`rules` [^3]。
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值