前端vue之属性指令、style和class、条件渲染、列表渲染、事件处理、数据双向绑定、表单控制、v-model进阶
阅读原文时间:2022年04月13日阅读:1

今日内容概要

  • 属性指令
  • style和class
  • 条件渲染
  • 列表渲染
  • 事件处理
  • 数据的双向绑定
  • v-model进阶
  • 购物车案例

内容详细

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>

    <style>
        .red {
            background: red;
        }

        .green {
            background: green;
        }
    </style>
</head>
<body>
<div id="app">
    <button @click="changeBac">点我变色</button>
    <!--    <p v-bind:class="p_class">{{name}}</p>-->
    <p :class="p_class">{{name}}</p>

    <button @click="changePhoto">点我切换美女</button>
    <div>
        <img :src="url" alt="" width="400px" height="400px">
    </div>
</div>

</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            name: '阿祖',
            p_class: 'red',
            url: 'https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg',
        },

        methods: {
            changeBac() {
                this.p_class = 'green'
            },
            changePhoto() {
                this.url = 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic%2F09%2F3a%2Fbc%2F093abce7b31f4c8ffdbf345375ff4abb.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652321528&t=3709d1c880107a53d265f936022f0d53'
            }
        }
    })
</script>
</html>

# 属性指令中比较特殊的有style和class
    class 可以对应字符串,数组(推荐),对象
    style 可以对应字符串,数组,对象(推荐)

# 语法:
    :属性名=js变量/js语法

    :class=’js变量、字符串、js数组’
    class:三目运算符、数组、对象{red: true}

    :style=’js变量、字符串、js数组’
    style:三目运算符、数组[{backgreound: ‘red’},]、对象{background: ‘red’}


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>

    <style>
        .red {
            background: red;
        }
        .font {
            font-size: 60px;
            text-align: center;
        }
        .green {
            background: green;
        }
    </style>
</head>

<body>
<div id="app">
    <h1 :class="h1_class">我是class的h1</h1>

    <h1 :style="h1_style">我是style的h1</h1>
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            // class 可以对应字符串,数组(推荐),对象
            // h1_class:'green font',
            // h1_class:['green',]  //在控制台给h1_class添加一个元素
            h1_class: {'green': true, 'font': false},

            // style 可以对应字符串,数组,对象(推荐)
            // h1_style:'background: pink;font-size:80px'
            // h1_style:[{background:'pink'},{'font-size':'100px'}],
            // h1_style:[{background:'pink'},{fontSize:'200px'}],  // 不用引号,就要使用驼峰
            // h1_style:{background:'red','font-size':'40px'},
            h1_style: {background: 'red', fontSize: '40px'},
        },
    })
</script>
</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">
    <h2>您的成绩是:</h2>
    <p v-if="score>90">优秀</p>
    <p v-else-if="score>80">良好</p>
    <p v-else-if="score>60">及格</p>
    <p v-else>不及格</p>
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            score: 99,
        },
    })
</script>
</html>

4.1 v-if+v-for+v-else控制购物车商品的显示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <h1>购物车如下</h1>
    <div v-if="good_list.length>0">
        <table border="1">
            <tr>
                <td>商品名字</td>
                <td>商品价格</td>
            </tr>
            <tr v-for="good in good_list">
                <td>{{good.name}}</td>
                <td>{{good.price}}</td>
            </tr>
        </table>
    </div>

    <div v-else>
        购物车空空如也
    </div>
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            good_list: [{name: "特斯拉", price: 100203}, {name: "鸡蛋", price: 2}, {name: "猪肉", price: 35}]
        },
    })
</script>
</html>

