vue之事件指令&属性指令&条件渲染&列表渲染&数据双向绑定&处理事件&过滤案例

发布时间 2023-06-06 15:48:08作者: 雀雀飞了

1.事件指令

v-on:事件名='函数'-----简写成  @事件名='函数'

1.1 vm对象和vm函数传参

<div id="vmobj">
    <h1>vm对象</h1>
    <h2>{{name}}</h2>
    <button @click="handleClick">点击!</button>
    <!--    1 写在data或methods中的属性或方法,从vm中直接可以 . 出来,这是data和methods的配置项上升到vm对象:vm.name;vm.handleclick-->
    <!--    2 this指代当前Vue的实例对象,之前属性需要vm.$data.name中取出来。this.name 就是 vm.$data.name。methods的函数中,如果想使用data或methods中的属性,直接this.名字 就可以了-->
    <h1>vm函数传参</h1>
    <button @click="handlePush('bengshaka',18)">按下!</button>
    <!--    3 函数,可以多传参数,也可也少传参数,都不会报错-->
    <h1>事件对象</h1>
    <button @click="handlePush1">按⬇️!</button>
    <button @click="handlePush2('bengshaka',$event)">按?!</button>
    <!--    4 事件对象,调用函数,如果不传参数,会把当前事件对象传入,可以不接收,也可以接收;手动传的话,写$event-->
</div>
// 事件指令start
let vm1 = new Vue({
    el: "#vmobj",
    data: {name: '雀雀', age: 33},
    methods: {
        handleClick() {
            console.log(this)
            this.name = '菲菲'

            this.handleClick1()
        },
        handleClick1() {
            this.name = '春春'
        },
        handlePush(name, age) {
            console.log(name, age)
        },
        handlePush1(event) {
            console.log(event)
        },
        handlePush2(name, event) {
            console.log(name, event)
        },
    }

})
// 事件指令end

2.属性指令

v-bind:属性名='变量名',简写成 :属性名='变量名'
<!--2 属性指令start-->
<div id="attr">
    <!--    标签上的name、id、class、src、href、height都是属性。如果写成name="pyy"就写死了,我们想动态地绑定变量,即变量变化属性的值也随之变化-->
    <h1>标签属性</h1>
    <!--    点击按钮后切换成另一张图片-->
    <button @click="foodClick">中午吃啥么?</button>
    <!--    点击按钮后图片变小-->
    <button @click="smallClick">变小变小</button>
    <hr>
    <img :src="url" alt="" :height="h">
    <br>
    <!--    每隔一秒随机切换图片,且点击图片时图片停止切换-->
    <button @click="spongeClick">?</button>
    <hr>
    <img :src="link" alt="" @click="finishClick">
</div>
<!--特殊属性style和class-->
<div id="specialattr">
    <h1>class的使用</h1>
    <div :class="class_str">字符串div</div>
    <div :class="class_arr">数组div</div>
    <div :class="class_obj">对象div</div>
    <button @click="changecolor">点我变样式</button>
    <h1>style的使用</h1>
    <div :style="style_str">字符串div</div>
    <div :style="style_arr">数组div</div>
    <div :style="style_obj">对象div</div>

