Vue笔记之入门

一、 Vue概念

  • Vue是一个结合了React的虚拟DOM和Angular的模块化开发的一个渐进式js框架
  • 渐进式是指先使用vue核心库,在vue核心库的基础上,根据自己需要再去逐渐增加功能
  • 其核心是只专注于视图层,实现了后端的mvc
  • Vue的官网:Vue.js

1.1 MVVM的概念

  • MVVM(Model-View-ViewModel)是一种软件架构模式,是一种简化用户界面的事件驱动编程方式。

  • MVVM源自于经典的MVC(Model-View-Controller)模式,MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下

    • 该层向上与视图层进行双向数据绑定
    • 向下与Model层通过接口请求进行数据交互
      在这里插入图片描述
  • 当下流行的MVVM框架有Vue.js、Angular.js。

1.2 MVVM的优点

MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model)

  • **低耦合:**视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可复用:你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
  • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
  • 可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。

1.3 Vue的优点

  • 轻量级, 体积小是一个重要指标。Vue.js压缩后有只有20多kb(Angular压缩后56kb+,React压缩后44kb+)
  • 移动优先。更适合移动端, 比如移动端的Touch事件
  • 易上手,学习曲线平稳,文档齐全
  • 吸取了Angular(模块化) 和React(虚拟DOM) 的长处, 并拥有自己独特的功能,如:计算属性
  • 开源,社区活跃度高

1.4 引入

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<!-- 脚手架创建 -->
npm install  @vue/cli -g
<!-- 创建项目 -->
vue create app

1.5 Vue入门

