美文网首页
Vue基础教程之-核心概念(二)

Vue基础教程之-核心概念(二)

作者: AC编程 | 来源:发表于2021-05-25 17:25 被阅读0次

一、Vue注入

1.1 注入概念

配置对象中的部分内容会被提取到Vue实例中:data、methods,该过程称之为注入。

如下代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id ="app">
        <!-- 界面模板 -->
        <!-- mustache -->
        <h1>系统名称:{{title}}</h1>
        <ul>
            <!-- v-for 指令-->
            <li v-for="(item,i) in products">
                名称:{{item.name}} 
                <button @click="changeStock(item,item.stock-1)">-</button>
                <span v-if="item.stock>0">{{item.stock}}</span>
                <span v-else>无货</span>
                <button @click="changeStock(item,item.stock+1)">+</button>

                <button @click="remove(i)">删除</button>
            </li>
        </ul>
    </div>
    <script src="./vue.min.js" ></script>
    <script>
        // vm:Vue实例
        var vm = new Vue({       //配置对象
            el:"#app",  // css选择器
            data:{      //和界面相关的数据
                title:"库存管理系统",
                products:[
                    {name:"iphone",stock:10},
                    {name:"xiaomi",stock:5},
                    {name:"huawei",stock:6},
                ],
            },
            methods:{
                remove(i){
                    this.products.splice(i,1);
                },
                changeStock(product,newStock){
                    if(newStock<0){
                        newStock = 0;
                    }
                    product.stock = newStock;
                }
            },
        });
    </script>
</body>
</html>
注入
1.2 注入目的

注入目的有两个

  • 完成数据响应式
  • 绑定this
1.3 数据响应式vue是怎么知道数据被更改了?

vue2.0是通过Object.defineProperty方法完成了数据响应式(更改数据后会调用该方法),这个是ES5的方式。
vue3.0是通过Class Proxy完成的数据响应式。

Class ProxyObject.defineProperty效率更高,Object.defineProperty有天生的缺陷,新增或删除了属性,Object.defineProperty无法感知

1.3.1 新增属性无感知,界面不会重新渲染

添加一个<p>{{abc}}</p>标签,abc这个属性暂时不存在,页面会报错,我们动态添加abc属性,并赋值为123,但页面没有显示出123的p标签,因此新增属性无感知,界面不会重新渲染。

添加p标签 新增属性无感知,界面不会重新渲染
1.3.2 删除属性无感知,界面不会重新渲染

我们动态删除第一项的产品,delete vm.products[0],界面没有重新渲染。

删除属性无感知,界面不会重新渲染
1.4 注入目的绑定this
// vm:Vue实例
        var vm = new Vue({       //配置对象
            el:"#app",  // css选择器
            data:{      //和界面相关的数据
                title:"库存管理系统",
                products:[
                    {name:"iphone",stock:10},
                    {name:"xiaomi",stock:5},
                    {name:"huawei",stock:6},
                ],
            },
            methods:{
                remove(i){
                    this.products.splice(i,1);
                },
            },
        });

remove方法中的this,按道理来说,应该指向的是methods,但现在指向的是vm实例。原因是methods.remove先提取到Vue实例中了,并绑定了thisvm,类似于 methods.remove.bind(vm)

二、虚拟DOM树

2.1 虚拟DOM树概览

为了提高渲染效率,Vue会把模板编译为虚拟DOM树,然后再生成真实的DOM

模板-虚拟DOM-真实DOM

console.dir(document.body) 可以打印出真实DOM树结构

真实DOM树

vm._vnode 可查看虚拟DOM

虚拟DOM树

当数据更改时,将重新编译成虚拟DOM树,然后对前后两棵树进行对比,仅将差异部分反映到真实DOM,这样即可最小程度的改动真实DOM,提升页面效率。

diff算法
2.2 提升Vue效率

因此,对于vue而言,提升效率重点着眼于两个方面:

  • 减少新的虚拟DOM的生成
  • 保证对比之后,只有必要的节点有变化
2.3 Vue生成虚拟DOM树的方式

Vue提供了多种方式生成虚拟DOM树
1、在挂载的元素内部直接书写,此时将使用元素的outerHTML作为模板

outerHTML

2、在template配置中书写

