5

前端vue之属性指令、style和class、条件渲染、列表渲染、事件处理、数据双向绑定、表...

 2 years ago
source link: https://www.cnblogs.com/jgx0/p/16138388.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

今日内容概要

  • style和class
  • 数据的双向绑定
  • v-model进阶
  • 购物车案例

1、属性指令

image

<!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>

image
image

2、style和class

# 属性指令中比较特殊的有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>

image

3、条件渲染

image

<!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>

image

4、列表渲染

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')

5、数据的双向绑定

# 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>

6、事件处理

<!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>

image

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">-–>{{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>

image

image

7、表单控制

<!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>

image

8、v-model进阶

# 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>

image


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK