VUE---学习进阶03

1.jsonp解决跨域问题

什么是跨域:协议,域名,端口号只要有一个不一致就叫做跨域

 jsonp解决跨域问题
 1.动态创建script标签 var os = document.createElemnt('script')
 2.设置src   os.src = '地址'  http://suggestion.baidu.com/su?cb=aa&wd=123
 3.添加到页面 document.body.appendChild(os)       
 4.设置回调函数 aa
 function aa(res) {
      console.log(res)
 }

2.wtach:监听器

2.1监听简单类型

语法:
这里的msg必须是声明之后的,打印的是更新后和更新前的值

<body>
    <div id="app">
        {{msg}}
        <input type="text" v-model='msg'>
    </div>
</body>
<script src="./vue.js"></script>
<script>
    // 1.监听器
    let vn = new Vue({
        el:'#app',
        data:{
            msg:'hello'
        },
        // 监听器
        watch: {
            // msg必须是声明后的
            msg(newVal,oldVal){
                console.log(newVal,oldVal)
            }
        },
    })
</script>

2.2监听复杂数据类型:

这是深监听:一般不推荐使用,原因是会导致页面卡顿,如果需要监听对象类型,可以把数据转为简单数据类型进行浅监听。
下面代码可以实现监听复杂数据类型:
主要代码是:

 watch: {
            // 这是深监听  不建议使用,原因是会导致页面卡顿,如果需要监听对象类型,可以把数据转为简单数据类型进行浅监听
            json:{
                handler(){
                    console.log('更新了')
                },
                deep:true
            }
        }

全部代码:

<body>
    <div id="app">
        <input type="text" v-model='json.name'>
    </div>
</body>
<script src="./vue.js"></script>
<script>
    // 1.监听器
    let vn = new Vue({
        el:'#app',
        data:{
           json:{
               name:'zs'
           },
           arr:[]
        },
        methods: {
            
        },
        watch: {
            // 这是深监听  不建议使用,原因是会导致页面卡顿,如果需要监听对象类型,可以把数据转为简单数据类型进行浅监听
            json:{
                handler(){
                    console.log('更新了')
                },
                deep:true
            }
        },
    })
</script>
</html>

2.3监听的两个简单案例

案例一:当input中的输入包括问好的时候,后面显示出YES(出现概率70%)或NO(出现概率30%)
效果图:
在这里插入图片描述
代码:

<body>
    <div id="app">
        <input type="text" v-model='question'>
        <div>答案是:{{answer}}</div>
    </div>
</body>
<script src="./vue.js"></script>
<script>
    // 1.监听器
    let vn = new Vue({
        el:'#app',
        data:{
           question:'',
           answer:''
        },
        methods: {
            
        },
        watch: {
            question(){
                // includes   indexOf
                if(this.question.includes('?')||this.question.indexOf('?') !=-1){
                    // 出来yes的概率是70%   出来no的是30%
                   this.answer =  Math.random()<0.7?'YES':'NO'
                }
            }
        },
    })
</script>
</html>

案例二:模拟百度,可以实现搜索,用的是百度的链接
效果图:点击回车可以搜索百度
代码:

<!DOCTYPE html>
    <style>
        .active{
            background: red;
        }
    </style>
</head>
<body>
    <div id="app">
        <input type="text" v-model='kw' @keydown.up = 'up' @keydown.down='down' @keydown.enter = 'enter'>
        <ul>
            <li v-if='4>index' v-for = '(item,index) in arr' :class='[index==n?"active":""]'>{{item}}</li>
        </ul>
    </div>
</body>
<script src="./vue.js"></script>
<script>
    // 1.监听器
    let vm = new Vue({
        el:'#app',
        data:{
           kw:'',//这是关键字
           arr:[],//这是请求回来的数据
           n:-1//上下切换的标识
        },
        methods: {
            // 向上
            up(){
                this.n--;
                if(this.n<0){
                    this.n = 3
                }
            },
            // 向下
            down(){
                this.n++;
                if(this.n>=4){
                    this.n=0
                }
            },
            // 回车
            enter(){
                if(this.n!=-1){
                    window.open('https://www.baidu.com/s?wd='+this.arr[this.n],'_self')
                }else{
                    window.open('https://www.baidu.com/s?wd='+this.kw)
                }
                
            }
            
        },
        watch: {
            kw(){
             //1.创建标签
             var os = document.createElement('script');
            //  2.设置连接  http://suggestion.baidu.com/su?cb=callback&wd=234
            os.src = 'http://suggestion.baidu.com/su?cb=aa&wd='+this.kw 
            // 3.添加页面
            document.body.appendChild(os)
            }
            
        },
    })
    function aa(res){
        console.log(res)
        vm.arr = res.s
    }
</script>
</html>

3.filter:过滤器

3.1全局过滤器

电话号码:{{tel | filterTel}}:这句话相当于调用filterTel,传入的实参为tel;

声明全局的过滤器:
Vue.filter(‘filterTel’,(tel)=>{
return tel.slice(0,3)+’****’+tel.slice(7)
})

<body>
    <div id="app">
        <!-- |  管道符 -->
        电话号码:{{tel | filterTel}}
    </div>
</body>
<script src="./vue.js"></script>
<script>
    // 全局过滤器
    Vue.filter('filterTel',(tel)=>{
        return tel.slice(0,3)+'****'+tel.slice(7)
    })

    let vm = new Vue({
        el:'#app',
        data:{
           tel:'13858585858'
        },
        methods: {
            
        },

    })
</script>
</html>

3.2局部过滤器

局部过滤器写在new的Vue中,仅对#app里面的内容起作用

基本写法:

        电话号码:{{tel | filterTel}}
  // 局部过滤器
        filters:{
            filterTel:function(tel){
                return tel.slice(0,3)+'****'+tel.slice(7)
            }
        }
<body>
    <div id="app">
        <!-- |  管道符 -->
        电话号码:{{tel | filterTel}}
        价格:{{price | filterPrice}}
    </div>
    <div id="box">
        <!-- |  管道符 -->
        电话号码:{{mytel | filterTel}}
        价格:{{price | filterPrice }}
    </div>
</body>
<script src="./vue.js"></script>
<script>  
  let vm = new Vue({
        el:'#app',
        data:{
           tel:'13858585858',
           price:90.00
        },
      
        // 局部过滤器
        filters:{
            filterTel:function(tel){
                return tel.slice(0,3)+'****'+tel.slice(7)
            }
        }

    })
    let vn = new Vue({
        el:'#box',
        data:{
           mytel:'13858585858',
           price:199.8
        },
    })
</script>
</html>

3.3过滤器案例

案例一:格式化时间:将时间戳转换成真正的时间,并且当时间不过两位数的时候,在前面自动不零。这里用到了padStart(2,‘0’)方法:补零的方法,
效果图:
在这里插入图片描述

<body>
    <div id="app">
        <table border="1" style="border-collapse: collapse;" width='500'>
            <tr>
                <th>姓名</th>
                <th>日期</th>
            </tr>
            <tr v-for='item in list' :key='item.id'>
                <td>{{item.name}}</td>
                <td>{{item.time | formatTime}}</td>
            </tr>
        </table>
    </div>
</body>
<script src="./vue.js"></script>
<script>
    // 1.监听器
    // 2.filter过滤器
    Vue.filter('formatTime',(time)=>{
        // 获取时间
        var data = new Date(time);
        var year = data.getFullYear();
        // var month = (data.getMonth()+1)<10?"0"+(data.getMonth()+1):(data.getMonth()+1);
        var month = (data.getMonth()+1+'').padStart(2,'0')
        var day = data.getDate();

        var hours = data.getHours();
        var minutes = data.getMinutes();
        var seconds = (data.getSeconds()+'').padStart(2,'0');

     return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    })

    let vn = new Vue({
        el:'#app',
        data:{
           list:[
               {
                   id:1,
                   name:'高',
                   time:1602486061690
               },
               {
                   id:2,
                   name:'乐',
                   time:1602383061690
               },
               {
                   id:3,
                   name:'丁',
                   time:1602493061690
               },
               {
                   id:4,
                   name:'刘',
                   time:1602483061490
               }
           ]
        },
        methods: {
            
        },
    })
</script>
</html>

4.computed:计算属性

