• Vue


    Vue

    一、Vue概述

    (一)Vue是什么

    Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。Vue 只关注视图层, 采用自底向上增量开发的设计。
    Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
    Vue.JS是优秀的前端 JavaScript 框架

    image

    (二)为什么学习Vue

    随着项目业务场景的复杂,传统模式(html+jquery)已无法满足需求,就出现了Angular/React/Vue等框架
    企业需求、主流框架之一、易用、灵活、高效

    (三)Vue能做什么

    最大程度上解放了 DOM 操作
    单页web项目开发
    传统网站开发

    什么是工具(库)、什么是框架

    1.库(插件):是一种封装好的特定方法集合,对项目的侵入性较小,提供给开发者使用,控制权在使用者手中,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求 (jquery)
    
    2.框架:是一套架构,会基于自身特点向用户提供一套相当完整的解决方案,而且控制权在框架本身;对项目的侵入性较大,使用者要按照框架所规定的某种特定规范进行开发,项目如果需要更换框架,则需要重新架构整个项目
    

    二、Vue核心特征

    ① 解耦视图与数据
    ② M-V-VM模型 关注模型和视图
    M:即Model,模型,包括数据和一些基本操作。
    V:即View,视图,页面渲染结果
    VM:即View-Model,模型和视图间的双向操作
    ③ 双向数据绑定

    (一)MVVM之前

    开发人员从后端获取需要的数据模型,然后要通过DOM操作Model渲染到View中。而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model中

    (二)MVVM之后

    而MVVM中的VM要做的事情就是把DOM操作完全封装起来,开发人员不用再关心Model和View之间是如何互相影响的:

    • 只要我们Model发生了改变,View上自然就会表现出来。
    • 当用户修改了View,Model中的数据也会跟着改变
      把开发人员从繁琐的DOM操作中解放出来,把关注点放在如何操作Model上

    image

    三、Vue入门

    (一)下载安装

    vue是一个前端框架,也是其实是一个js文件,下载vue.js文件并在页面中引入
    vue.js的下载方式:
    ① 可以引入在线的vue.js(公共的CDN服务)
    	<!-- 开发环境版本,包含了用帮助的命令行警告 -->
    	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    	或
    	<!-- 生产环境版本,优化了尺寸和速度 -->
    	<script src="https://cdn.jsdelivr.net/npm/vue"></script>
    ② 可以离线下载vue.js
    	开发版本: https://vuejs.org/js/vue.js
    	生产版本: https://vuejs.org/js/vue.min.js
    
    ③ npm包资源管理器,可以下载vue.js  (前端专用)
    	初始化:npm init -y
    	安装vue:npm install vue --save
    	注:切记重启计算机
    

    (二)第一个vue

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
         <div id="app">
             <h2>{{name}},欢迎你!</h2>
         </div>
         <script src="https://cdn.jsdelivr.net/npm/vue"></script>
         <script type="text/javascript">
             //生成一个Vue实例
             var app=new Vue({
                 el:"#app",//el ,即是element。要渲染的页面元素
                 data:{//数据
                     name:"优就业"
                 }
             })
         </script>
    </body>
    </html>
    
    Vue参数详解:
    	1. body中,设置Vue管理的视图<div id="app"></div> 
    	2. 引入vue.js
    	3. 实例化Vue对象 new Vue();
    	4. 设置Vue实例的选项:如el、data...
    		new Vue({选项:值});
    	5. 在<div id='app'></div>中通过{{ }}使用data中的数据
    

    四、Vue常见指令

    指令 (Directives) 是带有 v- 前缀的特殊attribute。是Vue框架提供的语法,扩展了html标签的功能、大部分的指令的值是js的表达式。用于取代DOM操作

    (一)v-textv-html

    类似innerText和innerHTML
    	① v-text:更新标签中的内容
    	② v-html:更新标签中的内容/标签
    案例:
    <!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>v-text、v-html</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        
        <div id="app">
            <!-- 
                插值表达式  {{}}
                v-text  不识别html文本们只能原样输出,直接覆盖原本标签的内容
                v-html  能识别html文本,直接覆盖原本标签的内容
            -->
                <p v-text="a">您好</p>
                <p v-html="b"></p>
                <p v-html="c"></p>
                <p>你好,{{msg}}</p>
        </div>
    </body>
    <script>
    
        let app =  new Vue({
            el:"#app",
            data:{
                msg:"helloworld",
                a:'hi',
                b:'hello',
                c:'<h1>嗨</h1>'
            }
        });
    </script>
    </html>
    

    (二)v-ifv-show

    根据表达式的boolean值进行判断是否渲染该元素
    案例:
    
    <!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>
        <script src="vue.js"></script>
    </head>
    <body>
        <!-- v-if  v-show 都可以用于显示或者隐藏元素 
            区别:
                v-if 使用注释 隐藏元素
                v-show 使用样式 display:none 隐藏元素
        -->
        <div id="app">
            <p v-if="show">{{name}}</p>
            <p v-show="show">{{name}}</p>
        </div>
    </body>
    
    <script>
        let app = new Vue({
            el:"#app",
            data:{
                name:'张三',
                show:true
            }
        })
    </script>
    </html>
    

    (三)v-on

    ① 作用:使用 v-on 指令绑定 DOM 事件,并在事件被触发时执行一些 JavaScript 代码。
    ② 语法:
    	 v-on:事件名.修饰符 = "methods中的方法名";
    	 v-on的简写方法: @事件名.修饰符 = "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>v-on</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <p>当前计数: {{count}}</p>
            <!-- <button type="button" v-on:click="jia()">+</button>
            <button type="button" v-on:click="jian()">-</button> -->
    
            <!-- <button type="button" @click="jia()">+</button>
            <button type="button" @click="jian()">-</button> -->
    
    
            <button type="button" @click="count++">+</button>
            <button type="button" @click="count--">-</button>
        </div>
    </body>
    
    <script>
    
        let app =  new Vue({
           el:"#app",
           data:{
                count:0
           },
           methods:{
                jia(){
                    this.count++;
                },
                jian(){
                    this.count--;
                }
           }
        });
    </script>
    </html>
    

    v-on绑定事件案例:

    image

    练习-显示隐藏

    内容显示时,按钮是隐藏功能。隐藏内容后,按钮是显示功能,显示、隐藏共用一个按钮.

    image

    image

    代码

    <!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>v-on</title>
        <script src="vue.js"></script>
    </head>
    <body>
            <div id="app">
                    <p v-show="condition">你能看见我吗</p>
                    <button @click="change()">{{btn}}</button>
            </div>
    
            
    </body>
    <script>
        let app = new Vue({
            el:"#app",
            data:{
                btn:'隐藏',
                condition:true
            },
            methods:{
                change(){
                   this.btn =  this.btn=="隐藏" ?"显示":"隐藏";
                   this.condition = this.btn=="隐藏"?true:false;
                }
            }
            
        })
    </script>
    </html>
    

    (四)v-for

    ① 作用:列表渲染,当遇到相似的标签结构时,就用v-for去渲染
    ② 格式:
    	    (item,index) in 数组或集合 
    	 	参数item:数组中的每个元素 
    	 	参数index:数组中元素的下标
    
    <!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>v-for</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <!-- 
                遍历固定次数、固定内容
                <p v-for="(item, index) in 100">好好学习,天天向上</p>
             -->
    
    
             <!-- 遍历数组-->
             <p v-for="(stu, index) in stuArr">{{index}}--{{stu.name}}--{{stu.age}}</p>
        </div>
    </body>
    
    <script>
    
        let app =  new Vue({
           el:"#app",
            data:{
                stuArr:[
                    {
                        id:1,
                        name:'张三',
                        age:20
                    },
                    {
                        id:2,
                        name:'李四',
                        age:22
                    },
                    {
                        id:3,
                        name:'王五',
                        age:25
                    }
                ]
            }
        });
    </script>
    </html>
    
    

    (五)v-bind

    ① 作用: 可以绑定标签上的任何属性
    ② 格式:v-bind:属性="值"
    ③ 简写格式::属性="值"
    ④ 属性值一部分进行替换的格式::属性="'常量值' + vue对象data中的数据"
    ⑤ 案例:
    
    <!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>v-bind</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <!-- 如果直接写属性名 , 不认识vue中定义的变量 -->
           <a href="addr">京东</a>
    
           <!-- 通过v-bind绑定的属性,能识别vue中定义的变量、方法-->
           <a v-bind:href="addr">百度</a>
    
           <a :href="addr2">中公</a>
    
           <a :href="'http://'+addr3">淘宝</a>
        </div>
    </body>
    
    <script>
    
        let app =  new Vue({
           el:"#app",
           data:{
                addr:"http://www.baidu.com",
                addr2:"http://www.offcn.com",
                addr3:"www.taobao.com"
           }
        });
    </script>
    </html>
    

    练习-点击换样式

    蓝色

    color:blue;

    border:1px solid blue;

    box-shadow:0px 0px 3px black;

    红色

    color:red;

    border:1px solid red;

    box-shadow:0px 0px 3px black;

    image

    image-20210721201241401

    
    

    (六)v-model

    ① 作用:表单元素的绑定
    ② 特点:双向数据绑定
    	(1)vue对象中的数据发生变化可以更新到界面
    	(2)通过界面可以更改vue对象中数据
    	(3)v-model 会忽略所有表单元素的 value、 checked 、 selected 特性的初始值而总是将 Vue 实 例的数据作为数据来源。应该在data选项中声明初始值。
    ③ 案例:
    
    
    <!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>v-model</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <div id="app">
            
                请输入您的个人信息:
                姓名:<input type="text" v-model="name"  /> 年龄: <input type="text"  v-model="age">  
    
                <hr>
                请核对您的个人信息 <br>
                姓名: {{name}}  <br>
                年龄: {{age}}
        </div>
          
    </body>
    <script>
        let app = new Vue({
            el:"#app",
            data:{
                name:'张三',
                age:20
            }
        })
    </script>
    </html>
    
    

    (七)计算属性

    计算属性可以时刻关注在vue中定义的关联的变量。  当这些关联的变量值发生变化,计算属性也会发生变化.
    
    代码
    
    <!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="app">
            <input type="text" v-model="num1" /> +  <input type="text" v-model="num2" /> 
    
            <p>
                <span>{{num1}}</span>   +    <span>{{num2}}</span>  = <span>{{sum}}</span>
               
            </p>
    
            <p>
                <span>{{num1}}</span>   *    <span>{{num2}}</span>  = <span>{{cheng}}</span>
            </p>
        </div>
    
    </body>
    <script>
    
        const app = new Vue({
            el:'#app',
            data:{
                num1:0,
                num2:0
            },
            computed:{
                sum(){
                   return this.num1*1 + this.num2*1;  
                },
                cheng(){
                    return this.num1 * this.num2;
                }
            }
        });
    </script>
    </html>
    

    image-20210406114151765

    案例说明:

    1.修改数量、移除书籍后,总价会发生变化

    2.当一本书籍都没有了,提示购物车为空,表格消失

    image-20210723114412260

    代码:

    <!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="vue.js"></script>
    </head>
    <body>
        
        <div id="app">
            <table v-show="items.length>0"  width="700" style="text-align: center;" border="1" cellspacing="0" cellpadding="0">
                <tr>
                    <th></th>
                    <th>书籍名称</th>
                    <th>出版日期</th>
                    <th>价格</th>
                    <th>购买数量</th>
                    <th>操作</th>
                </tr>
    
                <tr v-for="(item, index) in items">
                    <td>{{item.id}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.date}}</td>
                    <td>¥{{item.price}}</td>
                    <td><button v-on:click="--item.count">-</button>{{item.count}}<button @click="++item.count">+</button></td>
                    <td><button @click="items.splice(index,1)">移除</button></td>
                </tr>
    
            </table>
            
            <p v-show="items.length>0">总价:¥{{sum}}</p>
    
            <p v-show="items.length==0">购物车为空</p>
        </div>
    </body>
    
    <script>
        let app = new Vue({
            el:'#app',
            data:{
                items:[
                    {id:1,name:'<<算法导论>>',date:'2006-9',price:85,count:1},
                    {id:2,name:'<<UNIX编程艺术>>',date:'20016-2',price:59,count:1},
                    {id:3,name:'<<编程珠玑>>',date:'2003-1',price:39,count:1},
                    {id:4,name:'<<代码大全>>',date:'2012-7',price:128,count:1}
                ]
            },
            methods: {
                jian(book){
                    if(book.count>1)
                        book.count--;
                },
                jia(book){
                    book.count++;
                },
                remove(index){
                    this.items.splice(index,1);
                }
            },
            computed:{
                sum(){
                    let sum = 0;
                    for(let i = 0 ; i < this.items.length;i++){
                       let book =  this.items[i];
                       sum+=book.price * book.count;
                    }
                    return sum;
                }
            }
        });
    </script>
    
    </html>
    

    五、Vue的生命周期

    	每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板等等。Vue为生命周期中的每个状态都设置了钩子函数(监听函数)。每当Vue实例处于不同的生命周期时,对应的函数就会被触发调用。
    

    image

    image

    钩子函数:
    如:created代表在vue实例创建后;我们可以在Vue中定义一个created函数,代表这个时期的构造函数:
    
    

    六、组件

    (一)定义全局组件

    我们通过Vue的component方法来定义一个全局组件。
    Vue.component(组件名,{组件参数})
    <!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>
     <script src="js/vue.js"></script>
    
    
    </head>
    <body>
     <div id="app">
        <con></con>
        <con></con>
     </div>
    </body>
    <script>
    
     let con = Vue.component("con",{
         template:`<div><p>次数{{count}}</p>
         <button type="button" @click="--count">-</button>
         <button type="button" @click="++count">+</button></div>`,
         data(){
            return {
                 count:0
            }
         }
    
     });
     let app = new Vue({
         el:'#app'
    
     })
    </script>
    </html>
    
    特点:
    - 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
    - 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
    - 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
    - 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。
    - data的定义方式比较特殊,必须是一个函数。
    
    注:
    	定义组件要在Vue对象之前声明
    	模板template中只能有一个root(根)
    

    (二)定义局部组件

    	一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。因此,对于一些并不频繁使用的组件,我们会采用局部注册。
    <!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>
        <script src="js/vue.js"></script>
    
    
    </head>
    
    <body>
        <div id="app">
            
        </div>
    
        <div id="app1">
            <con></con>
            <con></con>
        </div>
    </body>
    <script>
    
    
    let con =  {
                    template: `<div><p>次数{{count}}</p>
            <button type="button" @click="--count">-</button>
            <button type="button" @click="++count">+</button></div>`,
                    data() {
                        return {
                            count: 0
                        }
                    }
                }
    
        let app = new Vue({
            el: '#app'
    
        })
    
        
    
        let app1 = new Vue({
            el: '#app1',
            components: {
                con: con
            }
        })
    </script>
    
    </html>
    - components就是当前vue对象组件集合。
      - 其key就是子组件名称
      - 其值就是组件对象的属性
    - 效果与刚才的全局注册是类似的,不同的是,这个conn组件只能在当前的Vue实例中使用
    
    注:定义组件要在Vue对象之前声明
    

    七、Vue的Ajax(axios)

    在Vue.js中发送网络请求本质还是ajax,我们可以使用插件方便操作。
    

    (一)安装

    下载axios.js
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    用离线版的axios.js
    

    (二)axios请求

    GET请求

    
    
    axios.get('/user?id=12345')
     .then(response => {
         console.log(response.data);
     });
    
    axios.get('/user?id=12345').then(function(response){
        
    })
    
    
    

    POST请求

    axios.post('/user', "name=迪丽热巴&age=23") .then(response => {
            console.log(response.data);
        });
    

    (三)跨域问题

    什么是跨域?
    指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。
    什么是同源策略?
    是指协议,域名,端口都要相同,其中有一个不同都会产生跨域,在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
    跨域问题怎么出现的?
    开发一些前后端分离的项目,比如使用 Servlet + Vue 开发时,后台代码在一台服务器上启动,前台代码在另外一台电脑上启动,此时就会出现问题。
      比如:

        后台 地址为 http://192.168.70.77:8081
        前台 地址为 http://192.168.70.88:8080
      此时 ip 与 端口号不一致, 不符合同源策略,造成跨域问题。

    image

    处理思路

    使用CORS,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
    值得注意的是,目前主流浏览器都支持cors,会自动发出cors请求。在简单请求下,cors请求和同源请求的区别主要是浏览器的请求头信息中会多了一个origin字段。 这个字段表示本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这个请求。

    因此在后续解决方案中,主要是服务器需要处理orgin这个请求头字段,同意跨域请求。

    如何解决:
    	后台解决(自定义过滤器)
    
        
    package com.offcn.filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebFilter("/*")
    public class CorsFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            HttpServletRequest request = (HttpServletRequest) servletRequest;
    
            // 不使用*,自动适配跨域域名,避免携带Cookie时失效
            String origin = request.getHeader("Origin");
            response.setHeader("Access-Control-Allow-Origin", origin);
    
            // 自适应所有自定义头
            String headers = request.getHeader("Access-Control-Request-Headers");
            response.setHeader("Access-Control-Allow-Headers", headers);
            response.setHeader("Access-Control-Expose-Headers", headers);
    
            // 允许跨域的请求方法类型
            response.setHeader("Access-Control-Allow-Methods", "*");
            // 预检命令(OPTIONS)缓存时间,单位:秒
            response.setHeader("Access-Control-Max-Age", "3600");
            // 明确许可客户端发送Cookie,不允许删除字段即可
            response.setHeader("Access-Control-Allow-Credentials", "true");
    
            filterChain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
    
        }
    }
    
    
    
    
    
  • 相关阅读:
    《软件测试经验与教训》—读书笔记
    【转】性能测试工程师的素质
    【转】如何成为优秀的性能测试工程师
    性能测试学习之路
    FTP 、TCP/IP、HTTP、Cookies、Session
    Loadrunner工具介绍
    tesseract-ocr图像识别技术(一)
    MongoDB 自动分片 auto sharding
    mongodb 3.0下载安装、配置及mongodb最新特性、基本命令教程详细介绍
    java使用memcached2--集群部署
  • 原文地址:https://www.cnblogs.com/conglingkaishi/p/15315243.html
Copyright © 2020-2023  润新知