Vue【JavaScript 框架】

目录

Vue

简介

MVVM

简单使用

数据单项渲染 【v-bind】

数据双向绑定【v-model】

事件绑定

修饰符

条件渲染【v-if / v-show】

列表渲染

组件化编程

全局组件

 局部组件

生命周期和监听函数(钩子函数)


Vue

简介

1. Vue是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任

2. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合

3. 支持和其它类库结合使用

4. Vue 是 Vue.js 的简称(也就是说它就是一个js库文件)

官网: https://cn.vuejs.org/

git地址:https://github.com/vuejs


MVVM

· M∶Model,模型,包括数据和一些基本操作

· V∶View,视图,页面渲染结果

· VM∶View-Model,模型与视图间的双向操作

MVVM与传统前端开发的区别:

        在 MVVM之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染到View 中。而后当用户操作视图,我们还需要通过 DOM获取 View 中的数据, 然后同步到Model 中。而 MVVM中的VM 要做的事情就是把DOM 操作完全封装起来,开发人员不用再关心 Model 和View 之间是如何互相影响的。

        只要 Model 发生了改变,View上自然就会表现出来

        当用户修改了View,Model 中的数据也会跟着改变

结果:把开发人员从繁琐的 DOM操作中解放出来,把关注点放在如何操作 Model上, 大大提高开发效率。


简单使用

Vue2 官方文档:https://cn.vuejs.org/v2/guide/index.html

为了让 IDEA 识别 Vue 代码,需要安装插件 Vue.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<div id = "app">
    <h1>hi! {{name}}</h1>
</div>

<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            name: "jack"
        }
    })
</script>


</body>
</html>

运行结果:

由上例可知:Vue 没有繁琐的 DOM 操作,如果使用 jQuery,我们需要先找到 div 节点,获取到 DOM 对象,然后进行节点操作, 显然 Vue 更加简洁


数据单项渲染 【v-bind

v-bind 指令:v-bind: " 【可简写为" : "】

简单示例:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<div id = "app">
    <!--1. 使用插值表达式引用 data数据池数据是在标签体内-->
    <h1>hi! {{name}}</h1>
    <!--2. 如果是在标签/元素 的属性上去引用data数据池数据时,不能使用插值表达式-->
    <!--3. 需要使用v-bind, 因为v-bind是vue来解析, 默认报红,但是不影响解析-->
    <!--4. 如果不希望看到报红, 直接 alt+enter 引入 xmlns:v-bind-->
    <img v-bind:src="img_path" v-bind:width="img_width">
    <!--5. 可以不写 v-bind 简写为如下形式-->
    <img :src="img_path" :width="img_width">
</div>

<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            name: "hzw",
            img_path: "hz03.jpg",
            img_width: "200px"
        }
    })

    // 如果想观察其具体结构,可以控制台输出查看
    console.log("vm=>", vm);
</script>


</body>
</html>

运行结果: 


数据双向绑定【v-model

v-model 可以完成双向数据绑定
简单示例:
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>

<div id = "app">
    <h1>{{message}}</h1>

    <!--v-model="hobby.val" 是数据的双向渲染,-->
    <!--(1)data数据池绑定的数据变化,会影响view 【底层的机制是 Data Bindings】-->
    <!--(2)view关联的的元素值变化, 会影响到data数据池的数据【底层机制是Dom Listeners】-->
    
    <!--下面三处的值都来自 data数据池-->
    <input type="text" v-model="name"><br/><br/>
    <input type="text" :value="name"><br/><br/>
    <h1>hi~ {{name}}</h1>
</div>

<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            message: "尾部名字随输入值变化",
            name: "jack",
        }
    })

    // 如果想观察其具体结构,可以控制台输出查看
    console.log("vm=>", vm);
</script>


</body>
</html>
运行结果:

事件绑定

1. 使用 v-on 进行事件处理,比如: v-on:click 表示处理鼠标点击事件

2. 事件调用的方法定义在 vue 对象声明的 methods 节点中

简单示例:

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>事件处理</title>
</head>
<body>

<div id="app">
    <!--
    1. v-on:click 表示我们要给button元素绑定一个click的事件
    2. sayHi() 表示绑定的方法, 在方法池 methods{} 定义的
    3. 底层仍然是dom处理
    -->
    <button v-on:click="sayHi()">点击输出</button>
    <button v-on:click="sayOk()">点击输出</button>

    <!--4. 如果方法不需要传递参数,可以省略()-->
    <!--5. v-on:click可以简写@, 但是需要浏览器支持-->
    <button v-on:click="sayHi">点击输出</button>
    <button @click="sayOk">点击输出</button>
</div>

<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        // 1. methods属性, 对应的值是对象{}
        // 2. 在{} 中, 可以写很多的方法, 可以理解为一个方法池
        methods: {
            sayHi() {
                console.log("sayHi。。。");
            },
            sayOk() {
                console.log("sayOk。。。");
            }
        }
    })
</script>
</body>
</html>

运行结果:


修饰符

