• vue 基础(二)


    Vue对象提供的属性功能

    一.过滤器

    过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容操作数据中。

    1. 全局过滤器

    Vue.filter  写在vm 对象外。必须要有返回值。
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.js"></script>
    
    </head>
    <body>
        <div id="app">
            <span>{{num|f2}}</span>
            <span>{{num|f3}}</span>
        </div>
    
    </body>
    <script>
        // 全局过滤器
        Vue.filter("f2",function (v) {
            //必须要使用return 把过滤后的内容返回
            //js 提供的toFixed ()   保留小数位数
            return v.toFixed(2) //保留两位小数
    
        });
        Vue.filter("f3",function (v) {
            return v+""
        });
    var vm =new Vue({ el:"#app", data:{ num:10.333333, text:'hello world' }, }) </script> </html>

    2.局部过滤器

    过滤器定义在某个vm 对象中。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.js"></script>
    
    </head>
    <body>
        <div id="app">
            <span>{{text|trans}}</span>
            <span>{{num|f2}}</span>
            <span>{{num|f3}}</span>
        </div>
    
    </body>
    <script>
        // 全局过滤器
        Vue.filter("f2",function (v) {
            //必须要使用return 把过滤后的内容返回
            //js 提供的toFixed ()   保留小数位数
            return v.toFixed(2) //保留两位小数
    
        });
        Vue.filter("f3",function (v) {
            return v+""
        });
        var vm =new Vue({
    
            el:"#app",
            data:{
                num:10.333333,
                text:'hello world'
            },
            //局部过滤器
            filters:{
    
                trans:function (v) {
                    return v.toUpperCase();
                }
            }
    
    
    
    
        })
    </script>
    </html>

    二.阻止事件冒泡和刷新页面

    1事件冒泡

    在js的事件操作中,子元素的事件触发以后,会默认情况把事件传播给其父级元素,然后一层层往外传播,这种现象就是"事件冒泡".

    例子:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件冒泡</title>
    </head>
    <body>
        <div class="div1"  onclick="alert('div1')">
            <div class="div2"  onclick="alert('div2')">
                <div class="div3"  onclick="alert('div3')">
                    <p>点我呀~</p>
                </div>
            </div>
        </div>
    
    </body>
    </html>

    上面的例子,点击:点我呀, 会依次触发 弹出窗口:  div3-----div2-----div1  这种现象叫事件冒泡。

    防止事件冒泡的方式:@click.stop=""   

    以下为一个事件冒泡的问题,就是外层元素设置了一个点击事件,点击内层元素时,也会触发该事件,如果想点击内层某个div 所有内容都不触发外层点击事件的影响,

    那就在该层div 设置: @click.stop=""     就能实现点击该div内所有的元素都不会触发外层的事件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.js"></script>
        <style>
        .box{
            background-color: #fff;
            border-radius: 5px;  /* 边框圆角 */
            padding-top: 15px;
            padding-left: 30px;
            padding-bottom: 15px;
            width: 290px;
            height: 160px;
            position: fixed;
            margin: auto;
            left: 0px;
            right: 0px;
            top:0;
            bottom: 0;
        }
        .container{
            background: rgba(0,0,0,0.6);
            width: 100%;
            margin:auto;
            position: fixed;
            top:0;
            left: 0;
            bottom:0;
            right:0;
        }
        </style>
    </head>
    <body>
        <div id="app">
            <h1 @click="is_show=true">显示</h1>
            <div class="container" v-show="is_show" @click="is_show=false">
                <div class="box" @click.stop="">   /*点击本层就不会触发外层的点击事件*/
                    账号: <input type="text"><br><br>
                    密码: <input type="password"><br><br>
                    <input type="submit" vlaue="提交">
               </div>
            </div>
        </div>
        <script>
    
            let vm = new Vue({
                el:"#app",
                data:{
                    is_show:false,
                },
                methods:{
    
                },
            })
        </script>
    </body>
    </html>

    2.阻止事件刷新

    @click.prevent=""

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <!-- 超链接表单中的提交,希望阻止页面刷新,可以使用 @事件.prevent="" -->
            <a href="" @click.prevent="">百度</a>
        </div>
        <script>
    
            let vm = new Vue({
                el:"#app",
                data:{
                },
    
            })
        </script>
    </body>
    </html>

    计算属性

    computed  

    该方法中的每个函数必须要return 值。 

    如果直接把反转的代码写在元素中,则会使得其他同事在开发时时不易发现数据被调整了,
    所以vue提供了一个计算属性(computed),可以让我们把调整data数据的代码存在在该属性中。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>计算属性</title>
        <script src="vue.js"></script>
    </head>
    <body>
       <div id="app">
           <div>
               <span>{{name}}</span>
               <span>{{str_revs}}</span>
           </div>
       </div>
    
       <script>
           var vm=new Vue({
               el:'#app',
               data:{
                    name:'python'
    
               },
               computed:{
                   str_revs:function () {
                       ret=this.name.split('').reverse().join("");
                       return ret
                   }
               }
               
           })
       </script>
    </body>
    </html>
    计算属性

    监听事件

    watch   

    侦听属性是一个对象,它的键是要监听的对象或者变量值一般是函数,

    当侦听的data数据发生变化时,会自定执行的对应函数,这个函数在被调用时,

    vue会传入两个形参,第一个是变化前的数据值,第二个是变化后的数据值。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <span @click="num--">-</span>
            <input type="text" size="1" v-model="num">
            <span @click="num++">+</span>
        </div>
        <script>
            // 侦听属性
            // 这里的属性是指代data中的数据
            let vm = new Vue({
                el:"#app",
                data:{
                    num:0
                },
                // watch里面的方法,会在数据发生变化时,自动执行
                watch:{
                    /**
                 *  要观察的变量名: function(变化后的值,变化前的值){
                    
                     *  }
                     */
                    num: function(v1,v2){
                        if(v1<0){
                            this.num=0;
                        }
                    }
                }
            })
        </script>
    </body>
    </html>

    Vue对象的生命周期(执行过程)

    每个Vue对象在创建时都要经过一系列的初始化过程。在这个过程中Vue.js会自动运行一些叫做生命周期的的钩子函数,

    我们可以使用这些函数,在对象创建的不同阶段加上我们需要的代码,实现特定的功能。

    1. beforeCreate:function(){}      vm对象初始化之前,此时el和data还没有出现

    2.created: function(){}  created在vm对象初始化之后执行了,此时$el没有,但是已经有data数据

        开发项目时,在这个函数中,编写向后台请求数据的代码,这些代码不涉及到视图html标签的操作
         ajax

    3.beforeMount: function(){} 

      把data数据挂载到html视图之前

      此时vue并没有把data数据挂载到html视图中,所以$el还是源码中的vue指令

    4. mounted: function(){}

      把data数据挂载到html视图之后

      此时vue已经把data数据挂载到html视图中了,所以$el就是挂载后的数据

      这个位置用于编写初始化中操作html内容的代码.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <p>{{num}}</p>
        </div>
        <script>
            // 侦听属性
            // 这里的属性是指代data中的数据
            let vm = new Vue({
                el:"#app",
                data:{
                    num:10
                },
                //  vm对象初始化之前,此时el和data还没有出现
                beforeCreate: function(){
                    console.log("beforeCreate在vm对象初始化之前,此时el和data还没有出现");
                    console.log(this.$el); // this..$el 查看上面vue对象操作的标签控制器
                    console.log(this.$data); // this.$data 查看上面vue对象保存的data,访问bum这些数据时没有的
                },
                // vm对象初始化之后,
                created: function(){
                    console.log('created在vm对象初始化之后执行了,此时$el没有,但是已经有data数据了');
                    console.log(this.$el);
                    console.log(this.$data);
                    console.log( this.num );
                    // 开发项目时,在这个函数中,编写向后台请求数据的代码,这些代码不涉及到视图html标签的操作
                    // ajax
                },
                // 把data数据挂载到html视图之前
                beforeMount: function(){
                    console.log('beforeMount执行了,此时vue并没有把data数据挂载到html视图中,所以$el还是源码中的vue指令');
                    console.log(this.$el.innerHTML);
                    console.log(this.$data); // $data早已经有了
                },
                // 把data数据挂载到html视图之后
                mounted: function(){
                    console.log('mounted执行了,此时vue已经把data数据挂载到html视图中了,所以$el就是挂载后的数据');
                    console.log(this.$el.innerHTML);
                    // 这个位置用于编写初始化中操作html内容的代码
                }
            })
        </script>
    </body>
    </html>
    vue的生命周期

    总结 :

    1.在vue使用的过程中,如果要初始化操作,把初始化操作的代码放在 mounted 中执行。
    mounted阶段就是在vm对象已经把data数据实现到页面以后。一般页面初始化使用。例如,用户访问页面加载成功以后,就要执行的ajax请求。

    2. created,这个阶段就是在 vue对象创建以后,把ajax请求后端数据的代码放进 created。

    axios实现数据请求

    vue.js默认没有提供ajax功能的。一般都会使用axios的插件来实现ajax与后端服务器的数据交互。

    注意,axios本质上就是javascript的ajax封装,所以会被同源策略限制

    下载地址:

    https://unpkg.com/axios@0.18.0/dist/axios.js
    https://unpkg.com/axios@0.18.0/dist/axios.min.js

    使用axios时需要注意: 引入时,axios 文件需要放在vue文件之后。

     <script src="js/vue.js"></script>
      <script src="js/axios.js"></script><!-- 写在vue后面 -->

    axios提供发送请求的常用方法有两个:

    1. axios.get() 

    发送get请求:
    参数1: 必填,字符串,请求的数据接口的url地址
    参数2:必填,json对象,要提供给数据接口的参数
    参数3:可选,json对象,请求头信息

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
        <script src="js/axios.js"></script><!-- 写在vue后面 -->
    </head>
    <body>
        <div id="app">
            请输入您要查询的城市: <input type="text" v-model="city">
            <button @click="getWeather">点击获取天气</button>
            <p>{{ganmao}}</p>
        </div>
        <script>
            let vm = new Vue({
                el:"#app",
                data: {
                    city:"深圳",
                    ganmao:"",
                    weather_info:""
                },
                methods: {
                    getWeather: function(){
                        // 在这里编写ajax
                        // axios是一个对象
                        // axios.get(url地址).then(function(){})  发送get请求获取数据
                        // axios.post() 发送post请求上传数据
                        // 进入ajax之前,保存vue对象到一个变量里面,方便在ajax内部使用 this
                        _this = this;
                        axios.get("http://wthrcdn.etouch.cn/weather_mini?city="+this.city)
                            .then(function(response){ // 会在ajax请求成功过以后,自动执行
                                // response 里面会包含后端返回的数据
                                console.log(response);
                                console.log("ajax内部的匿名函数:",this);
    
                                // this.ganmao = response.data.data.ganmao // 这里代码不对,this表示window
                                _this.ganmao = response.data.data.ganmao
                            }).catch(function(error){ // 会在ajax请求失败过后,自动执行
                                // error 里面你会包含错误信息
                                console.log(error);
                            })
                    }
                }
            })
        </script>
    </body>
    </html>

    axios.post()

    数据接口

    数据接口,也叫api接口,表示`后端提供`操作数据/功能的url地址给客户端使用。

    客户端通过发起请求向服务端提供的url地址申请操作数据【操作一般:增删查改】

    同时在工作中,大部分数据接口都不是手写,而是通过函数库/框架来生成。

          接口                                | 地址 |
    | ------------ | ------------------------------------------------------------ |
    | 天气接口 | http://wthrcdn.etouch.cn/weather_mini?city=城市名称 |
    | 音乐接口搜索 | http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.catalogSug&query=歌曲标题 |
    | 音乐信息接口 | http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.song.play&songid=音乐ID |

    同源策略问题

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>axios ajax请求</title>
    <script src="vue.js"></script>
    <script src="axios.js"></script>
    </head>
    <body>
    <div id="app">
    <div>
    <input type="text" v-model="music"><button @click="get_weather">搜索音乐</button>
    </div>
    <div>
    音乐信息:<span>{{music_info}}</span>
    </div>
    </div>

    <script>

    var vm=new Vue({
    el:'#app',
    data:{

    music:'',
    music_info:'',

    },
    methods:{
    get_weather:function () {
    // 写ajax请求
    _this = this;// 先保存 data对象中 的this 用于axios 中调用
    axios.get("http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.catalogSug&query="+this.music)
    .then(
    function (response) {
    //response 包含后端返回来的数据
    console.log(response);

    }).catch(function (error) {
    console.log(error);
    })


    }
    }


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

    到axios 请求到此接口:http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.catalogSug&query=歌曲标题  ,

    拿数据时,发生了同源策略问题,直接获取不到数据的现象。会抛出一下错误提示:

    同源策略:浏览器的一种保护用户数据的一种安全机制。
    浏览器会限制脚本语法不能跨源访问其他源的数据地址。
    同源:判断两个通信的地址之间,是否协议,域名[IP],端口一致
    ajax: http://127.0.0.1/index.html
    api数据接口: http://localhost/index

    这两个是同源么?不是同源的。

    1. ajax默认情况下会受到同源策略的影响,一旦受到影响会报错误如下:
    No 'Access-Control-Allow-Origin' header is present on the requested resource

    2. 解决ajax只能同源访问数据接口的方式:
      1. 在服务端的响应行中设置:
        Access-Control-Allow-Origin: 允许访问的域名地址

      2. 通过爬虫先爬取到数据,在写入到自己的后端,通过访问自己的后端间接拿到数据。

    案例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.js"></script>
    
    </head>
    <body>
    <div id="app">
    
        <select  v-model="province">
            <option value="0">省份</option>
            <option v-for="item in item_list" v-if="item.pid==0 & item.flag==='a'" :value="item.id">{{item.name}}</option>
    
        </select>
           <select  v-model="city" >
            <option value="0">城市</option>
            <option v-for="item in item_list" v-if="item.pid==province & item.flag==='b'" :value="item.id">{{item.name}}</option>
    
        </select>
           <select  v-model="area" >
            <option value="0">地区</option>
            <option v-for="item in item_list" v-if="item.pid==city & item.flag==='c'" :value="item.id">{{item.name}}</option>
    
        </select>
    </div>
    <script>
        var vm = new Vue({
            el:"#app",
    
            data: {
                province:0,
                city:0,
                area:0,
    
                item_list: [
                    {"id": 1, "name": "广东省", 'pid': 0,"flag":"a"},
                    {"id": 2, "name": "广州", 'pid': 1,"flag":"b"},
                    {"id": 3, "name": "深圳", 'pid': 1,"flag":"b"},
                    {"id": 4, "name": "东莞", 'pid': 1,"flag":"b"},
                    {"id": 5, "name": "江西省", 'pid': 0,"flag":"a"},
                    {"id": 6, "name": "南昌", 'pid': 5,"flag":"b"},
                    {"id": 7, "name": "吉安", 'pid': 5,"flag":"b"},
                    {"id": 8, "name": "赣州", 'pid': 5,"flag":"b"},
                    {"id": 9, "name": "九江", 'pid': 5,"flag":"b"},
                    {"id": 10, "name": "天河区", 'pid': 2,"flag":"c"},
                    {"id": 11, "name": "海珠区", 'pid': 2,"flag":"c"},
                    {"id": 12, "name": "黄埔区", 'pid': 2,"flag":"c"},
                    {"id": 13, "name": "南山区", 'pid': 3,"flag":"c"},
                    {"id": 14, "name": "龙岗区", 'pid': 3,"flag":"c"},
                    {"id": 15, "name": "宝安区", 'pid': 3,"flag":"c"}
    
                ]
    
    
            },
            watch:{
                province:function () {
                    this.city=0;
                    this.area=0;
                },
                city:function () {
                    this.area=0;
                }
                    
             
            }
    
    
        })
    </script>
    
    </body>
    </html>
    地级市3级联动

    知识点:

      1. 数据结构的设计。 pid 解决层级问题,flag 分类

      2. v-model

      3.v-for    

      4.v-if   中多条件   用 & 连接

      5. watch  事件监听

  • 相关阅读:
    字符串哈希
    codeforces#766 D. Mahmoud and a Dictionary (并查集)
    莫比乌斯反演模板
    马拉车模板
    codeforces#580 D. Kefa and Dishes(状压dp)
    1076E
    448C
    543A
    295B
    poj3974 Palindrome
  • 原文地址:https://www.cnblogs.com/knighterrant/p/10518493.html
Copyright © 2020-2023  润新知