TOC

简介

    Vue.js可以说是MVVM架构的最佳实践,是一个JavaScript MVVM库,是一套构建用户界面的渐进式框架,它专注于MVVM中的ViewModel,不仅做到了数据双向绑定,而且也是一款相对比较轻量级的JS库,API也非常简洁;
    Vue.js会自动响应数据的变化情况,并且根据用户在代码中预先写好的绑定关系,对所有绑定在一起的数据和视图内容都进行修改,这也是vue.js最大的优点,通过MVVM思想实现数据的双向绑定,让开发者不用再操作dom对象,有更多的时间去思考业务逻辑;
    Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component)中,我们只要先在父级应用中写好各种组件标签(占坑),并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现(填坑),然后整个应用就算做完了;

Vue热加载

    因为Vue的双向数据绑定特性以及技术的成形,实现了项目的热加载,改完页面代码能立即在浏览器方面显示效果,提高开发效率;
    Vue.js是采用Object.defineProperty的getter和setter,并结合Proxy观察者模式来实现数据绑定的。当把一个普通 Javascript对象传给Vue实例来作为它的data选项时,Vue将遍历它的属性,用Object.defineProperty将它们转为 getter/setter,但是用户看不到 getter/setter,只是在内部它们让Vue追踪依赖,在属性被访问和修改时通知变化;

Vue Devtools

    在使用Vue时,推荐在浏览器上安装Vue Devtools,它允许你在一个更友好的界面中审查和调试Vue应用,在Google插件商城中,我们也可以直接搜索到;

Vue文件引入

    Vue既然作为一个JavaScript的库,我们就可以直接使用<script>标签的方式,将这个库引入到我们的HTML文档当中,Vue有在线的库文件,我们可以直接去官方中找,也可以在boocdn中找到这个JavaScript库,如下;
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
<div id="box"></div>
<script>
    const vm = Vue.createApp({
        template: "<h1>cce</h1>"
    })
    vm.mount("#box")
</script>
    在引入之后,我们就可以使用Vue对象下面的createApp方法传递一个对象,这个对象里面包含了我们的Vue模版源码,然后将这个模版源码挂载到页面的某个容器之上,实现页面渲染;

template属性

    Vue对象的createApp属性可以传入一个对象,这个对象里面有一个template属性,这个属性主要作用就是声明我们的Vue模版语言的一个属性,我们将Vue的模版语法写到这个属性里面,Vue框架内部会自动将这个里面的模版语法在页面中进行渲染;
    可以看到,我们上述直接将HTML文档写到一个template属性里面,对于开发来将,非常的不便,其实这个属性我们可以直接省略,将template里面的代码,直接放在<script>标签外部;
    Vue有个机制,当template属性为非空时,会直接将template里面的内容直接替换mount挂载的标签里面的内容,直接覆盖mount挂载的标签里面的内容,那么当template属性为空时,会直接渲染,mount挂载的标签里面的内容;
    所以,我们就可以直接将代码,放在mount挂载的标签里面,Vue会自动渲染,这个里面的所有内容,如下;
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
<div id="box">
    <h1>cce</h1>
</div>
<script>
    const vm = Vue.createApp({})
    vm.mount("#box")
</script>

data属性

    Vue对象的createApp属性可以传入一个对象,这个对象里面有一个data属性,该属性必须是一个函数(在Vue2里面可以是一个对象),并且这个函数的的返回值必须是一个对象,在Vue解析template属性中的模版语言时,会进行检测,一旦检测到存在"{{ var }}"这种语法的定义的字符串时,就会在data属性返回的对象中去寻找标识符为"var"所对应的值,然后将这个值替换到我们的模版语言中;
    同时,Vue的响应式系统也会监听这个data返回的对象的变化,之后该对象的修改或访问,都会在劫持中被处理,那么这个劫持的手段在Vue3中主要是采用ES6的新特性Proxy代理实现的,而在Vue2是使用如下语法实现监听的;
var obj = { name: "cce" };
Object.defineProperty(obj,"name",{
    set:function () {},
    get:function () {}
})
    那么在Vue3之后,是使用Proxy代理来实现的,如下;
var obj = {name: "cce"};
let new_obj = Proxy(obj, {
    set: function (target, property, value, receiver) {},
    get: function (target, property, receiver) {}
})
    一旦监听到,data函数返回的对象内的属性发生变化,就立马将这个最新的数据,渲染到页面上,所以我们template或者app中通过定义"{{ var }}"模版语法,就可以直接访问到data函数返回的对象中的var属性,如果我们修改了标识符var的值,就会被Vue的响应式系统劫持,然后被处理;

methods属性

    Vue对象的createApp属性可以传入一个对象,这个对象里面有一个methods属性,该属性必须是对象,通常,我们在这个对象里面会定义很多方法,比如我们的一些事件函数、功能函数都可以写在里面,同时在这些方法内部使用this可以直接访问到data属性对应的函数返回的对象;
this绑定
    在methods对象里面的函数使用this需要注意,因为函数内部的this绑定是取决于如何被调用的,在之前说过,如果我们将这个函数放到一个对象里面,那么这个函数内部的this绑定的就是对象本身,如果我们这个函数就是一个普通的函数,没有被其他任何对象绑定,那么这个函数中的this就是window,而如果我们调用这个函数时,调用了这个函数的apply方法,传入了this,那么这个函数绑定的this就是apply方法的第一个参数;
    而methods里面的函数绑定的this,其实就是data属性的返回值,即data属性对应函数返回的对象,通过下面的源码我们也可以看到,Vue3通过bind的方式,将methods属性里面的每一个方法都显式的绑定了this;

    从这里,我们也可以看到,methods属性里面的每一个函数绑定的是一个instance.proxy对象,实际上,这个instance.proxy对象就是data属性的函数的返回值;