<div id='app'>
  {{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
  var app = new Vue({
    el: '#app', //绑定元素的ID
    data: {     //数据对象
      message: 'Hello Vue!'
    }
  })
</script>

二、Vue的基本语法

2.1 Vue的生命周期

在这里插入图片描述

  1. 概念

    Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

  2. 作用

    Vue生命周期中有多个事件钩子,让我们在控制整个Vue实例过程时更容易形成好的逻辑。

  3. 阶段

    可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/后。

    • 第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
    • DOM 渲染在 mounted 中就已经完成了。
    • 生命周期钩子的一些使用方法:
      • beforecreate : 可以在此阶段加loading事件,在加载实例时触发;
      • created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用;
      • mounted : 挂载元素,获取到DOM节点;
      • updated : 如果对数据统一处理,在这里写上相应函数;
      • beforeDestroy : 可以做一个确认停止事件的确认框;
      • nextTick : 更新数据后立即操作dom;

2.2 钩子函数

  1. 概念
    钩子函数,其实就是Vue提前定义好的时间,其作用类似与Servlet中的init和distory方法

  2. 语法

    <script type="text/javascript">
        var app = new Vue({
            el:"#app",
            //钩子函数created,该方法在页面显示之后,自动执行
            created() {
                console.log("created...");
            }
        });
    </script>
    

2.3 插值表达式

  1. 概述
    插值表达式用户把Vue中所定义的数据,显示在页面中,插值表达式允许用户输入"JS代码片段"

  2. 语法
    {{ 变量名/对象.属性名 }}

  3. 案例

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue插值表达式</title>
        <script src="node_modules/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <h1>欢迎来到-->{{ name }}</h1>
        </div>
        <script type="text/javascript">
            //创建vue对象
            var app = new Vue({
                //让vue接管div标签
                el:"#app",
                //定义数据,里边包含一个属性name,值为"白大锅"
                data:{
                    name:"白大锅"
                }
            });
        </script>
    </body>
    </html>
    

2.4 显示数据(v-text和v-html)

  1. 概述
    v-text和v-html专门用来展示数据,其作用和插值表达式类似。v-text和v-html可以避免插值闪烁。

    插值闪烁:在数据未加载完成时,页面会显示原始的{{}},过一会才显示正常数据。

  2. 语法

    v-text:<span v-text="msg"></span><!-- 相当于<span>{{msg}}</span> -->
    v-html:<span v-html="msg"></span><!-- 相当于<span>{{msg}}</span> -->
    
  3. 区别

    • v-text:把数据当作纯文本显示
    • v-html:遇到html标签,会正常解析

2.5 判断语法(v-if和v-show)

  1. 概述

    • v-if与v-show可以根据条件的结果,来决定是否显示指定内容
    • v-if:条件不满足时,元素不会存在
    • v-show:条件不满足时,元素不会显示(但仍然存在)
  2. 案例

    <div id="app">
    	<button @click="show = !show">点我</button>
    	<h1 v-if="show">Hello v-if.</h1>
        <h1 v-show="show">Hello v-show.</h1>
    </div>
    <script>
        var app = new Vue({
            el:"#app",
            data: {
            	show:true
            }
        });
    </script>
    

2.6 事件处理(v-on)

  1. 概述
    Vue中也可以给页面元素绑定事件

  2. 语法

    <!--完整写法-->
    <button v-on:事件名="函数名/vue表达式">点我</button>
    <!--简化写法-->
    <button @事件名="函数名/vue表达式">点我</button>
    
  3. 注意

    Vue支持html中所有已知事件,如:@click,@submit等,只不过事件的名称不带on

  4. 案例

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue事件处理</title>
        <script src="node_modules/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <button @click="show">点我</button>
        </div>
        <script type="text/javascript">
            //创建vue对象
            var app = new Vue({
                //获取id为app的元素,该元素被vue对象所管理.只有被vue对象管理的标签,其内部才允许书写vue语法
                el:"#app",
                //定义vue的方法
                methods:{
                    //定义show方法,弹出提示框
                    show() {
                        alert("Hello Vue!!!");
                    }
                }
            });
        </script>
    </body>
    </html>
    
  5. 事件修饰符
    事件修饰符主要对事件的发生范围进行限定

  6. 语法:

    <button @事件名.事件修饰符="函数名/vue表达式">点我</button>
    事件修饰符:
    .stop :阻止事件冒泡, 也就是当前元素发生事件,但当前元素的父元素不发生该事件
    .prevent :阻止默认事件发生
    .capture :使用事件捕获模式, 主动获取子元素发生事件, 把获取到的事件当自己的事件执行
    .self :只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
    .once :只执行一次
    

2.7 循环遍历(v-for)

2.9.1 遍历数组

  1. 语法

    v-for="item in items"
    v-for="(item,index) in items"
    

    items:要遍历的数组
    item:存储数组元素的变量名
    index:迭代到的当前元素索引,从0开始

  2. 代码

    <div id="app">
    	<ul>
            <li v-for="(user, index) in users">
            	{{index}}--{{user.name}}--{{user.age}}--{{user.gender}}
            </li>
    	</ul>
    </div>
    <script>
        var app = new Vue({
            el:"#app",//el即element,要渲染的页面元素
            data: {
                users:[
                    {"name":"白卓冉","age":8,"gender":"男"},
                    {"name":"白大锅","age":12,"gender":"女"},
                    {"name":"白仙女","age":4,"gender":"男"}
                ]
            }
        });
    </script>
    

2.9.2 遍历对象

  1. 语法
    v-for="value in object"
    v-for="(value,key) in object"
    v-for="(value,key,index) in object"
    
    value:对象的值
    key:对象的键
    index:索引,从0开始
  2. 代码
    <div id="app">
    	<ul>
            <li v-for="(value,key,index) in person">
            	{{index}}--{{key}}--{{value}}
            </li>
    	</ul>
    </div>
    <script>
        var app = new Vue({
            el:"#app",//el即element,要渲染的页面元素
            data: {
                person:{"name":"白大锅", "age":3, "address":"中国"}
            }
        });
    </script>
    

2.9.3 key

  1. 概述
    :key一般配合v-for一起使用,用在特定的情况下,保证被遍历数组中的元素的顺序

  2. 案例

    <div id="app">
        <button @click="add">添加</button>
        <ul>
            <li v-for="name in list">
                <input type="checkbox"> {{name}}
            </li>
        </ul>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                list: ["孙悟空", "猪八戒", "沙和尚"]
            },
            methods: {
                add() {
                    //注意这里是unshift,向数组的头部添加一个元素
                    this.list.unshift("唐僧");
                }
            }
        });
    </script>
    

    在这里插入图片描述

  3. 点击添加后
    在这里插入图片描述

  4. 解决方案:

    <div id="app">
        <button @click="add">添加</button>
        <ul>
            <!-- 添加:key即可. 注意,key中的值必须是唯一且不会改变的值-->
            <li v-for="name in list" :key="name">
                <input type="checkbox"> {{name}}
            </li>
        </ul>
    </div>
    