4.2 v-for遍历数组(列表)、对象(字典)、数字

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <h1>购物车如下</h1>
    <div v-if="good_list.length>0">
        <table border="1">
            <tr>
                <td>商品名字</td>
                <td>商品价格</td>
            </tr>
            <tr v-for="good in good_list">
                <td>{{good.name}}</td>
                <td>{{good.price}}</td>
            </tr>
        </table>
    </div>

    <div v-else>
        购物车空空如也
    </div>
    <hr>

    <h1>遍历对象(第一个是value,第二个是key)</h1>
    <p v-for="item in info">{{item}}</p>
    <hr>
    <p v-for="(v,k) in info" :key="k">key值是:{{k}}--value值是:{{v}}</p>

    <h1>遍历数组</h1>
    <ul>
        <li v-for="girl in girls">{{girl}}</li>
    </ul>
    <hr>
    <ul>
        <li v-for="(v,i) in girls">第{{i}}个女孩是:{{v}}</li>
    </ul>

    <h1>遍历数字,从1开始</h1>
    <p v-for="i in 5">第{{i}}个数字</p>
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            good_list: [{name: "特斯拉", price: 100203}, {name: "鸡蛋", price: 2}, {name: "猪肉", price: 35}],
            info: {name: 'lqz', age: 19, gender: '男'},
            girls: ['迪丽热巴', '刘亦菲', '杨颖', '糖宝']
        },
    })
</script>
</html>

4.3 注意

# 注意!在Vue中:
    数组的index和value是反的
    对象的key和value也是反的

# key值的解释
    看到别人代码在循环时,写在标签中  :key='值'
    key:一般咱么在循环的时候,都要加 :key='值',值不要是固定的

    vue中使用的是虚拟DOM,会和原生的DOM进行比较,然后进行数据的更新,提高数据的刷新速度(虚拟DOM用了diff算法)

    在v-for循环数组、对象时,建议在控件/组件/标签写1个key属性,属性值唯一
    页面更新之后,会加速DOM的替换(渲染)
    :key="变量"

# key可以加速页面的替换--》key加上,效率高

# 数组更新与检测
# 数组追加一个值---页面里面跟着变
    可以检测到变动的数组操作:
        push:最后位置添加
        pop:最后位置删除
        shift:第一个位置删除
        unshift:第一个位置添加
        splice:切片
        sort:排序
        reverse:反转

    检测不到变动的数组操作---页面不会变
        filter():过滤
        concat():追加另一个数组
        slice():
        map():
    原因:
        作者重写了相关方法(只重写了一部分方法,但是还有另一部分没有重写)

# 数组变了,但页面没变---》解决方案
    // 方法1:通过 索引值 更新数组(数据会更新,但是页面不会发生改变)
        vm.arrayList[0]
        "Alan"
        vm.arrayList[0]='Darker'
        "Darker"

    // 方法2:通过 Vue.set(对象, index/key, value) 更新数组(数据会更新,页面也会发生改变)
        Vue.set(vm.arrayList, 0, 'Darker')


# input标签---》跟js变量绑定


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <input type="text" v-model="text">--->{{text}}
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            text: ''
        },
    })
</script>
</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">
    change: <input type="text" v-model="text" @change="handleChange">
    <hr>
    input: <input type="text" v-model="text1" @input="handleInput">
    <hr>
    blur:<input type="text" v-model="text2" @blur="handleBlur">
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            text: '',
            text1: '',
            text2: '',
        },
        methods: {
            handleChange() {
                console.log('change触发:', this.text)
            },
            handleInput() {
                console.log('input触发:', this.text1)
            },
            handleBlur() {
                console.log('blur触发:', this.text2)
            },
        }
    })
</script>
</html>

6.1 过滤案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <input type="text" v-model="text" @input="handleInput">---》{{text}}
    <ul>
        <li v-for="data in newdataList">{{data}}</li>
    </ul>
</div>
</body>

<script>
    // 补充 filter
    // var newdataList = ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf']
    // var l = newdataList.filter(function (item) {
    //     if (item.length > 2) {
    //         return true
    //     } else {
    //         return false
    //     }
    // })
    // console.log(l)

    // 补充:判断一个字符串是否在另一个字符串中
    // var text = 'at'
    // var newdataList = ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf']
    // var l = newdataList.filter(function (item) {
    //     var i = item.indexOf(text)
    //     if (i >= 0) {
    //         return true
    //     } else {
    //         return false
    //     }
    // })

    // 同上 --简写
    // var l = newdataList.filter(function (item) {
    //     return item.indexOf(text) >= 0
    // })
    // console.log(l)

    // 箭头函数  -es6
    // var a = function (name) {
    //     console.log(name)
    // }
    // a('lqz')

    // 同上 --简写 箭头函数没有自己的this
    // var a = (name) => {
    //     console.log(name)
    // }
    // a("lqz")

    var vm = new Vue({
        el: "#app",
        data: {
            text: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
            newdataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
        },
        methods: {
            handleInput() {
                console.log(this)
                // var _this = this
                // // 只要text发生变化,newdataList就变化,就过滤
                // this.newdataList = this.dataList.filter(function (item) {
                //     // js 中this指向的问题
                //     console.log(this)
                //     return item.indexOf(_this.text) >= 0
                // })

                // es6 处理this指向,箭头函数
                this.newdataList = this.dataList.filter((item) => {
                    // js 中this指向的问题
                    console.log(this)
                    return item.indexOf(this.text) >= 0
                })
            },
        }
    })
