72、事件指令补充、属性指令、style和class、条件渲染、列表渲染、事件处理、数据的双向绑定、过滤案例

147 阅读3分钟

事件指令的补充

vm对象

1.写在data或method中的属性或方法,从vm中直接可以 . 出来
2.methods的函数中,如果想使用data或methods中的属性,直接this.名字  就可以了
3.在前端控制台,可输入vm.name  vm.age. vm.$data,获取值
<!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>{{name}}</h1>
    <button @click = 'handleClick'>点我</button>
</div>
</body>

<script>
    var vm = new Vue({
        el:'#app',
        data:{
            name:'nana',
            age :19,
        },
        methods:{
            handleClick(){
                console.log(this)  //Vue
                this.handleClick1()

            },
            handleClick1(){
                console.log(this) //Vue
                this.name = 'cx'
            }
        }
    })

</script>
</html>

函数传参

1.在事件指令给函数传参中:
	1.函数,可以多传参数,也可也少传参数,都不会报错
  2.事件对象,调用函数,不传参数,会把当前事件对象传入,可以不接受,也可以接
  3.当有参数的时候,想要获取事件对象,参数:$event
  
2.vue:事件函数,如果不传参数,默认其实有一个event对象
    1.手动传,在view中: 函数名($event)
    2.想使用data中的数据,直接this. 即可:但是这里有坑  this指向的问题
    3.methods的函数中,没有嵌套其它函数,this 就是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'>
    <h1>函数,可以多传参数,也可也少传参数,都不会报错</h1>
    <button @click = 'handleClick("nana")'>点我</button>
    <h1>事件对象,调用函数,不传参数,会把当前事件对象传入,可以不接受,也可以接</h1>
    <button @click = 'handleClick2'>点我</button>
    <h1>当有参数的时候,想要获取事件对象,参数:$event</h1>
    <button @click="handleClick3('nana',$event)">点我3</button>
</div>
</body>

<script>

    var vm = new Vue({
        el:'#app',
        data:{
        },
        methods:{
            handleClick(name,age){
                console.log(name,age)  //nana undefined
            },
            handleClick2(event){
                console.log(event) //PointerEvent{...}
            },
            handleClick3(name,event){
                console.log(name,event)// nana PointerEvent{...}
            }
        }
    })

</script>
</html>

属性指令

1.标签上的属性:name、idclass 、src、href、height等属性
	如果这样:name='xx' 就写死了,我们想动态的绑定变量,使变量变化,属性的值也变化
    
2.v-bind:属性名='变量'
	简写成: :属性名='变量'

属性指令的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src = './js/vue.js'></script>
</head>
<body>
<div id = 'app'>
    <button  @click ="handleClick" >点我换美女</button>
    <img v-bind:src="img" alt="" height="300px">

    <hr>
    <button @click="handleClick1">点我美女变大</button>
    <img v-bind:src="img_bigger" alt="" :height="h" >
</div>
</body>
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            img:'/img/1.jpg',
            img_bigger:'/img/1.jpg',
            h:'300px'
        },
        methods:{
          handleClick(){
              this.img = '/img/3.jpg'
          },
            handleClick1(){
              this.h ='500px'
            }
 
        }
    })
</script>
</html>

切换图片

需求:点击按钮开始,图片每隔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'>
    <button @click="setTime">开始选图片</button>
    <img :src="img" alt="" height="300px" @click = 'handleStop'>

</div>
</body>

<script>

    var vm = new Vue({
        el:'#app',
        data:{
            img:'/img/1.jpg',
            img_list : ['/img/1.jpg','/img/2.jpg','/img/3.jpg','/img/4.jpg','/img/5.jpg','/img/6.jpg','/img/7.jpeg'],
            t : null

        },
        methods:{
        handleClick(){
             //Math.random() 生成0--1之间的小数
            //this.img_list.length: 列表长度
            // Math.floor 向下取整
            // 能返回一个数组大小以内的数字()
            var index= Math.floor(Math.random()*this.img_list.length)
            this.img = this.img_list[index]
        },
        setTime(){
           
            this.t = setInterval(this.handleClick,1000)
        },
        handleStop(){
            clearInterval(this.t)
            this.t = null
        }

        }
    })
</script>
</html>

style与class

style 和 class 也是属性,可以使用属性指令  :class=   :style=   
但是他们比较特殊

style

1.style 推荐使用对象形式
2.style 绑定的变量,类型可以是 字符串,数组,对象
<!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>style 的使用:字符串,数组,对象</h1>
    <div style="font-size: 80px;background-color: greenyellow">oo</div>
    <div :style="style_str">div-str</div>
    <div :style="style_arr">div-arr</div>
    <div :style="style_obj">div-obj</div>