三、Vue的绑定和其他语法

3.1 数据的绑定(v-bind和v-model)

  1. 概述

    • 单向绑定(v-bind):数据只能从data流向页面
    • 双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data
  2. 语法

    <!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>数据绑定</title>
        <script src="../js/vue.js"></script>
    </head>
    <body>
        <div id="root">
            单向数据绑定:<input type="text" v-bind:value="name"><br>
            双向数据绑定:<input type="text" v-model:value="name">
        </div>
    
        <script>
            Vue.config.productionTip = false 
            new Vue({
                el:'#root', 
                data:{
                    name:'JOJO'
                }
            })
        </script>
    </body>
    </html>
    
  3. 注意:

    1. 双向绑定一般都应用在表单类元素上(如input、select、textarea等)
    2. v-model : value 可以简写为v-model ,因为v-model默认收集的就是value值
    3. v-bind:value可以简写为 : value
    4. 双向绑定文本框/单选按钮/textarea,绑定的数据都是字符串,单个复选框,绑定的是boolean类型,多个复选框,绑定的是数组,select单选对应字符串,多选对应的也是数组

3.2 计算属性

  1. 概述
    计算属性就是一个提前定义好的方法, 该方法可以看作是一个特殊的值, 可以在插值表达式中使用

  2. 语法

     var app = new Vue({
         el:"#app",
         //计算属性必须放在Vue的computed中
         computed:{
             //定义计算属性
             属性名(){
                 return "返回值";
             }
         }
    });
    
  3. 案例

    <div id="app">
        <h1>{{birth}}</h1>
        <h1 v-text="birth"></h1>
        <h1 v-html="birth"></h1>
    </div>
    <script type="text/javascript">
        var app = new Vue({
            el:"#app",
            computed:{
                //定义一个birth方法,该方法就是一个计算属性,可以在插值表达式中使用
                birth(){
                    let date = new Date();
                    let year = date.getFullYear();
                    let month = date.getMonth()+1;
                    let day = date.getDay();
                    return year + "-" + month + "-" + day;
                }
            }
        });
    </script>
    

3.3 watch监控

  1. 概述

    • watch可以监听简单属性值及其对象中属性值的变化
    • watch类似于onchange事件,可以在属性值修改的时候,执行某些操作
  2. 语法

    <script type="text/javascript">
    var app = new Vue({
        el:"#app",
        data:{
            message:"白大锅",
            person:{"name":"heima", "age":13}
        },
        //watch监听
        watch:{
            //监听message属性值,newValue代表新值,oldValue代表旧值
            message(newValue, oldValue){
            	console.log("新值:" + newValue + ";旧值:" + oldValue);
            },
            //监控person对象的值,对象的监控只能获取新值
            person: {
                //开启深度监控;监控对象中的属性值变化
                deep: true,
                //获取到对象的最新属性数据(obj代表新对象)
                handler(obj){
                    console.log("name = " + obj.name + "; age=" + obj.age);
                }
            }
        }
    });
    </script>
    