</script>
</html>

6.2 事件修饰符

# 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生
    用 v-on:click.prevent.self 会阻止所有的点击
    而 v-on:click.self.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">
    <ul @click.self="handleUl">
        <li @click.stop="handleC('刘亦非')">刘亦菲</li>
        <li @click="handleC('杨颖')">杨颖</li>
        <li>迪丽热巴</li>
    </ul>
    <hr>
    <a href="http://www.baidu.com" @click.prevent="handleA">点我看美女</a>
    <hr>
    <button @click.once="handleSubmit">点我秒杀</button>
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {},
        methods: {
            handleUl() {
                console.log('ul被点解了')
            },
            handleC(name) {
                console.log(name, '被点击了')
            },
            handleA() {
                // 允许跳,不允许跳
                console.log('a被点击了')
                // location.href='http://www.baidu.com'
            },
            handleSubmit() {
                console.log('秒杀按钮被点击了')
            }
        }
    })
</script>
</html>

6.3 按键修饰符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
<!--    <input type="text" v-model="mytext" v-on:keyup="handleKeyUp">-&ndash;&gt;{{mytext}}-->
<!--    简写:-->
    <input type="text" v-model="mytext" @keyup="handleKeyUp($event)">--->{{mytext}}
    <hr>
    <input type="text" v-model="mytext" @keyup.enter="handleKeyUp2($event)">--->{{mytext}}
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            mytext: '',
        },
        methods: {
            handleKeyUp(event) {
                console.log(event)
                console.log(event.key, '被按下弹起了')
                if (event.key == 'Enter') {
                    alert('美女你好')
                }
            },
            handleKeyUp2(event) {
                console.log(event.key, '被按下弹起了')
            },
        }
    })
</script>
</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">
    <h1>checkbox单选</h1>
    <p>用户名:<input type="text" v-model="username"></p>
    <p>密码:<input type="password" v-model="password"></p>
    <p>记住密码:<input type="checkbox" v-model="remember"></p>
    <hr>
    {{username}}---{{password}}--{{remember}}
    <br>

    <h1>radio单选</h1>
    <input type="radio" v-model="radio" value="1">男
    <input type="radio" v-model="radio" value="2">女
    <input type="radio" v-model="radio" value="0">保密
    <br><br>您选择的性别:{{radio}}
    <hr>

    <h1>checkbox多选</h1>
    <input type="checkbox" v-model="many" value="篮球">篮球
    <input type="checkbox" v-model="many" value="足球">足球
    <input type="checkbox" v-model="many" value="棒球">棒球
    <input type="checkbox" v-model="many" value="桌球">桌球
    <br><br>您喜欢的球类:{{many}}
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            username: '',
            password: '',
            remember: true,  // checkbox单选,布尔
            radio: '',  // redio的单选字符串,对应选中的value值
            many: [],  //checkbox多选---》数组
        },
        methods: {}
    })
</script>
</html>

# v-model 之 lazy、number、trim
    lazy:等待input框的数据绑定时区焦点之后再变化

    number:数字开头,只保留数字,后面的字母不保留;字母开头,都保留

    trim:去除首位的空格


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    lazy: <input type="text" v-model.lazy="username">--->{{username}}
    <br>
    number:<input type="text" v-model.number="age">--->{{age}}
    <br>
    trim:<input type="text" v-model.trim="info">--->{{info}}
    <br>
</div>
</body>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            username: '',
            age: '',
            info: '',
        },
        methods: {}
    })
</script>
</html>