</div>
<!--属性指令end-->
// 属性指令start
let vm2 = new Vue({
    el: "#attr",
    data: {
        url: 'https://img1.baidu.com/it/u=3528793185,2081042586&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=667',
        h: '800px',
        link: 'https://img1.baidu.com/it/u=1535498233,212421436&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
        img_list: [
            'https://img1.baidu.com/it/u=1935211653,3753972112&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
            'https://img1.baidu.com/it/u=110959689,3641660006&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
            'https://img2.baidu.com/it/u=874958372,1611128489&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
            'https://img2.baidu.com/it/u=3682247877,3328738795&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
            'https://img0.baidu.com/it/u=3148234475,2234042550&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
            'https://img1.baidu.com/it/u=280615882,1185979654&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
            'https://img0.baidu.com/it/u=1443008156,2260840723&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
            'https://img1.baidu.com/it/u=1276976048,865890998&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400',
        ],
        t: null
    },
    methods: {
        foodClick() {
            this.url = 'https://img0.baidu.com/it/u=3193953794,3699765169&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=667'
        },
        smallClick() {
            this.h = '400px'
        },
        spongeClick() {
            // 定时器,每隔一段时间干什么setInterval(匿名函数,间隔时间)
            // link随机从列表中取值,赋值给link,Math.random()生成0-1之间小数,Math.floor()向下取整,返回的res为任意一个数组内的索引
            // 这里不可以直接用this,因为this在匿名函数之中,指向发生了变化,需要中转
            var _this = this
            this.t = setInterval(function () {
                var res = Math.floor(Math.random() * _this.img_list.length)
                _this.link = _this.img_list[res]
            }, 1000)

        },
        finishClick() {
            // 停止计时器
            clearInterval(this.t)
            this.t = null
        }
    },
})
let vm3 = new Vue({
    el: '#specialattr',
    data: {
        // class 绑定的变量,类型可以是字符串,数组,对象,推荐数组
        // class_str 字符串类型改的话要全部修改,不方便,vm3.class_str='size blue'
        class_str: 'size',
        // class_arr 头部追加unshift删除shift,尾部追加push弹出pop;给该变量变化值,class变化,页面会发生变化
        class_arr: ['size', 'blue'],
        // class_obj 必须先提前设置属性key,后期通过修改value的true或false控制类,但是不能往对象中放之前不存在的值,导致没有响应式。因为vue只对先前写的key进行监听,后续写进去的虽然进到对象里但是不进行监听数据变化,没有做数据劫持。如果想达到后续新增key生效,有一个方法:Vue.set(obj,key,value),这样有响应式。
        class_obj: {size: true},
        // style 绑定的变量,类型可以是字符串、数组、对象,推荐对象
        // style_str 字符串类型改的话要全部修改,不方便,vm3.style_str='font-size:30px'
        style_str: 'font-size:30px;background-color:green',
        // style_arr 数组套对象[{},{},{},],追加是push({})
        style_arr: [{'font-size': '30px'}],
        // 同上修改用set,其中key的引号可以省略,但是会报错,需要将key的书写形式由横杠改为驼峰形式
        style_obj: {'font-size': '30px', backgroundColor: 'green'},
    },
    methods: {
        changecolor() {
            Vue.set(this.class_obj, 'blue', true)
        }
    },
})
// 属性指令end

3.条件渲染

v-if  v-else-if   v-else
<!--3 条件指令start-->
<div id="condition">
    <h6>根据学生分数,显示学生的 优秀,良好</h6>
    <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>不及格</div>
</div>
<!--条件指令end-->
// 条件指令start
let vm4 = new Vue({
    el: "#condition",
    data: {
        score: 88,
    },
})
// 条件指令end

4.列表渲染

<!--v-for="i in data或methods里的属性",循环字符串,数组,数字,对象 ,v-for的使用,配合插值语法-->
<!--看到别人写v-for时,在标签上都会加一个key属性,目的是为了提高虚拟dom的替换效率
<el-carousel-item v-for="item in 4" :key="item">
key 的值必须唯一,如果不唯一就报错-->
<!--4 列表渲染start-->
<div id="list">
    <!--    循环渲染购物车的数据-->
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h1 class="text-center">购物车</h1>
                <button class="btn pull-right btn-danger" @click="showshopping">加载购物车</button>
                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th>id号</th>
                        <th>商品名</th>
                        <th>商品价格</th>
                        <th>商品数量</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr v-for="good in good_list">
                        <th scope="row">{{good.id}}</th>
                        <td>{{good.name}}</td>
                        <td>{{good.price}}</td>
                        <td>{{good.count}}</td>
                    </tr>

                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <h1>循环数字</h1>
    <ul>
        <li v-for="(value,index) in num">{{index}}----->{{value}}</li>
    </ul>
    <h1>循环字符串</h1>
    <ul>
        <li v-for="(value,index) in str">{{index}}----->{{value}}</li>
    </ul>
    <h1>循环数组</h1>
    <ul>
        <li v-for="(value,index) in arr">{{index}}----->{{value}}</li>
    </ul>
    <h1>循环对象(key和value是反的)</h1>
    <ul>
        <li v-for="(value,key) in obj">key=>{{key}}-----value=>{{value}}</li>
    </ul>