3.4 插槽(slot)

  1. 概念
    将父组件利用 插槽 将结构传送到子组件中

  2. 插槽的本质:
    是组件标签中间传递结构,实现公共代码的提取

  3. 语法

    //父组件
    < 组件名>
        //传输 结构/数据
        <p>数据</p>
    </ 组件名>
    //子组件
    <slot>接收结构/数据</slot>
    
  4. 案例:

    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta charset="UTF-8">
    		<title>Vue插槽</title>
    	</head>
    	<body>
    		<div id="el">
    			<my-div>
    				<my-title slot="my-title" :title="tle"></my-title>
    				<my-item slot="my-item" v-for="(item,index) in list" :item="item" :index="index"></my-item>
    			</my-div>
    		</div>
    	<script src=" https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    	<script>
    		Vue.component("my-div", {
    			template: ` <div>
    							<slot name='my-title'></slot>
    							<ul>
    								<slot name='my-item'></slot>
    							</ul>
    						</div>`
    				
    		});
    		Vue.component('my-title', {
    			props: ['title'],
    			template: `<div>{{title}}</div>`
    		});
    		Vue.component("my-item", {
    			props: ["item", "index"],
    			template: "<li>{{index+1}},{{item}}</li>"
    		});
    		var vm = new Vue({
    			el: "#el",
    			data() {
    				return {
    					tle: "前端基础课程",
    					list: ['HTML', 'CSS', 'JavaScript']
    				}
    			}
    		})
    	</script>
    	</body>
    </html>
    
  5. 图解
    在这里插入图片描述

四、Vue组件

4.1 基本使用

  1. 概述
    组件类似于模板,模块。在项目需要重用某个模块(头部、尾部、导航…)的时候,可以将模块抽取成组件,其他页面中注册组件并引用。

  2. 案例

    <div id="app">
        <!--使用组件(组件名称),如果组件名称中有大写字母,如"myList",则这里需要书写<my-list>-->
        <counter></counter>
        <counter></counter>
    </div>
    <script type="text/javascript">
        //定义组件
        const counterTemp = {
            //定义组件的模版
            template:`<button @click='num++'>你点击了{{num}}次</button>`,
            //定义组件中使用到的数据属性
            data(){
               return {
                  num:0
               }
            } 
        };    
    
        //全局注册组件:在所有的vue实例中都可以使用组件
        //参数1:组件名称,参数2:具体的组件
        //Vue.component("counter", counterTemp);
        
        var app = new Vue({
            el:"#app",
            //局部注册组件: 只能在当前Vue实例中使用
            components:{
                //组件名称:具体组件
                counter: counterTemp
            }
        });
    </script>
    
  3. 注意

    • 组件的模块中,只能书写一个跟标签
    • 组件的定义必须放在Vue创建对象之前,否则报错

4.2 父组件向子组件通信

  1. 概述
    子组件无法直接使用父组件中的数据, 如果需要使用, 则必须由父组件把数据传递给子组件才可以

  2. 本质:
    让子组件中的属性与父组件中的属性进行关联绑定, 然后子组件使用该属性, 这样才能做到数据传递

  3. 意义
    可以把父组件中的数据, 更新传递到子组件

  4. 示例

    <div id="app">
         <!-- 把父组件中的count传递给子组件的number属性,把父arr传递给子ids,把父p传递给子person -->
        <aaa :number="count" :ids="arr" :person="p"></aaa>
    </div>
    
    <script>
        var aaa = {
            //定义组件的模版
            template: `<h2>{{num}}---{{number}}--{{ids}}--{{person}}</h2>`,
            //定义组件中使用到的数据属性
            data() {
                return {
                    num: 0
                }
            },
            //给组件添加属性
            props: {
                //普通属性number
                number: "",
                //数组属性ids
                ids: [],
                //对象属性person
                person: {}
                /*
                *	//以上属性还可以书写为以下格式
                *	items:{
                *        //数据类型,如果是数组则是Array,如果是对象则是Object
                *       type:Array,
                *       //默认值
                *       default:[]
                *	}
                */
            }
        };
    
        //注册:全局注册
        Vue.component("aaa", aaa);
    
        var app = new Vue({
            el: "#app",
            data: {
                count: 5,
                arr: [1, 2, 3],
                p: {username: "zhangsan", age: 23}
            }
        });
    </script>
    

4.3 子组件向父组件通信

  1. 概述
    子组件无法直接给父组件传递数据. 也无法操作父组件中的数据, 更无法调用父组件中的方法。所以, 所谓的子组件向父组件通讯, 其实就是想办法让子组件调用父组件的方法. 进而响应到父组件中的数据。

  2. 意义
    子组件可以调用父组件中的方法

  3. 示例

    <div id="app">
        <h1>父组件中:app_num={{app_num}}</h1>
        <!-- 把父组件的add方法,绑定给子组件的aaa属性,绑定方法使用@属性名="方法名" -->
        <!-- 把父组件的rem方法,绑定给子组件的bbb属性,绑定方法使用@属性名="方法名 -->
        <!-- 把父组件的app_num变量,绑定给子组件的counter_num属性,绑定变量使用:属性名="方法名 -->
        <counter @aaa="add" @bbb="rem" :counter_num="app_num"></counter>
    </div>
    
    <script>
        //定义一个组件(模版)
        let counter = {
            template: `
                 <div>
                       <h1>子组件中:counter_num={{counter_num}}</h1>
                       <input type="button" @click="fun1" value="+"/>
                       <input type="button" @click="fun2" value="-"/>
                </div>
                    `,
            props:{
                //定义属性counter_num,用来接收父组件传递的数据
                counter_num:null,
                //定义aaa属性,用来绑定父组件的方法,当然,该定义也可以省略
                aaa:function(){},
                //定义bbb属性,用来绑定父组件的方法,当然,该定义也可以省略
                bbb:function(){},
            },       
            methods:{
                fun1(){
                    //找到aaa属性所绑定的那个方法,执行那个方法
                    return this.$emit("aaa");
                },
                fun2(){
                    //找到bbb属性所绑定的那个方法,执行那个方法
                    return this.$emit("bbb");
                }
            }
        }
    
        var app = new Vue({
            el: '#app',
            data: {
                app_num: 0
            },
            components: {
                counter
            },
            methods:{
                add(){
                    this.app_num++;
                },
                rem(){
                    this.app_num--;
                }
            }
        });
    </script>
    

五、axios异步请求

5.1 axios概述

  1. 概述
    axios是一个基于promise的HTTP库,主要用于:发送异步请求获取数据

  2. 常见的方法
    axios(config)
    axios.get(url,[config])
    axios.post(url,[data])

  3. 发送数据config常用参数

    {
        url: '请求的服务器',
    	method: '请求方式', // 默认是 get
        // GET请求参数
        params: {
        	参数名: 参数值
        },
    	// POST请求参数, 如果使用axios.post,则参数在url之后直接书写,不需要该位置传递参数
        data: {
        	参数名: 参数值
        },
    	// 响应数据格式,默认json
    	responseType: 'json'
    }
    
    
  4. 响应数据常用参数:

    {
        data: {},		//真正的响应数据(响应体)
        status: 200,	//响应状态码
        statusText: 'OK',	 //响应状态描述
        headers: {},	//响应头
        config: {}		//其他配置信息
    }
    
    

5.2 get请求

var app = new Vue({
    el: "#app",
    data: {
        user: {}
    },
    //当页面加载完毕后
    created() { 
        //发送GET请求axios.get("请求路径",{ config });
       axios.get("请求路径",{
            //get请求参数
            params: {
                name:"zhangsan",
                age:23
            },
            //响应数据格式为"json"
            responseType: 'json'
        }).then(res => {
            //打印响应数据
            console.log(res);
            //把响应数据赋值给Vue中的user属性
            app.user = res.data;
        }).catch(err => {
            //打印响应数据(错误信息)
            console.log(err);
        });
    }
});

5.3 post请求

var app = new Vue({
    el: "#app",
    data: {
        user: {}
    },
    //当页面加载完毕后
    created() { 
        //发送POST请求axios.post("请求路径",{ 参数 });
        axios.post("请求路径",{
                name:"zhangsan",
                age:23
            }).then(res => {
                console.log(res);
                app.user = res.data;
            }).catch(err => {
                console.log(err);
            });
    }
});

5.4 跨域请求

跨域请求:在前端js中如果发送异步请求的话,请求的地址与当前服务器的ip或者端口号不同都是跨域请求.

  • 跨域请求需要在服务提供方, 开启允许跨域请求
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JAVA开发区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值