在配置里加template

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id ="app">
    </div>
    <script src="./vue.min.js" ></script>
    <script>
        // vm:Vue实例
        var vm = new Vue({       //配置对象
            el:"#app",  // css选择器
            template:`
            <div id ="app">
                <!-- 界面模板 -->
                <!-- mustache -->
                <h1>系统名称:{{title}}</h1>
                <ul>
                    <!-- v-for 指令-->
                    <li v-for="(item,i) in products">
                        名称:{{item.name}} 
                        <button @click="changeStock(item,item.stock-1)">-</button>
                        <span v-if="item.stock>0">{{item.stock}}</span>
                        <span v-else>无货</span>
                        <button @click="changeStock(item,item.stock+1)">+</button>

                        <button @click="remove(i)">删除</button>
                    </li>
                </ul>
            </div>
            `,
            data:{      //和界面相关的数据
                title:"库存管理系统",
                products:[
                    {name:"iphone",stock:10},
                    {name:"xiaomi",stock:5},
                    {name:"huawei",stock:6},
                ],
            },
            methods:{
                remove(i){
                    this.products.splice(i,1);
                },
                changeStock(product,newStock){
                    if(newStock<0){
                        newStock = 0;
                    }
                    product.stock = newStock;
                }
            },
        });
    </script>
</body>
</html>

3、在render配置中用函数直接创建虚拟节点树,此时,完全脱离模板,将省略编译步骤

render方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id ="app">
    </div>
    <script src="./vue.min.js" ></script>
    <script>
        // vm:Vue实例
        var vm = new Vue({       //配置对象
            el:"#app",  // css选择器

            render(h){
                return h("div",[
                    h("h1",this.title),
                    h("p","首页")
                ]);
            },
        
            data:{      //和界面相关的数据
                title:"库存管理系统",
            },
        });
    </script>
</body>
</html>
render方式

我们可以用这种方式动态生成6级标题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id ="app">
    </div>
    <script src="./vue.min.js" ></script>
    <script>
        // vm:Vue实例
        var vm = new Vue({       //配置对象
            el:"#app",  // css选择器

            render(h){

                var titles = [];

                for(var i = 1;i<=6;i++){
                    titles.push(h(`h${i}`,`${i}级标题`));
                }

                return h("div",titles);
            },
        
            data:{      //和界面相关的数据
                title:"库存管理系统",
            },
        });
    </script>
</body>
</html>
动态生成6级标题

这些步骤从上到下,优先级逐渐提升

注意:虚拟节点树必须是单根的
原因是diff算法只能对比前后两棵树,如果是多根节点,则会生成多棵树,diff算法无法对比。

三、挂载

将生成的真实DOM树,放置到某个元素位置,称之为挂载。挂载的方式:
1、通过el:"css选择器" 进行配置
2、通过vue实例.$mount("css选择器") 进行配置

四、完整流程

完整流程

源码

源码 001

相关文章

  • Vue基础教程之-核心概念(二)

    一、Vue注入 1.1 注入概念 配置对象中的部分内容会被提取到Vue实例中:data、methods,该过程称之...

  • 2019-11-26 Vue学习常用网站

    Vue中文官网 基础教程 Vue中文官网 API即Vue实例包含的默认属性和方法 Vue状态共享之Vuex Vue...

  • Vue基础教程之-组件核心概念(四)

    一、模块化 1.1 为什么需要模块化 没有模块化的世界:全局变量污染、难以管理的依赖。常见的模块化标准:Commo...

  • vue组件三大核心概念详解

    vue组件三大核心概念详解

  • Kubernetes之核心概念(二)

    Kubernetes核心概念 要深入的理解Kubernetes的特性和工作机制,首先要掌握Kubernetes模型...

  • Day1.Vue(基本使用和define.properties)

    基本使用(概念) 1.vue的三大核心core,vuex(状态管理),vue-Router(路由),也称为VUE全...

  • Vue原理

    vue原理相关 Vue核心概念 vue实例化 虚拟dom 模板编译 数据绑定(响应式) 组件化 MVVM mode...

  • Python读书线

    《Python基础教程》 《Python核心编程》 《Python Cookbook》 首先是大二的时候看完了《P...

  • vue原理相关

    Vue核心概念 vue实例化 虚拟dom 模板编译 数据绑定(响应式) 组件化 MVVM model和view层通...

  • Vue路由-Vue Router

    一、概念 Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页...

网友评论

      本文标题:Vue基础教程之-核心概念(二)

      本文链接:https://www.haomeiwen.com/subject/kqtcsltx.html