vue生命周期与侦听器,vue实现购物车和百度搜索(附源码)

vue生命周期与侦听器

动态样式

基于vue和js语法来研究一下动态处理样式的方式

动态的class

基本模式

<div id="app">
        <div :class="isShow?'show':'hidden'">    
            嘿嘿嘿
        </div>
        <p @click="isShow = !isShow">切换</p>
        <p @click="change_color">变红</p>
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                isShow: true,
                class_arry: ['box', 'font']           
            },
            methods: {
                change_color(){
                    this.class_arry.unshift('red')
                }
            }
        })
    </script>

数组模式

<div id="app">
        <!-- <div :class="['box', 'font', 'red']"> 基本数组结构 -->
        <div :class="class_arry">
            嘿嘿嘿
        </div>
        <p @click="change_color">变红</p>
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                class_arry: ['box', 'font']           
            },
            methods: {
                change_color(){
                    this.class_arry.unshift('red')
                }
            }
        })
    </script>

对象模式

<div id="app">
        <!-- <div :class="{'red': false,'box': true}">     -->
        <div :class="class_obj">    
            嘿嘿嘿
        </div>
        <p @click="isShow = !isShow">切换</p>
        <p @click="change_color">变红</p>
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                isShow: true,
                class_arry: ['box', 'font'],
                class_obj: {'red': true,'box': true}           
            },
            methods: {
                change_color(){
                    this.class_arry.unshift('red')
                }
            }
        })
    </script>

动态的style

常规写法

<body>
    <div id="app">
        <div :style="'background-color:red'">    
            嘿嘿嘿
        </div>
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: { 
            },
        })
    </script>
</body>

对象写法

<body>
    <div id="app">
        <!-- <div :style="{'background-color':'red'}">     -->
        <div :style="obj">  
            嘿嘿嘿
        </div>
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                 obj:{
                     backgroundColor:'red'
                    }       
            },
        })
    </script>
</body>

数组写法

<div id="app">
    <div :style="[obj,obj1]">    
        嘿嘿嘿
    </div>
</div>
<script>
    var vue = new Vue({
        el: "#app",
        data: {
            obj:{
                backgroundColor:'red'
            },
            obj1:{
                fontSize: "24px"
            }       
        },
    })
</script>

生命周期

在vue执行的过程当中,会有几个共性关键的执行节点,我们称为生命周期节点。生命周期指的是vue实例从创建,挂载,运行到销毁的过程。

创建阶段(create)

创建阶段的生命周期函数是自动执行的

首先执行beforeCreate,然后执行created

beforeCreate 创建前

创建前,vue的变量还没有声明

created 创建后

创建后,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="./vue.js"></script>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
    <div id="app">
        <div>    
            {{ message }}
        </div> 
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                 message: "hello world"   
            },
            created(){
                console.log(this.message,"created")
            },
            beforeCreate(){
                console.log(this.message,"beforeCreate");
            }
        })
    </script>
</body>
</html>

挂载阶段(mount)

beforeMount 挂载前

mounted 挂载后

挂载阶段的生命周期函数在创建阶段的生命周期函数执行完成自动执行,

beforeMount 还没有实现页面上变量数据的挂载

mounted 已经完成页面数据的挂载

<body>
    <div id="app">
        <div id="msg">    
            {{ message }}
        </div> 
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                 message: "hello world"   
            },
            beforeMount(){
                console.log(document.querySelector("#msg"),"beforeMount");
            },
            mounted(){
                console.log(document.querySelector("#msg"),"mounted");
            },
        })
    </script>
</body>

更新阶段(update)

beforeUpdate 更新前

updated 更新后

更新阶段的生命周期函数在挂载阶段的生命周期函数执行完成后发生数据修改自动执行,

beforeUpdate 数据修改前执行

updated 数据修改后执行

更新阶段的生命周期函数每次跟新都执行,但是挂载阶段的生命周期函数和创建阶段的生命周期函数只在第一次加载执行一次

<!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>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
    <div id="app">
        <div id="msg">    
            {{ message }}
            <input v-model="message">
        </div> 
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                 message: "hello world"   
            },
            beforeUpdate(){
                console.log(document.querySelector("#msg").innerHTML,"beforeUpdate");
            },
            updated(){
                console.log(document.querySelector("#msg").innerHTML,"updated");
            }
        })
    </script>
</body>
</html>

销毁阶段 (destroy)

beforeDestroy 销毁前

destroyed 销毁后

触发销毁函数后执行销毁阶段的生命周期函数,通常用来进行内存回收。