1. 修饰符 (Modifiers) 是以(.)指明的后缀,指出某个指令以特殊方式绑定。

2. 事件修饰符

.stop 阻止事件继续传播

.prevent 阻止标签默认行为

.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理

.self 只当在 event.target 是当前元素自身时触发处理函数

.once 事件将只会触发一次

.passive 告诉浏览器你不想阻止事件的默认行为

3. 键盘事件的修饰符

例如: 项目经常需要监听一些键盘事件来触发程序的执行,而 Vue 中允许在监听的时候添加关键修饰符

<input v-on:keyup.13="submit">

4. v-model 的修饰符

例如: 自动过滤用户输入的首尾空格 <input v-model.trim="msg">

总之,修饰符 (Modifiers) 是以(.)指明的后缀,指出某个指令以特殊方式绑定

简单示例:

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Vue修饰符使用</title>
</head>
<body>
<div id="app">

    <!--1. v-on:submit.prevent的.prevent 修饰符-->
    <!--表示阻止表单提交的默认行为而去程序员指定的方法-->
    <!--2. 如果没有 v-on:submit.prevent 这段代码,表单则会提交到百度-->
    <form action="http://www.baidu.com" v-on:submit.prevent="onMySubmit">
        姓名: <input type="text" v-model="name"><br/><br/>
        <button type="submit">注册</button>
    </form>

</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {//数据池
            name: "jack"
        },
        methods: {//方法池
            onMySubmit() {
                alert("输入的姓名 "+ this.name +" 来到了这里")
            }
        }
    })
</script>
</body>
</html>

运行结果:


条件渲染【v-if / v-show】

还是直接查文档比较快

官方文档:https://v2.cn.vuejs.org/v2/guide/conditional.html


列表渲染

官方文档:https://v2.cn.vuejs.org/v2/guide/list.html


组件化编程

        在大型应用开发的时候,页面可以划分成很多部分,往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航等。 但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。

1、组件(Component) 是 Vue.js 最强大的功能之一,可以提高复用性

2、组件也是一个Vue实例,也包括∶ data、methods、生命周期函数等

3、组件渲染需要 html模板,所以增加了template 属性,值就是 HTML 模板

4、对于全局组件,任何vue 实例都可以直接在 HTML 中通过组件名称来使用组件

5、在组件中data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据

全局组件

简单示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件化编程-全局组件</title>
</head>
<body>
<div id="app">
    <h1>组件化编程-全局组件-app</h1>
    <!--使用全局组件-->
    <counter></counter>
    <counter></counter>
    <counter></counter>
    <counter></counter>
    <counter></counter>
</div>

<div id="app2">
    <h1>组件化编程-全局组件-app2</h1>
    <!--使用全局组件-->
    <counter></counter>
    <counter></counter>
</div>
<script src="vue.js"></script>
<script>
    //1、定义一个全局组件, 名称为 counter
    //2. {} 表示就是我们的组件相关的内容
    //3. template 指定该组件的界面, 因为会引用到数据池的数据,所以需要是模板字符串
    //4. 说明: 要把组件视为一个Vue实例,也有自己的数据池和methods
    //5. 说明: 对于组件,我们的数据池的数据,是使用函数/方法返回[目的是为了保证每个组件的数据是独立], 不能使用原来的方式
    //6. 这时,界面通过template实现共享,业务处理也复用
    //7. 全局组件是属于所有vue实例,因此,可以在所有的vue实例使用
    Vue.component("counter", {
        template: `<button v-on:click="click()">点击次数= {{count}} 次【全局组件化】</button>`,
        data() { //数据池的数据,是使用函数/方法返回
            return {
                count: 0
            }
        },
        methods: {
            click() {
                this.count++;
            }
        }
    })
    //创建Vue实例,必须有
    let vm = new Vue({
        el: "#app"//Vue实例的挂载点
    })

    let vm2 =  new Vue({
        el: "#app2"//Vue实例的挂载点
    })


</script>
</body>
</html>

运行结果:

 局部组件

简单示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件化编程-局部组件</title>
</head>
<body>
<div id="app">
    <h1>组件化编程-局部组件</h1>
    <!--使用局部组件 ,该组件是从挂载到app的vue中的组件中获取的-->
    <my_counter></my_counter><br/>
    <my_counter></my_counter><br/>
    <my_counter></my_counter><br/>
</div>

<div id="app2">
    <h1>组件化编程-局部组件-app2</h1>
    <!--使用局部组件 -->
    <my_counter2></my_counter2><br/>
    <my_counter2></my_counter2><br/>
</div>
<script src="vue.js"></script>
<script>

    //定义一个组件, 组件的名称为 buttonCounter
    //扩展
    //1. 可以把常用的组件,定义在某个 js文件 中 export 引出使用
    //2. 如果某个页面需要使用, 直接 import 引入使用
    const buttonCounter = {
        template: `<button v-on:click="click()">点击次数= {{count}} 次【局部组件化】</button>`,
        data() {
            return {
                count: 0
            }
        },
        methods: {
            click() {
                this.count++;
            }
        }
    }

    //创建Vue实例,必须有
    let vm = new Vue({
        el: "#app",//Vue实例的挂载点
        components: { //引入/注册某个组件, 此时my_counter就是一个局部组件,它的使用范围为当前vue
            'my_counter': buttonCounter
        }
    })

    let vm2 = new Vue({
        el: "#app2",//Vue实例的挂载点
        components :{//引入/注册组件buttonCounter
            'my_counter2': buttonCounter
        }
    })