</div>
</body>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            // style 推荐使用   对象形式
            style_str: 'font-size: 80px;background-color: green',// vm.style_str='background-color: red'
            style_arr:[{"font-size":'60px'},] ,//vm.style_arr.push({'background-color':'red'})
            // style_obj:{'font-size':'60px','background-color':'green'},
            style_obj:{'fontSize':'60px','backgroundColor':'green'},   // 省略key值的引号后,要变成驼峰形式
            
        },
    })
</script>
</html>

class

1.class:推荐使用 数组方式
2.class 绑定的变量,类型可以是 字符串,数组,对象
3.对象的用法,必须先提前设置,后期通过修改true或false控制类
4.可以通过:Vue.set()来设置class的属性值
	eg:Vue.set(this.class_obj,'yellow',true)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src = './js/vue.js'></script>
    <style>
         .size {
            font-size: 60px;
        }

        .red {
            background-color: red;
        }

        .yellow {
            background-color: yellow;
        }

    </style>

</head>
<body>
<div id = 'app'>
    <h1>class 的使用:字符串,数组,对象</h1>
    <button @click = 'handleClick'>点我变样式</button>
    <div :class = 'class_str'>div-str</div>
    <div :class = 'class_arr'>div-arr</div>
    <div :class = 'class_obj'>div-obj</div>
    <br>
</div>

</body>
<script>
    var vm = new Vue({
        el:'#app',
        data:{
            // class 推荐使用 数组方式
            // class 绑定的变量,类型可以是 字符串,数组,对象
            class_str:'size',  //vm.class_str='red size'
            class_arr:['red'], //vm.class_arr.push('size'),给该变量追加值,class发生变化,页面会发生变化
            // class_obj:{size: true,red:false} //vm.class_obj['red'] = true  对象的用法,必须先提前设置,后期通过修改true或false控制类
            class_obj: {size: true},// 但是不能往对象中放之前不存在的值,放不存在的值,没有响应式

        },
        methods:{
            handleClick(){
                // this.class_obj.yellow = true  // 直接放,没有响应式
                Vue.set(this.class_obj,'yellow',true)  // 这样才有响应式
            }
        }
    })
</script>
</html>

条件渲染

指令释义
v-if相当于: if
v-else相当于:else
v-else-if相当于:else if

效果:根据学生分数,显示学生的 优秀,良好

<!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>
        请输入你的成绩: <input type="text" v-model="score">-->{{score}}
    </p>
    <h2>你的等级是:</h2>
    <div v-if="score>=90&&score<=100">优秀</div>
    <div v-else-if="score>=80&&score<90">良好</div>
    <div v-else-if="score>=60&&score<=80">及格</div>
    <div v-else-if="score>0&&score<60">不及格</div>
    <div v-else>输入不合法</div>
    
</div>
</body>
<script>
    var vue = new Vue({
        el:'#app',
        data:{
            score:'',
        },
        created(){
            console.log(this.score,typeof this.score)
        }
    })
</script>
</html>

列表渲染

1.循环渲染一些数据,比如购物车的数据
2.v-for:循环字符串,数组,数字,对象

效果:有购物车数据,循环显示再页面中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js'></script>
    <script src='https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"
            integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd"
            crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css"
          integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
    <script src='./js/vue.js'></script>
</head>
<body>
<div id='app'>
    <div class="container-fluid">
        <div class="row">
            <div class='col-md-6 col-md-offset-3'>
                <h1 class="text-center">商品展示</h1>
                <button @click="ClickShow">展示商品</button>
                <table class="table table-hover table-striped" v-if='is_show'>
                    <thead>
                    <tr>
                        <th>商品id</th>
                        <th>商品名</th>
                        <th>商品数量</th>
                        <th>商品价格</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr v-for="goods in goods_list">
                        <th scope="row">{{goods.id}}</th>
                        <td>{{goods.name}}</td>
                        <td>{{goods.count}}</td>
                        <td>{{goods.price}}</td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    var vue = new Vue({
        el: '#app',
        data: {
            goods_list: [],
            is_show:false
        },
        methods:{
            ClickShow(){

                this.goods_list=[
                    {'id': 1, 'name': '小汽车', 'count': 2, 'price': 100000},
                    {'id': 2, 'name': '脸盆', 'count': 1, 'price': 23},
                    {'id': 3, 'name': '方便面', 'count': 3, 'price': 6},
                    {'id': 4, 'name': '钢笔', 'count': 4, 'price': 5},
                ]
                this.is_show=true
            }
        }
    })
</script>
</html>

v-for循环其他数据类型