<!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>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
    <div id="app">
        <div id="msg">    
            {{ message }}
            <input v-model="message">
            <button @click="destroy">销毁吧</button>
        </div> 
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                 message: "hello world"   
            },
            methods:{
                destroy(){
                    this.$destroy()
                }
            },
            beforeDestroy(){
                console.log(this,"beforeDestroy");
            },
            destroyed(){
                console.log(this,"destroyed");
            }
        })
    </script>
</body>
</html>

vue的生命周期一共有四种,八个,其中两种四个自动执行,剩下的条件执行。

侦听器

方法名称: watch

作用,监听某个数据的变化,从而进行一些特殊的操作

特点:不需要调用执行,触发执行即可,类似update

注意:watch本身有一定的系统开销,所以,侦听器不可以滥用。

<!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>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
    <div id="app">
        <div id="msg">    
            {{ message }}
            <input v-model="message">
        </div> 
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                 message: "hello world",  
                 hhh: "hhh", 
            },
            watch :{
                message(new_value,old_value){
                    console.log(new_value,old_value)
                }
            }
        })
    </script>
</body>
</html>

深度侦听器

深度侦听器主要针对的是嵌套结构的数据修改。

<div id="app">
        <div id="msg" @click="add">    
            {{ message }}
        </div> 
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                message: {
                    msg: {
                        name: "王"
                    }
                },  
            },
            methods: {
                add(){
                    this.message.msg.name = "李"
                }
            },
            watch :{
                message:{
                    handler(){
                        console.log(arguments);
                    }, //句柄
                    deep: true //启动深度侦听
                }            
            }
        })
    </script>

计算属性

computed:作为vue当中的计算属性,主要用在页面当中的数据计算,特点:

1、调用的时候不用加括号,灵活度不够好。

2、本身具备缓存能力。

3、计算属性不可以和其他的vue变量或者功能重名。

4、计算属性的值可以读取,不可以修改

<div id="app">
        <div id="msg" @click="add">    
            {{ add() }}
            {{ add() }}
            {{ add() }}
            <hr />
            {{ add_1 }}
            {{ add_1 }}
            {{ add_1 }}
            <input v-model="add_2">
            {{ add_1 }}
        </div> 
    </div>
    <script>
        var vue = new Vue({
            el: "#app",
            data: {
                add_2: 123
            },
            methods:{
                add(){
                    console.log("add 被调用了,methods")
                    return 999
                }
            },
            computed:{
                add_1(){
                    console.log("add 被调用了,computed")
                    return "abc"
                }
            }
        })
    </script>

购物车案例

代码实现

<!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>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        .container {
            width: 1000px;
            margin: 20px auto;
        }

        .form-group {
            margin: 15px 0;
        }

        .form-control {
            height: 40px;
            padding: 10px;
            width: 100%;
            border: 1px solid #DDD;
            border-radius: 4px;
        }

        tr {
            height: 60px;
            text-align: center;
        }


        .active {
            background-color: #EEE;
        }

        table {
            width: 100%;
        }

        table,
        th,
        td {
            border: 1px solid #CCC;
            /* 合并边框 */
            border-collapse: collapse;
        }

        label {
            cursor: pointer;
        }

        input[type='checkbox'] {
            width: 16px;
            height: 16px;
            vertical-align: middle;
        }

        .btn {
            border: 0;
            width: 70px;
            line-height: 35px;
            text-align: center;
            color: #555;
            background: #EEE;
            border-radius: 4px;
            cursor: pointer;
            font-weight: 700;
            outline: 0;
            margin: 0 2px;
        }

        .btn.danger {
            background-color: #D9534F;
            color: #FFF;
        }

        .btn.success {
            background-color: #337AB7;
            color: #FFF;
        }

        .line {
            border-bottom: 1px solid #DDD;
            margin: 10px 0;
        }

        .btn-cart {
            width: 30px;
            height: 30px;
            background: #CCC;
            border: 0;
            outline: none;
            cursor: pointer;
        }
    </style>
    <script src="./vue.js"></script>
</head>

<body>
    <div class="container" id="app">
        <h1>购物车</h1>
        <table cellpadding="0" cellspacing="0" width="100%">
            <thead>
                <tr class="active">
                    <th width="80">
                        <label><input type="checkbox" v-model="checked" @change="toggleChecked">&nbsp;全选</label>
                    </th>
                    <th>商品</th>
                    <th>单价</th>
                    <th>数量</th>
                    <th>小计</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(goods,index) in goods_list">
                    <td>
                        <input type="checkbox" v-model="goods.checked" @change="childCheck"/>
                    </td>
                    <td>

                        <img style="height: 120px;"
                            :src="goods.goodsimg"
                            alt="">
                        <h5>{{ goods.goodsname }}</h5>

                    </td>
                    <td>&yen;{{ goods.price }}</td>
                    <td>
                        <button class="btn-cart" @click="computed('d',index)">-</button>
                        {{ goods.num }}
                        <button class="btn-cart" @click="computed('u',index)">+</button>

                    </td>

                    <td>&yen;{{ goods.num*goods.price }}</td>
                    <td>
                        <button class="btn danger">删除</button>
                    </td>
                </tr>
                <tr>
                    <td colspan="6" style="text-align: left;">
                        <b style="color:red">
                            &nbsp;订单总金额: &yen;{{ total }}
                        </b>
                    </td>
                </tr>

            </tbody>
        </table>
    </div>
</body>
<script>
    var vue = new Vue({
        el: "#app",
        data: {
            checked: false,
            goods_list: [{
                id: 1,
                goodsname: "vivo IQ777",
                goodsimg: "https://img12.360buyimg.com/seckillcms/s280x280_jfs/t1/166249/4/1781/100467/5ffc0654Eb618aa21/2188e4ef3f6abe7e.jpg.webp",
                price: 2999,
                num: 1,
                checked: false
            },
            {
                id: 2,
                goodsname: "小米10",
                goodsimg: "https://img10.360buyimg.com/seckillcms/s280x280_jfs/t1/97161/40/12127/66234/5e440190E7cd0f54e/33627b2c39a67241.jpg.webp",
                price: 998,
                num: 1,
                checked: false
            },
            {
                id: 3,
                goodsname: "传世的珐琅锅",
                goodsimg: "https://img20.360buyimg.com/seckillcms/s280x280_jfs/t1/168750/15/16697/127861/606c22c0Eca19515e/5adfe8e452fffbff.png.webp",
                price: 1768,
                num: 1,
                checked: true
            },
            {
                id: 4,
                goodsname: "蔻驰的丑包",
                goodsimg: "https://img12.360buyimg.com/ceco/s300x300_jfs/t1/119430/19/3585/133796/5eb12fe7E1a4ee264/392d83858bb8cd52.jpg!q70.jpg.webp",
                price: 17865,
                num: 1,
                checked: false
            }
            ]
        },
        methods: {
            computed(type,index){
                console.log(type)
                if(type == "u"){
                    this.goods_list[index].num++
                }else{
                    if(this.goods_list[index].num>1){
                        this.goods_list[index].num--
                    }
                }
            },
            toggleChecked(){
                //this.checked === false 全选
                this.goods_list.forEach(element => {
                    element.checked = this.checked
                });
            },
            childCheck(){
                var ckd = true;
                this.goods_list.forEach(element => {
                    if(!element.checked){
                        ckd = false
                    }
                });
                this.checked = ckd
            }
        },
        computed: {
            total(){
                var price = 0;
                this.goods_list.forEach(element => {
                    if(element.checked){
                        price += element.price*element.num
                    }
                });
                return price
            }
        }
    })
</script>
</html>

删除

del(index){
    this.goods_list.splice(index,1)
},

百度案例优化

jsonp

跨域问题:同源问题,在浏览器当中,为了安全,不同域名或相同域名不同端口,或者相同域名和端口,不同协议,都称为不同源的请求,不同的地址之间不可以直接发送ajax或者表单请求,但是可以发生a标签,img标签,script标签的get请求。

jsonp可以利用script标签进行数据发送,所以也先天可以免疫跨域问题,但是只能完成get请求。

<!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>
    <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        li {
            list-style: none;
        }
        .container{
            width: 600px;
            margin: 20px auto;
        }
        
        .form-control {
            padding: 10px;
            width: 100%;
            border: 1px solid #DDD;
            border-radius: 4px;
            vertical-align: middle;
            outline: none;
        }
        .options{
            background: #EEE;
        }
        .options li{
            line-height: 30px;
            padding: 0 10px;
            cursor: pointer;
        }
        .options li:hover{
            background: cornflowerblue;
            color:#FFF;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="container">
            <input class="form-control" type="text" placeholder="请输入搜索关键词" v-model="keywords"/>
            <ul class="options">
                <li v-for="v in search_list">{{ v }}</li>
            </ul>
        </div>
    </div>
</body>
<script>
    var vue = new Vue({
        el: '#app',
        data:{
            keywords: "",
            search_list: []
        },
        watch:{
            keywords(value){
                var url = "https://suggestion.baidu.com/su?cb=callback&wd="+value
                const script = document.createElement('script')
                if(this.keywords.trim() !== ""){
                    script.src = url
                }
                document.body.appendChild(script)
            }
        }
    });
    function callback(res){
        vue.search_list = res.s
    }
</script>
</html>

总结:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值