</script>
</body>
</html>

运行结果:


 

生命周期和监听函数(钩子函数)

1. Vue 实例有一个完整的生命周期,即从开始创建、初始化数据、编译模板、挂载DOM、渲染-更新-渲染、卸载等一系列过程,我们称为 Vue 实例的生命周期。

2. 钩子函数(监听函数):Vue 实例在完整的生命周期过程中(比如设置数据监听、编译模板、将实例挂载到 DOM 、在数据变化时更新 DOM 等),也会运行叫做生命周期钩子的函数。

3. 钩子函数的作用就是在某个阶段, 给程序员一个对页面数据做某些处理的机会。

vue生命周期图

 

上图解读如下: 

1) new Vue()

new 了一个 Vue 的实例对象,此时就会进入组件的创建过程

2) Init Events & Lifecycle

初始化组件的事件和生命周期函数

3) beforeCreate

组件创建之后遇到的第一个生命周期函数,在这个阶段 data 和methods 以及 DOM 结构都未被初始化,也就是获取不到 data 的值,不能调用 methods 中的函数

4) Init injections & reactivity

在这个阶段中, 正在初始化 data 和 methods 中的函数

5) created

在这个阶段组件的 data 和 methods 中的方法已初始化结束,可以访问,但是 DOM 结构未初始化,页面还未渲染

注意:在这个阶段,经常会发起 Ajax 请求

6) 编译模板结构(在内存)

7) beforeMount

当模板在内存中编译完成,此时内存中的模板结构还未渲染至页面上,看不到真实的数据

8) Create vm.$el and replace ‘el’ with it

在这个阶段中, 再在把内存中渲染好的模板结构替换至真实的 dom 结构也就是页面上

9) mounted

此时,页面渲染好,用户看到的是真实的页面数据,生命周期创建阶段完毕,进入到了运行中的阶段

10) 生命周期运行中

10.1) beforeUpdate

当执行此函数,数据池的数据新的,但是页面还是旧的

10.2) Virtual DOM re-render and patch

根据最新的 data 数据,重新渲染内存中的模板结构,并把渲染好的模板结构,替换至页面上

10.3) updated

页面已经完成了更新,此时,data 数据和页面的数据都是新的

11) beforeDestroy

当执行此函数时,组件即将被销毁,但是还没有真正开始销毁,此时组件的 data、methods数据或方法还可被调用

12) Teardown……

注销组件和事件监听

13) destroyed

组件已经完成了销毁

其中比较常用的为以下6个函数

        beforeCreate

        created

        beforeMount

        mounted

        beforeUpdate

        updated

简单示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--这里可以视为用户看到的页面-即DOM页面-->
<div id="app">
    <span id="num">{{num}}</span>
    <button @click="num++">赞!</button>
    <h2>{{name}},有{{num}}次点赞</h2>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {//数据池
            name: "jack",
            num: 0
        },
        methods: {
            show() {
                return this.name;
            },
            add() {
                this.num++;
            }
        },
        beforeCreate() {//生命周期函数-创建vue实例前
            console.log("=============beforeCreate==========");
            console.log("数据模型/数据池的数据是否加载/使用?[no]", this.name, " ", this.num);
            //console.log("自定义方法是否加载/使用?[no]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
        },
        created() {//生命周期函数-创建vue实例
            console.log("=============created==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);
            //此时可以发出Ajax
            //接收返回的数据
            //再次去更新data数据池的数据
            //编译内存模板结构
            //.....

        },
        beforeMount() {//生命周期函数-挂载前
            console.log("=============beforeMount==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[no]", document.getElementById("num").innerText);

        },
        mounted() {//生命周期函数-挂载后
            console.log("=============mounted==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom是否被渲染?[yes]", document.getElementById("num").innerText);

        },
        beforeUpdate() {//生命周期函数-数据池数据更新前
            console.log("=============beforeUpdate==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom数据是否被更新?[no]", document.getElementById("num").innerText);
            //在此时可以根据需求添加一些 验证、修正数据的功能
            //例如:
            // if(this.num < 10 ) {
            //     this.num = 8;
            // }
        },
        updated() {//生命周期函数-数据池数据更新后
            console.log("=============updated==========");
            console.log("数据模型/数据池的数据是否加载/使用?[yes]", this.name, " ", this.num);
            console.log("自定义方法是否加载/使用?[yes]", this.show());
            console.log("用户页面dom是否加载/使用?[yes]", document.getElementById("num"));
            console.log("用户页面dom数据是否被更新?[yes]", document.getElementById("num").innerText);

        }

    })
</script>
</body>
</html>

运行结果:

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值