计算属性关键词:computed
这里的avg必须是声明过的,返回的值会直接赋值给avg,进行渲染到界面上。

 computed: {
            avg(){
                var sum = 0 ;
                this.list.forEach((item)=>{
                    sum+=item.score
                })
                return (sum/this.list.length).toFixed(2)
            },

下面这个案例实现了成绩平均值的计算。
成绩平均值

<body>
    <div id="app">
        <table border="1" style="border-collapse: collapse;" width='500'>
            <tr>
                <th>姓名</th>
                <th>分数</th>
            </tr>
            <tr v-for='item in list' :key='item.id'>
                <td>{{item.name}}</td>
                <td><input type="number" v-model.number='item.score'></td>
            </tr>
            <tr>
                <th>平均分</th>
                <td>{{avg}}</td>
            </tr>
        </table>
    </div>
</body>
<script src="./vue.js"></script>
<script>
    // 3.computed 计算属性
    let vn = new Vue({
        el:'#app',
        data:{
            list:[
               {
                   id:1,
                   name:'高',
                   score:90
               },
               {
                   id:2,
                   name:'乐',
                   score:95
               },
               {
                   id:3,
                   name:'丁',
                   score:85
               },
               {
                   id:4,
                   name:'刘',
                   score:70
               },
               {
                   id:5,
                   name:'陆',
                   score:40
               },
               {
                   id:6,
                   name:'冯',
                   score:60
               }
           ]
        },
        methods: {
            
        },
        computed: {
            avg(){
                var sum = 0 ;
                this.list.forEach((item)=>{
                    sum+=item.score
                })
                return (sum/this.list.length).toFixed(2)
            },
         
        },
    })
</script>
</html>

5.综合案例(购物车)

购物车实现了数据的增减,全选和部分选择以及价格的计算。
这里使用了bootstrap框架.
效果图:购物车模拟

    <title>Document</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
    <div id="app" class="container">
        <!-- <i class="glyphicon glyphicon-search"></i> -->
        <h3 class="text-center text-success">购物车</h3>
        <table class="table table-hover table-bordered">
            <tr>
                <th><input type="checkbox" @click = 'changeAll' v-model='allCheck'>全选</th>
                <th>商品名称</th>
                <th>商品单价</th>
                <th>商品数量</th>
                <th>小计</th>
                <th>操作</th>
            </tr>
            <tr v-for='(item,index) in goods' :key='item.id'>
                <td><input type="checkbox" v-model='item.check' @click = 'changeOne(index)'></td>
                <td>{{item.name}}</td>
                <td>{{item.price}}</td>
                <td>
                    <button class="btn btn-warning" @click = 'sub(index)'>-</button>
                    {{item.num}}
                    <button class="btn btn-success" @click='add(index)'>+</button>
                </td>
                <td>{{item.price*item.num}}</td>
                <td>
                    <button class="btn btn-primary" @click = 'del(index)'>删除</button>
                </td>
            </tr>
            <tr>
                <td>总价</td>
                <td colspan="5">{{total}}</td>
            </tr>
        </table>
    </div>
</body>
<script src="./vue.js"></script>
<script>
    // 1.监听器
    // 2.filter过滤器
    // 3.computed 计算属性
    let vn = new Vue({
        el:'#app',
        data:{
           allCheck:false,
           goods:[
                {
                    id:1,
                    name:'手机',
                    price:1999,
                    num:1,
                    check:false,
                },
                {
                    id:2,
                    name:'电脑',
                    price:3999,
                    num:1,
                    check:true,
                },
                {
                    id:3,
                    name:'平板',
                    price:999,
                    num:1,
                    check:false,
                }
           ]
        },
        methods: {
            // 减
            sub(index){
                if(this.goods[index].num>0){
                    this.goods[index].num--;
                }
            },
            // 增加
            add(index){
                
                if(this.goods[index].num<5){
                    this.goods[index].num++;
                }
            },
            // 删除
            del(index){
                this.goods.splice(index,1)
            },
            // 全选
            changeAll(){
                this.allCheck = !this.allCheck
                // console.log(this.allCheck)
                this.goods.forEach((item)=>{
                    item.check = this.allCheck
                })
            },
            // 选中某一个
            changeOne(index){
                this.goods[index].check = !this.goods[index].check
                this.allCheck = this.goods.every(item =>{
                    console.log(item.check)
                    return item.check
                })
                // console.log(this.allCheck);
            }
        },
        computed: {
            total(){
                var sum = 0;
                this.goods.forEach((item)=>{
                    if(item.check){
                        sum+=item.price*item.num
                    }
                })
                return sum
            }
        }
    })
</script>
</html>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值