添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
2 -Vue列表渲染-事件处理-数据的双向绑定-表单控制

2 -Vue列表渲染-事件处理-数据的双向绑定-表单控制

六 列表渲染

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

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>v-if + v-for + v-else控制购物车商品的显示</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    <style>
        table, td {
            border: 1px solid black;
            text-align: center;
    </style>
</head>
<div id="box">
    <h2>我的购物车</h2>
    <button @click="show">刷新购物车</button>
    <br><br>
    <table v-if="!shopping_car.length==0">
            <td>商品名称</td>
            <td>价格</td>
        <tr v-for="item in shopping_car">
            <td>{{item.name}}</td>
            <td>{{item.price}}</td>
    </table>
    <table v-else>
            <td>商品名称</td>
            <td>价格</td>
            <td>暂无信息</td>
            <td>暂无信息</td>
    </table>
</div>
</body>
<script>
    let vm = new Vue({
        el: '#box',
        data: {
            isActive: false,
            shopping_car: []
        methods: {
            show() {
                this.shopping_car = [
                    {name: 'Threadripper 3990X', price: '29999元'},
                    {name: 'NVIDIA RTX 8000', price: '59999元'},
                    {name: 'ROG ZENITH II EXTREME', price: '9999元'},
</script>
</html>



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

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>v-for遍历数组(列表)、对象(字典)</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    <style>
        table, td {
            border: 1px solid black;
            text-align: center;
    </style>
</head>
<div id="box">
    <h2>数组(列表)for循环遍历</h2>
        <li v-for="(value,index) in list_test">{{index}} —— {{value}}</li>
    <h2>对象(字典)for循环遍历</h2>
        <li v-for="(value,key) in dic_test">{{key}} —— {{value}}</li>
    <h2>数组(列表)套对象(字典)for循环遍历</h2>
    <table>
            <td>姓名</td>
            <td>年龄</td>
            <td>性别</td>
            <td>国籍</td>
        <tr v-for="info in summary_test">
            <td>{{info.name}}</td>
            <td>{{info.age}}</td>
            <td>{{info.gender}}</td>
            <td>{{info.country}}</td>
    </table>
</div>
</body>
<script>
    let vm = new Vue({
        el: '#box',
        data: {
            list_test: ['First', 'second', 'Third', 'Forth', 'Fifth'],
            dic_test:{name: 'Darker', age: 18, gender: 'male'},
            summary_test: [
                    {name: 'Alan', age: 23, gender: 'male', country: 'America'},
                    {name: 'Ben', age: 15, gender: 'male', country: 'Australia'},
                    {name: 'Cindy', age: 12, gender: 'female', country: 'Japan'},
                    {name: 'Darker', age: 18, gender: 'male', country: 'China'},
                    {name: 'Elisa', age: 26, gender: 'female', country: 'Mexico'},
</script>
</html>
#注意!在Vue中:
数组的index和value是反的
对象的key和value也是反的

3. key值 的解释

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

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

4. 数组更新与检测

可以检测到变动的数组操作:

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

七 事件处理

#change 和 blur 最本质的区别:
1-如果输入框为空,失去焦点后,change不会触发,但是blur会触发
2-两次输入的值没有变化也不会触发change

1.过滤案例

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>过滤案例</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<div id="box">
    <p><input type="text" v-model="myText" @input="handleInput" placeholder="请输入要筛选的内容:"></p>
    <!-- <p><input type="text" v-model="myText" @change="handleInput" placeholder="请输入要筛选的内容:"></p> -->
    <!-- <p><input type="text" v-model="myText" @blur="handleInput" placeholder="请输入要筛选的内容:"></p> -->
        <li v-for="data in newList">{{data}}</li>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            myText: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
            newList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
        methods: {
            //方式一:由于里面的this指向的是匿名函数function,所以前面是需要重新给他this的值
            // handleInput() {
            //     let _this = this
            //     this.newList = this.dataList.filter(
            //         function (item) {
            //             return item.indexOf(_this.myText) > -1
            //         })
            // },
            //方式二:箭头函数的应用主要是为了处理this指向的问题
            handleInput() {
                this.newList = this.dataList.filter(item => {
                    // item.indexOf(this.myText):输入框中输入的字符串在筛选元素中的索引
                    return item.indexOf(this.myText) > -1   // 返回索引大于1的元素:>-1 就表示包含在其中
</script>
</html>

2.事件修饰符 (阻止事件冒泡事件)

v-on:click.prevent.self 会阻止 所有的点击 v-on:click.self.prevent 只会阻止 对元素自身的点击

<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-lg-6 col-md-offset-3">
            <div id="app">
                <div v-on:click="div_click">
                    //新方法
                    <button @click.stop="button_click">点我看美女</button>
                    //老方法 使用的js操作
                    //<button @click="handleLink">点我看美女</button>
                </div>
                <div v-on:click.self="div_click">
                    <button @click="button_click">点我看美女2</button>
                </div>
                <a href="http://www.baidu.com" @click.prevent="handle_a">链接被阻止访问了</a>
                <button @click.once="handle_one">我只能点一次</button>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {
            div_click() {
                alert('div被点击了')
            button_click() {
                alert('button被点击了')
            handle_a() {
                alert('a链接跳转阻挡了')
                // location.href = 'http://www.baidu.com'
            handle_one() {
                alert('我只会谈一次')
            //使用了stopPropagation,阻止控件的运行
            handleLink(event) {
                console.log('li被点击了')
                event.stopPropagation()    // 点击事件停止 冒泡(向父组件传递时间)
</script>

3.按键修饰符

<body>
<div id="app">
    #1.只有按enter键才会触发他的执行
    <input type="text" @keyup.enter="handle" v-model="search">
    #2、任意键弹起都会触发他的执行
    <input type="text" @keyup="handle" v-model="search">
    #3、每按一个键都会触发他的执行
    <input type="text" @keydown="handle" v-model="search">
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            search:''
        methods: {
            handle(){
                console.log('enter建被放开了')
                location.href='https://www.baidu.com/s?wd='+this.search
</script>
</html>

八 数据的双向绑定(登录)

v-model的使用

<body>
<div id="app">
    请输入您的名字:<input type="text" v-model="name">
    请输入您的密码:<input type="password" v-model="password"> <span>{{error}}</span>
    您输入的名字是:{{name}}
    <button @click="submit_1">登录</button>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            name:'',
            password:'',
            error:''
        methods:{
            submit_1(){
                if(this.name=='longge' && this.password=='123'){
                    location.href='http://www.baidu.com'
                }else {
                    this.error='用户名或密码错误'
</script>

九 表单控制

1.checkbox选中

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>checkbox</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<div id="box">
    <input type="text" placeholder="请输入用户名:"><br>
    <input type="password" placeholder="请输入密码:"><br>
    <input type="checkbox" v-model="radio">记住用户名
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            myText: '',
            textBig: '',
            radio: false,
</script>
</html>

2.单选

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>单选</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<div id="box">
    <input type="radio" v-model="radio" value="男">
    <input type="radio" v-model="radio" value="女">
    <input type="radio" v-model="radio" value="保密">保密
    <br><br>您选择的性别:{{radio}}
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            radio: '',
</script>
</html>

3.多选

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>多选</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<div id="box">
    <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: '#box',
        data: {
            many: [],
</script>
</html>

4.购物车案例 - 结算

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>购物车结算</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    <style>
        table, td {
            border: 1px solid black;
            text-align: center;
    </style>
</head>
<div id="box">
    <table>
            <td>商品名称</td>
            <td>价格</td>
            <td>数量</td>
            <td>选择</td>
        <tr v-for="item in dataList">
            <td>{{item.name}}</td>
            <td>{{item.price}}</td>
            <td>{{item.number}}</td>
            <td><input type="checkbox" :value="item" v-model="checkGroup"></td>
    </table>
    <br>已选商品:{{checkGroup}}
    <br>总价:{{getPrice()}}
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            dataList: [
                {name: '今瓶没', price: 99, number: 2},
                {name: '西柚记', price: 59, number: 1},
                {name: '水壶转', price: 89, number: 5},
            checkGroup: [],
        methods: {
            getPrice() {
                let sum_price = 0
                for (i in this.checkGroup) {    // 这里的 i 是索引
                    sum_price += this.checkGroup[i]['number'] * this.checkGroup[i]['price']
                return sum_price
</script>
</html>

5.购物车案例 - 全选/全不选 -数量加减

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>控制加减</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<div class="row">
    <div id="box" class="col-md-4 offset-md-1 text-center mt-5 ">
        <table class="table table-bordered">
            <thead>
                <th scope="col">商品名称</th>
                <th scope="col">单价</th>
                <th scope="col">数量</th>
                <th scope="col">全选/全不选 <input type="checkbox" v-model="allChecked" @change="checkAll"></th>
            </thead>
            <tbody>
            <tr v-for="item in dataList">
                <td>{{item.name}}</td>
                <td>{{item.price}}</td>
                    <button class="btn link btn-sm" @click="reduceNum(item)">-</button>
                    {{item.number}}
                    <button class="btn link btn-sm" @click="item.number++">+</button>
                <td><input type="checkbox" :value="item" v-model="checkGroup" @change="checkOne"></td>
            <tr class="text-left">
                <td colspan="4">总价:{{getPrice()}}
            </tbody>
        </table>
    </div>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            dataList: [
                {name: '今瓶没', price: 99, number: 1},
                {name: '西柚记', price: 59, number: 1},
                {name: '水壶转', price: 89, number: 1},
            checkGroup: [],
            allChecked: false,
        methods: {
            getPrice() {
                let sum_price = 0
                for (i in this.checkGroup) {
                    sum_price += this.checkGroup[i]['number'] * this.checkGroup[i]['price']
                return sum_price
            checkAll() {
                if (this.checkGroup.length > 0) {
                    this.checkGroup = []
                } else {
                    this.checkGroup = this.dataList
            checkOne() {
                // if (this.checkGroup.length === this.dataList.length) {
                //     this.allChecked = true
                // } else {
                //     this.allChecked = false
                // }
                this.allChecked = this.checkGroup.length === this.dataList.length;
            reduceNum(item) {
                if (item.number === 1) {
                    item.number = 1
                } else {
                    item.number--