</div>
<!--列表渲染end-->
// 列表渲染start
let vm5 = new Vue({
    el: '#list',
    data: {
        good_list: '',
        num: 10,
        str: 'happy',
        arr: [45, 6, 56, 8, 9, 11],
        obj: {name: 'jack', gender: 'male', hobby: "rap"}
    },
    methods: {
        showshopping() {
            this.good_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}]
        }
    },
})
// 列表渲染end

5.数据的双向绑定

<!--咱们之前写的,其实都是数据的单向绑定,即修改js的值,页面变了;数据双向绑定---》只有input标签----》v-model-->
<!--5 数据的双向绑定start-->
<div id="bindtogether">
    <h1>单向数据绑定,咱们不用</h1>
    <p>用户名<input type="text" :value="username"></p>
    <p>密码<input type="password" :value="password"></p>
    <p>
        <button @click="singleSubmit">登录</button>
    </p>
    <h1>双向数据绑定</h1>
    <p>用户名<input type="text" v-model="username"></p>
    <p>密码<input type="password" v-model="password"></p>
    <p>
        <button @click="togetherSubmit">登录</button>
    </p>
</div>
<!--数据的双向绑定end-->
// 数据的双向绑定start
let vm6 = new Vue({
    el: '#bindtogether',
    data: {
        username: '',
        password: '',
    },
    methods: {
        singleSubmit() {
            console.log(this.username)
            console.log(this.password)
        },
        togetherSubmit() {
            console.log(this.username)
            console.log(this.password)
        },
    },
})
// 数据的双向绑定end

6.事件处理

<!--其实就是事件指令如click点击事件,这里特指input标签的事件:input、change、blur-->
<!--6 事件处理start-->
<div id="handleEvent">
    <h1>input:只要输入内容,就会触发</h1>
    <input type="text" @input="handleInput" v-model="inputname" >
    <h1>change:只要输入框发生变化,就会触发</h1>
    <input type="text" @change="handleChange" v-model="changename" >
    <h1>blur:只要失去焦点,就会触发</h1>
    <input type="text" @blur="handleBlur" v-model="blurname" >

</div>
<!--事件处理end-->
// 事件处理start
let vm7 = new Vue({
    el:'#handleEvent',
    data:{
        inputname:'',
        changename:'',
        blurname:'',
    },
    methods:{
       handleInput(){
           console.log(this.inputname)
       },
       handleChange(){
           console.log('我执行了')
       },
       handleBlur(){
           console.log('我失焦了')
       },
    },
})
// 事件处理end

7.过滤器案例

<!--7 过滤案例start-->
<div id="handleFilter">
<input type="text" v-model="search" @input="handleInput">
    <hr>
    <ul>
        <li v-for="data in newdataList">{{data}}</li>
    </ul>
</div>
<!--过滤案例end-->
// 过滤案例start
let vm8 = new Vue({
    el:'#handleFilter',
    data:{
        search:'',
        dataList: ['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf'],
        newdataList: ['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf'],
    },
    methods:{
        handleInput(){
            // 根据用户输入的search,对数组进行过滤,剩下只有包含输入文字的字符串
            this.newdataList=this.dataList.filter(item=>item.indexOf(this.search)>=0)
        }
    },
})
// 过滤案例end

8.补充

// 1 数组的过滤
var arr = ['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf']
// 数组.filer(匿名函数,接受一个参数,函数必须返回true或false,如果返回true,表示这个值保留)
var new_arr = arr.filter(function(item){
    return true // new_arr = arr
})

// 2 判断一个子字符串,是否在另一个字符串中
var s='que'
var s1='queque is cute'
res = s1.indexOf(s) // s的索引位置,如果大于等于0,说明s在s1中
console.log(res) // 0

9.小结

<div style="height: 500px">
    <span>总结:以后如果数据变了,页面没有发生变化,唯一的原因就是没有监控到数据的变化,要使用Vue.set来设置,不仅可以设置obj还可以设置arr</span>
    <p>Vue.set(对象, key, value)</p>
    <p>Vue.set(数组, 索引, 值)</p>
</div>