Vue的深入理解

2020-03-11  本文已影响0人  代艳霞

近期项目需要用到Vue,但又不是整个项目都用Vue的那种,只是部分功能需要使用,这个时候,就需要单独引入Vuejs文件来完成,官方文档虽然有使用说明,但是相对于整个项目都用Vue来写的文档,单独引用vuejs文件的使用说明相对来说要少一些,这个时候就需要对Vue有深入的理解,才能够正确使用,本人也是在此次摸索的过程中,对Vue有了更深入的理解。不再是之前整个项目都用Vue脚手架去搭建,只是会用,却不知道内部原理。

首先我们思考几个问题:

  1. 一个页面是否可以创建多个Vue实例;
  2. el匹配多个元素时,Vue实例会不会分别在每个元素上渲染;
  3. 多个Vue实例挂载到同一个元素上,最终会显示哪一个;
  4. Vue可以用来实例化,那组件可不可以实例化;
  5. 不同标签是否可以引用同一个组件,即:一个组件是否可以命名多个name
  6. 多个Vue实例是否可以共用一个Vue Router实例
  7. 多个Vue实例是否可以共用一个Store实例

1. 一个页面是否可以创建多个Vue实例

<body>
<div class="app1">
    {{message}}
</div>
<div id="html">
    非vue代码
</div>
<div class="app1 app2">
    {{message}}
</div>
<script>
<!-- 初始化第一个实例-->
var vm1 = new Vue({
        el:".app1",
        data:{
            message: "vue第一个实例",
            commont:"公用data"
        }
    });
<!-- 初始化第二个实例-->
var vm2 = new Vue({
    el:".app2",
    data:{
        message: "vue第二个实例",
    }
});
</script>

</body>
实例化多个vue

结果验证:一个页面是可以实例化多个Vue实例,因为每一个Vue都对应一个自己的el,它的作用就是指定在html的哪个元素中插入Vue渲染的DOM树,这样不但可以保证Vue代码正常解析,还能保证一个页面有多个Vue实例的时候,数据不会互相影响。

2. 当el匹配多个元素时,Vue实例会不会分别在每个元素上渲染

<body>
<div class="app1">{{message}}</div>

<div id="html">非vue代码</div>

<div class="app1">{{message}}</div>

<script>
//初始化第一个实例
var vm1 = new Vue({
        el:".app1",
        data:{
            message: "vue第一个实例",
        }
    });
</script>

</body>
el匹配多个元素

根据页面解析情况,我们得出如下结论:当el匹配到多个元素时,它并不会在每个元素上都渲染,而是在匹配到的第一个元素上渲染。所以这样的结果正好也说明了官方文档上为什么给el传的都是id选择器而不是类选择器了。

3. 多个Vue实例挂载到同一个元素上,最终会显示哪一个

<body>
<div class="app1">{{message}}</div>

<div id="html">非vue代码</div>


<script>
//初始化第一个实例
 new Vue({
        el:".app1",
        data:{
            message: "第一个Vue实例",
        }
    });
//初始化第二个实例
new Vue({
    el:".app1",
    data:{
        message: "第二个Vue实例",
    }
});
</script>

</body>

多个实例挂载到一个元素
<body>
<div class="app1">{{message}}</div>

<div id="html">非vue代码</div>

<script>
//初始化第一个实例
 new Vue({
        el:".app1",
        data:{
            message: "第一个Vue实例",
        }
    });
//初始化第二个实例
new Vue({
    el:".app1",
    template:"<div>第二个Vue实例</div>"
});
</script>

</body>
template

很显然,最终显示的是第二个Vue实例的效果,到此我们才可以判断多个Vue实例是可以挂载到同一个元素上的,并且最终展示的是最后一个被挂载的Vue实例的效果。

4. Vue可以用来实例化,那组件可不可以实例化

<body>
<div id="app">
    <app></app>
</div>

<script>
    var APP={
        template: '<div>我是组件-----{{compontentData}}</div>',
        data:function () {
            return{
                compontentData:"组件的数据"
            }
        }
    } ;
var Component =  Vue.component('app',APP);
new Vue({
    el:"#app",
})

</script>

</body>
根组件

代码如下:

<body>
<div id="app">
    <dyx></dyx>
</div>

<script>
    var Dyx={
        template: '<div>我是组件-----{{compontentData}}</div>',
        data:function () {
            return{
                compontentData:"组件的数据"
            }
        }
    } ;
var DyxComponent =  Vue.component('dyx',Dyx);
new DyxComponent({
    el:"#app",
})

</script>

</body>
根目录

测试证明:Vue组件是可以被实例化的,并且也可以作为根组件来渲染到元素上,这样就少一层组件的嵌套,效果是实现了,那组件可以被实例化的原理是什么呢?这就需要我们去查一下官网API,官网文档是这样描述组件注册的:

// 注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({ /* ... */ }))

// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', { /* ... */ })

// 获取注册的组件 (始终返回构造器)
var MyComponent = Vue.component('my-component')

那我们在看一下extend构造器又是什么?

子类

看完官方的API我们深刻理解了:Vue的组件就是Vue的子类,那类有继承的概念,Vue是一个类,Vue的组件是Vue的子类,所以Vue所具有的特性,Vue组件也都具有,Vue能被实例化且渲染到元素上,Vue组件也能被实例化且渲染到元素上,这就是Vue组件可以被实例化的本质。

5. 一个组件是否可以注册为多个组件名

组件定义
  1. 我们先定义一个组件,代码如下:
var Dyx={
        template: '<div>我是组件dyx</div>',
        data:function () {
            return{
                compontentData:"组件的数据"
            }
        }
    } ;

  1. 然后给这个组件全局注册两个名字(dyx,gby),代码如下:
Vue.component('dyx',Dyx);
Vue.component('gby',Dyx);
  1. 然后在页面里面使用,代码如下:
<div id="app">
    <dyx></dyx>
    <gby></gby>
</div>
  1. 打开浏览器,我们来看一下页面的效果:
两个组件页面效果

结果证明,一个组件是可以注册多个名字的,为什么可以呢?因为组件最重要的是定义,而名字只是起到一个映射的作用,以便让解析器可以通过名字找到对应的组件的定义。

6. 多个Vue实例是否可以共用一个Vue Router实例

  1. 首先我们看一下代码:
<body>
<!--第1个vue-->
<div id="routerele1">
    <p>第<span class="vue1">1</span>个vue实例</p>
    <div>
        <p><router-link to="/foo">GO to foo</router-link></p>
        <p><router-link to="/bar">GO to bar</router-link></p>
    </div>
    <p>第<span class="vue1">1</span>个路由显示的地方</p>
    <div class="routerView"><router-view></router-view></div>
</div>
<!--第2个vue-->
<div id="routerele2">
    <p>第<span class="vue2">2</span>个vue实例</p>
    <div>
        <p><router-link to="/foo">GO to foo</router-link></p>
        <p><router-link to="/bar">GO to bar</router-link></p>
    </div>
    <p>第<span class="vue2">2</span>个路由显示的地方</p>
    <div class="routerView"><router-view></router-view></div>
</div>
<script src="vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<script>
    // 定义路由
    var Foo = {template: '<div>foo路径</div>'};
    var Bar = {template: '<div>bar路径</div>'};
    var routes = [
        {path: '/foo', component: Foo},
        {path: '/bar', component: Bar}
    ];
    var router = new VueRouter({routes: routes});
    //初始化第1个vue
    new Vue({
        router: router
    }).$mount('#routerele1');
    //初始化第2个vue
    new Vue({
        router: router
    }).$mount('#routerele2');
</script>
</body>
  1. 打开浏览器,我们点击第1个Vue的路由foo来看一下页面的效果:
foo路由

3.然后我们点击第2个Vuebar路由,来看一下页面的效果:

bar路由

结果证明,多个Vue实例可以共用一个路由Vue Router实例的。这也说明了,Vue Router底层实现中,是支持多个Vue实例作为监听者的。

7. 多个Vue实例是否可以共用一个Store实例

  1. 首先我们看一下代码:
<body>
<div class="app1" @click="changeStore()">{{count1}}</div>

<div id="html">非vue代码</div>

<div class="app2">{{count2}}</div>

<script>
    var  store = new Vuex.Store({
        state: {
            count: 0
        },
        mutations: {
            increment (state) {
                state.count++
            }
        }
    });
//初始化第一个实例
 new Vue({
        el:".app1",
        store:store,
     computed: {
         count1:function () {
             return this.$store.state.count
         }
     },
     methods:{
       changeStore:function () {
           store.commit('increment') ;
       }
     },
    });
//初始化第二个实例
new Vue({
    el:".app2",
    store:store,
    computed: {
        count2:function () {
            return this.$store.state.count
        }
    },
});
</script>

</body>

我们初始化一个Store实例,然后给两个Vue实例配置同一个Store实例,页面显示,两个实例都可以获取Store里面的count,哪如果我们手动修改(触发@click事件)其中一个Vue实例里面的Store里面的值,另外一个Vue实例的Store值又会是什么样的结果呢?测试页面效果如下:

改变其中一个store的值

结果显示,两个Vue实例显示的Store里的count的值是一样的,这样也就证明了,多个Vue实例是可以共用一个Store实例的。

虽然以上的测试和想法,在实际项目中我们可能不会去应用,但是经过我们的思考、测试、验证,起码可以让我们对Vue框架有一个更深层次的理解,从而也能更好的应用框架。

以上就是本人对Vue的理解及研究,有判断不对的地方,欢迎大家留言指正。

上一篇 下一篇

猜你喜欢

热点阅读