1.v-for可以循环数字,字符串,数组,对象
	ps:数字,字符串,数组:v-for循环:第一个是值,第二个是索引值
			对象:v-for循环:第一个是值,第二个是key值
    
2.看到别人写v-for时,在标签上都会加一个key属性,目的是为了提高虚拟dom的替换效率
<el-carousel-item v-for="item in 4" :key="item">
	ps:key 的值必须唯一,如果不唯一就报错

3.以后如果数据变了,页面没有发生变化,解决:
  Vue.set(对象, key, value)
  Vue.set(数组, 索引, 值)
<!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>
    <ul>
        <li v-for="(value,index) in number">value:{{value}}--->index:{{index}}</li>
    </ul>
    <h1>循环字符串</h1>
    <ul>
        <li v-for="(value,index) in str">value:{{value}}--->index:{{index}}</li>
    </ul>
    <h1>循环数组</h1>
    <ul>
        <li v-for="(value,index) in arr">value:{{value}}--->index:{{index}}</li>
    </ul>
    <h1>循环对象</h1>
    <ul>
        <li v-for="(value,index) in obj">value:{{value}}--->key:{{index}}</li>
    </ul>
    
</div>
</body>
<script>
    var vue = new Vue({
        el: '#app',
        data: {
            number: 10,
            str: 'hello world!',
            arr: [11, 22, 33, 55, 44],
            obj: {name: 'nana', age: 19, gender: 'female'}
        },
    })
</script>
</html>

事件处理

事件释义
input当输入框进行输入的时候 触发的事件
change当元素的值发生改变时 触发的事件
blur当输入框失去焦点的时候 触发的事件
click点击事件
<!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>input事件</h1>
    <input type="text" @input="handelInput" v-model="username">--->{{username}}
    <br>
    <h1>change事件</h1>
    <input type="text" @change="handleChange" v-model="username1">--->{{username1}}
    <h2>blur事件</h2>
    <input type="text" @blur='handleBlur' v-model="username2">--->{{username2}}

</div>

</body>
<script>
    var vue = new Vue({
        el: '#app',
        data: {
            username: '',
            username1: '',
            username2: '',
        },
        methods: {
            handelInput() {
                console.log(this.username, 'input事件执行了')
            },
            handleChange() {
                console.log(this.username, 'change事件执行了')
            },
            handleBlur() {
                console.log(this.username, 'blur事件执行了')
            },
        },
    })
</script>
</html>

数据的双向绑定

1.数据双向绑定:只针对input标签,v-model做双向数据绑定
2.之前写的,其实都是数据的单向绑定
3.v-model可以实现修改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'>
    <h1>数据的单向绑定</h1>
    <p>用户名: <input type="text" :value="username"></p>
    <p>密码: <input type="password" :value="password"></p>
    <p>
        <button @click='handleSubmit'> 登陆</button>
    </p>
    <hr>
    <h1>数据的双向绑定</h1>
    <p>用户名: <input type="text" v-model="username1"></p>
    <p>密码: <input type="password" v-model="password1"></p>
    <p>
        <button @click='handleSubmit1'> 登陆</button>
    </p>
</div>
</body>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            username: 'nana',
            password: '123',
            username1: '',
            password1: '',
        },
        methods: {
            handleSubmit() {
                console.log(this.username, this.password)
            },
            handleSubmit1() {
                console.log(this.username1, this.password1)
            },
        }
    })
</script>
</html>

补充知识

数组的过滤

数组.filter(匿名函数)

    var arr = ['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf']
    //数组.filter(匿名函数)-->匿名函数接受一个参数,函数必须返回true或者false,如果返回true,表示这个值保留
    var new_arr = arr.filter((item)=>{
        console.log(item)
        if (item.length >3){
            return true
        }else {
            return false
        }
    })
    console.log(new_arr)  //['atom', 'attoo', 'beyond', 'csrf']

判断一个子字符串,是否在另一个字符串中

var s = 'is'
var s1 ='he is bad boy'
var res = s1.indexOf(s)
console.log(res)

过滤案例

<!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>搜索内容:
        <input type="text" v-model="search" @input="handleInput"> -->{{search}}</p>
    <ul>
        <li v-for="item in new_arr">{{item}}</li>
    </ul>
</div>
</body>
<script>
    var vm = new Vue({
        el:'#app',
        data: {
            search: '',
            arr: ['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf'],
            new_arr:['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf']
        },
        methods: {
            handleInput() {
                // console.log('出发了')
                this.new_arr= this.arr.filter((item) => {
                    if (item.indexOf(this.search) >= 0) {
                        return true
                    } else {
                        return false
                    }

                })
                console.log(this.new_arr)
            }
        }

    })

</script>
</html>