模版语言

    在前面,讲解了template、data、methods三个属性,那么从现在开始,进入一个大的篇章,即模版语言,模版语言其实讲的也就是template属性,template属性的值,就是一堆模版语言,Vue里面有很多模版语法,如插值语法、基本指令、事件绑定等模版语法;
Mustache插值语法
    Mustache是基于JavaScript实现的模版引擎,类似于JQuery Template,但是这个模版更加的轻量级,语法更加的简单易用,很容易上手,Mustache的语法很简单,用双大括号"{{}}"标记要绑定的字段即可;
    如果我们希望将data对应的函数返回的对象里面的数据,渲染到template中,就需要借助Mustache语法来实现,使用双大括号"{{}}"标记来实现文本插值,并且在前面也说过,data返回的对象,是有添加到Vue的响应式系统里面的,所以当data返回的对象里面的数据发生改变时,对应的内容也会随之更新;
    当然,Mustache插值语法不仅可以用来表示data对应函数返回对象中的属性,也可以是一个JavaScript表达式;
文本插值
    文本插值很简单,无非就是使用"{{}}"标记,来表示data对应的函数返回的对象内的内容,它会被Mustache模版引擎所解析,并且,在这个"{{}}"标记内部,使用表达式,来包装我们的值,比如三元运算符、加减法、对象方法等,甚至在"{{}}"标记内部还可以直接使用methods里面的函数,如下示例;
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
<div id="box">
    <h1>我的名字叫{{ name.toUpperCase() }},年龄为{{ age + 1 }},是一个{{ checkAge(age) }}</h1> <!-- 直接传入age,Mustache引擎会自动解析 -->
</div>
<script>
    Vue.createApp({
        data() {
            return {
                name: "cce",
                age: 26
            }
        },
        methods: {
            checkAge(age) {
                if (age > 18) {
                    return "成年人"
                } else {
                    return "未成年人"
                }
            }
        }
    }).mount("#box")
</script>

模版指令
    在Vue的模版语言中,也有很多的模版指令,不同的指令分别实现不同的功能,这些指令都是和属性放在同一个位置的,换句话说,这些指令都是HTML标签的一个属性,模版引擎渲染时,会去关注这些指令,然后根据指令的类型来实现不同的功能;
静态渲染指令(v-once)
    因为Vue是动态渲染的,一旦data对应函数返回的对象里面的值发生了变化,就会立即渲染到页面上来,那么如果我们不希望立即渲染到页面上来,而只是在刷新或者重新打开页面的时候,才会重新渲染到页面上来,那么这个时候就需要用到静态渲染指令,这里需要注意的是,如果父节点加入了静态渲染指令,那么子节点也将全部值渲染一次;
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
<div id="box">
    <p v-once>老数据:{{ number }}</p>
    <p>新数据:{{ number }}</p>
    <button v-on:click="change">自加</button>
</div>
<script>
    Vue.createApp({
        data() {
            return {
                number: 1
            }
        },
        methods: {
            change() {
                this.number++
            }
        }
    }).mount("#box")
</script>

文本指令(v-text)
    如果我们希望将data里面的数据,渲染到页面上,除了使用Mustache插值语法,还可以使用v-text文本指令,直接将指定标签的内容覆盖为指定的值,需要注意的是,它会覆盖当前值;
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
<div id="box">
    <p v-text="text">p标签</p>
</div>
<script>
    Vue.createApp({
        data() {
            return {
                text: "v-text"
            }
        }
    }).mount("#box")
</script>

HTML指令(v-html)
    如果我们希望直接将HTML文本插入到指定标签内部,可以直接使用v-html指令,同样的,这里需注意,它会覆盖原有的内容;
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
<div id="box">
    <p v-html="html">p标签</p>
</div>
<script>
    Vue.createApp({
        data() {
            return {
                html: "<h1>v-html</h1>"
            }
        }
    }).mount("#box")
</script>

原始值(v-pre)
    因为在Vue模版中,使用"{{}}"标记,会直接被模版引擎替换,这是模版引擎做的操作,如果我们就是想显示"{{ var }}",并不想它被模版引擎解析,那么这个时候,我们就可以使用v-pre,来告知模版引擎这个标签中的内容,不要解析;
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
<div id="box">
    <p v-pre>{{name}}</p>
</div>
<script>
    Vue.createApp({
        data() {
            return {
                name: "cce"
            }
        }
    }).mount("#box")
</script>

防插值闪烁(v-cloak)
    当网速比较慢时,会出现一个不好的过度现象,会让用户先看到我们的表达式,比如,首先会看到{{ var }},然后才看到data中的值,这就是所谓的插值闪烁问题,那么Vue为了防止这种问题产生带来的用户体验问题,就提供了一个v-cloak的指令来解决,在未成功渲染插值语法之前,先隐藏这个属性;
    但是,如果想要实现这个效果,还必须配合一个css样式来实现,如下css为固定写法;
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
<style>
    [v-cloak] {
        display: none;
    }
</style>
<div id="box">
    <p v-cloak>{{ name }}</p>
</div>
<script>
    Vue.createApp({
        data() {
            return {
                name: "cce"
            }
        }
    }).mount("#box")
</script>

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注