前端VUE学习总结(一)

1.v-if和v-show的使用与区别

1.1  v-if

        v-if用来控制是否显示包含该元素的块是否显示。接收一个布尔类型的值,为true的时候则显示,为false的时候就不显示。通常与v-else或者v-elseif配合使用。类似于代码中的if-else判断和if-elseif-else判断的使用。

<div v-if="isshow">
    <p>这是if判断中的文本</p>
</div>
<div v-else>
    <p>这是else判断中的文本</p>
</div>

        如果不显示,在DOM结构中,vue会将该元素直接注释掉。在查看Elements结构的时候。将会看到有一行的内容为注释行“<!---->”

1.2  v-show

        与v-if相同,都是控制使用的元素是否显示。同样也是接收一个布尔类型的值。与v-if不同,当为false的时候,vue只是将其display设置为了none值。并没有完全将其从DOM中移除。

1.3  两者的使用地方

        v-if适合于那种决定性的显示。类似于某些权限下使用到某些功能模块,这个时候就适合使用v-if来控制是否显示。

        v-show适合控制那些需要来回显示的内容。

1.4  衍生出的知识点

        vue内部的虚拟DOM有一个复用。在切换显示内容的时候。如果两个的DOM结构一样,则vue的虚拟DOM则会优先复用。即替换其中某些值得参数,列如id、value等。这会导致,用户在界面A的input中输入的内容,在界面B输入的时候依然存在。如果希望vue的虚拟DOM不复用input,需要为两个界面的input添加一个key。使用不同的两个v-bind:key的值来标记,这样虚拟DOM就不会去复用有key标记过的元素。

2.v-for的循环遍历

2.1  v-for的基本使用

        v-for用于遍历数组,也适合与对象数组。可以适用于需要输出同样的元素结构,但内容不同的界面。例如table中的列,ul或者ol列表中的内容,甚至是个性化定制的div元素界面。

        假如我们有这样的一个数组,里面存储了一些水果的名字。那么,可以通过下面的方式使用ul来将其显示。因为我们需要显示多个li,所以我们需要在li元素中加入v-for。

<div id="shuiguo">
    <ul>
        <li v-for="item in fruits">{{item}}</li>
    </ul>
</div>
<script>
    const app = new Vue({
        el:'#shuiguo',
        data:{
            fruits:['苹果','香蕉','葡萄','芒果']
        }
    })
</script>

        当我们需要同时显示出,这个数组的下标时,我们就不能只使用item了,需要使用括号。第一个参数依然是我们遍历出来的对象或内容,第二个值为下标。

<div id="shuiguo">
    <ul>
        <li v-for="(item,index) in fruits">{{index}}--{{item}}</li>
    </ul>
</div>
<script>
    const app = new Vue({
        el:'#shuiguo',
        data:{
            fruits:['苹果','香蕉','葡萄','芒果']
        }
    })
</script>

2.2  v-for的遍历对象数组

        有时候数组可能是对象,此时代表的item就是对象,要像使用对象一样来使用item

<div id="man">
    <div v-for="people in body">
        <h2>这是名字:{{people.name}}</h2>
        <p>这是年龄:{{people.age}}</p>
    </div>
</div>
<script>
    const app = new Vue({
        el:'#man',
        data:{
            body:[
                {name:'张三',age:18},
                {name:'李四',age:20},
                {name:'王五',age:23}
            ]
        }
    })
</script>

2.3  为v-for遍历的内容增加key

        数组的内容可能会增加,如果没有为遍历的内容添加v-bind:key,虚拟DOM进行元素添加的时候会不太智能。此时衍生出了虚拟DOM的Diff算法。因此,可以为每一个遍历的内容添加一个不会重复的key。一般为遍历出来的item内容。

2.4  哪些操作数组的方法可以让vue刷新界面

        数组的内容除了添加还有删除以及修改。某些对数组的操作会让vue进行响应,因为vue是响应式的。

  • 数组的push方法,该方法向数组最后添加一个数组内容
  • 数组的pop方法,该方法将删除数组最后一个内容
  • 数组的shift方法,该方法将删除数组的第一个内容
  • 数组的unshift(item),该方法将item添加到数组的头部
  • 数组的sort方法,该方法可以将数组进行排序
  • 数组的reverse方法,该方法将数组内容进行翻转,从尾部排列到头部
  • 数组的splice方法,该方法可以插入、修改或者删除数组内容

        直接通过数组的下标来修改对应的内容,vue将不会刷新界面。可以使用splice来修改,或者使用vue自带的Vue.set(要修改的对象,索引值,替换的值)来修改。

 3.一个案例,结合之前学过的vue知识点

        书籍购物车,通过table表格来模拟一个购物车。统合了前期学习的vue知识点,模拟购物功能(增加数量/减少数量)/(按钮的点击功能),移除功能(数组的操作),当购物车为空时显示另外的界面(v-if、v-show的使用),以及统计总价格(computed知识点的使用)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="../js/vue.js"></script>
    <title>Document</title>
    <style>
        table {
            border: 1px solid #e9e9e9;
            border-collapse: collapse;
            border-spacing: 0;
        }
        
        th,
        td {
            padding: 9px 16px;
            border: 1px solid #e9e9e9;
            text-align: left;
        }
        
        th {
            background-color: #f7f7f7;
            color: #5c6b77;
            font-weight: 600;
        }
        
        table tr:nth-child(odd) {
            background-color: gray;
        }
        
        .app h2 {
            color: red;
        }
    </style>
</head>

<body>
    <div id="app">
        <div v-if="books.length">
            <table>
                <thead>
                    <th>索引</th>
                    <th>书籍名称</th>
                    <th>出版日期</th>
                    <th>价格</th>
                    <th>购买数量</th>
                    <th>操作</th>
                </thead>
                <tr v-for="(book,index) in books">
                    <td>{{index+1}}</td>
                    <td>{{book.name}}</td>
                    <td>{{book.date}}</td>
                    <td>{{book.price | showPrice}}元</td>
                    <td>
                        <button @click="itemLessNumber(index)" v-bind:disabled="book.number===1">-</button><span>{{book.number}}</span><button @click="itemAddNumber(index)">+</button>
                    </td>
                    <td>
                        <button @click="removeBook(index)">移除</button>
                    </td>
                </tr>
            </table>
            <span>总价格:{{Allprice | showPrice}} 元</span>
        </div>
        <h2 v-else>购物车为空</h2>
    </div>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                books: [{
                    name: '语文',
                    price: 25,
                    date: '1997-11-04',
                    number: 1
                }, {
                    name: '数学',
                    price: 24,
                    date: '1997-11-04',
                    number: 1
                }, {
                    name: '英语',
                    price: 22,
                    date: '1997-11-04',
                    number: 1
                }, {
                    name: '政治',
                    price: 30,
                    date: '1997-11-04',
                    number: 1
                }, {
                    name: '地理',
                    price: 21,
                    date: '1997-11-04',
                    number: 1
                }, {
                    name: '历史',
                    price: 20,
                    date: '1997-11-04',
                    number: 1
                }]
            },
            computed: {
                Allprice: {
                    get: function() {
                        var number = 0;
                        for (let index = 0; index < this.books.length; index++) {
                             const element = this.books[index];
                             number += (element.number * element.price);
                        }
                        return number;
                    }
                }
            },
            methods: {
                itemAddNumber(index) {
                    this.books[index].number++;
                },
                itemLessNumber(index) {
                    this.books[index].number--;
                    if (this.books[index].number < 1) {
                        this.books[index].number = 1;
                    }
                },
                removeBook(index) {
                    this.books.splice(index, 1)
                }
            },
            filters: {
                showPrice(price) {
                    return price.toFixed(2)
                }
            }
        })
    </script>
</body>

</html>

4.由一个案例所引出的知识点:函数式编程/链式编程

4.1  方法会改变调用对象的内容还是生成新的对象

        4.1.1  Object调用的方法会改变自身

                以数组为例子,一个数组调用了sort()方法进行了排序。此时不需要新建一个新的变量来接收返回值。sort()方法直接改变了数组的排序。

        4.1.2  Object调用的方法不会改变自身

                以字符串对象为例子,当使用substring()方法对字符串进行截取的时候,需要定义一个变量来接收新的字符串,此时原先的字符串不会有任何的改变。

4.2  链式编程,就是一连串的方法调用

         数组调用方法之后会返回数组,字符串调用方法之后会返回字符串,如果需要对一个变量进行多个方法的调用。比如将一串文字,进行内容翻转。我们需要使用到split()方法对字符串进行分割,再使用reverse()方法进行翻转,再使用join()将其拼接。

        我们不需要在每一步都定义一个新的变量来保存结果,我们可以直接使用一行代码。

var newString = "你好啊,陌生人".split('').reverse().join('')

        当我们使用log打印之后,就是显示这段文字翻转后的内容了。

4.2  高阶函数

        现在有一个场景,有一个数组,里面存储了一些数值,没有按大小顺序来排列。现在有一个需求,需要你筛选出其中大于50的值,将这些值乘以2,再求和。

        我们需要使用三个变量来存储,第一个变量A用来存储筛选大小后的数组,第二个变量B在变量A的基础上将值都乘以2,第三个变量C在变量B的基础将这些值相加求和。

        如果我们使用高阶函数,可以不用定义如此多的变量来完成这个需求。

        使用filter()高阶函数来进行特定的筛选,使用map函数来对数组的值进行操作,使用reduce()函数来进行求值。这时候,我们就可以有更容易阅读的方法来实现这个需求,当然,需要知道这三个函数的时候方法为前提。

// filter函数
const num = ['10', '20', '111', '222', '30', '40'];

const newnum1 = num.filter(function(n) {
    return n < 100;
})
console.log(newnum1);
// map函数
const newnum2 = newnum1.map(function(n) {
    return n * 2;
})
console.log(newnum2);

// reduce函数
const newnum3 = newnum2.reduce(function(previousValue, currentValue, currentIndex) {
    console.log('当前操作的下标' + currentIndex, '之前的previousValue的值为:' + previousValue);
    return previousValue + currentValue;
}, 0)

console.log(newnum3);

const result = num.filter(function(n) {
    return n < 100
}).map(function(n) {
    return n * 2
}).reduce(function(previousValue, currentValue) {
    return previousValue + currentValue;
}, 0);

console.log(result);

5.v-model的使用

5.1  v-model的基本使用和一些控件的交互

       在元素中使用v-model来定义数据的双向交互。定义的内容改变会体现在界面上,同时用户更改界面的时候也会改变其内容。

        例如使用v-model为一个input输入框对一个message变量进行双向绑定,用户输入的时候可以改变message的值。代码改变message的值时也会体现在输入框中。

5.2  v-model的原理

        可以使用v-bind:value对输入框的值进行绑定,这样message的内容也是可以显示在内容中。监听输入事件,当输入框中的内容改变时,更改message的值。这样也相当于实现了双向绑定。

5.3  v-model与其他控件的交互

        5.3.1与radio单项选择的交互

                 每当选中不同的单项内容时,对应绑定的sex都会改变。

    <div id="app">
        <label for="male">
            <input type="radio" id="male" v-model="sex" value="男">男
        </label>
        <label for="female">
            <input type="radio" id="female" v-model="sex" value="女">女
        </label>
        <h2>您选择的性别是:{{sex}}</h2>
        <h2>{{message}}</h2>
    </div>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊',
                sex: '男'
            }
        })
    </script>

        5.3.2与checkbox多选框的交互

                checkbox的勾选框需要考虑单个与多个的情况,两个情况都不同

    <div id="app">
        <!-- 单选框情况 -->
        <label for="agree">
            <input type="checkbox" id="agree" v-model="isAgree">同意协议
        </label>
        <br>
        <h2>是否勾选中:{{isAgree}}</h2>
        <button v-bind:disabled="!isAgree">下一步</button>
        <br>

        <!-- 多选框情况 -->
        <label for="baskteboll"><input type="checkbox" value="篮球" id="baskteboll" v-model="hobbies">篮球</label>
        <label for="vollyboll"><input type="checkbox" value="排球" id="vollyboll" v-model="hobbies">排球</label>
        <label for="pinpanboll"><input type="checkbox" value="乒乓球" id="pinpanboll" v-model="hobbies">乒乓球</label>
        <label for="brathboll"><input type="checkbox" value="羽毛球" id="brathboll" v-model="hobbies">羽毛球</label>
        <label for="tabelboll"><input type="checkbox" value="网球" id="tabelboll" v-model="hobbies">网球</label>
        <br>
        <h2>您选择的爱好是:{{hobbies}}</h2>

        <!-- 关于值绑定 -->
        <label v-for="item in originHobbies" v-bind:for="item">
            <input type="checkbox" v-bind:id="item" v-bind:value="item" v-model="newhobbies">{{item}}
        </label>
        <h2>您选择的爱好是:{{newhobbies}}</h2>
    </div>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊',
                isAgree: false,
                hobbies: [],
                originHobbies: ['篮球', '羽毛球', '排球', '乒乓球', '网球', '桌球'],
                newhobbies: []
            }
        })
    </script>

        5.3.3与select的交互

                同样也需要考虑单选与多选的情况

    <div id="app">
        <!-- 单选的情况 -->
        <select name="abc" v-model="fruit">
            <option value="苹果">苹果</option>
            <option value="芒果">芒果</option>
            <option value="香蕉">香蕉</option>
            <option value="葡萄">葡萄</option>
            <option value="榴莲">榴莲</option>
        </select>
        <h2>您选择的是:{{fruit}}</h2>
        <br>
        <select name="bcd" v-model="fruits" multiple>
            <option value="苹果">苹果</option>
            <option value="芒果">芒果</option>
            <option value="香蕉">香蕉</option>
            <option value="葡萄">葡萄</option>
            <option value="榴莲">榴莲</option>
        </select>
        <h2>您选择的是:{{fruits}}</h2>
    </div>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                fruit: '香蕉',
                fruits: []
            }
        })
    </script>

        5.3.4  v-model的修饰符的使用

                修饰符用来处理一些特殊的情况,例如v-model.lazy修饰符的作用是延时同步。在输入框失去焦点或者使用回车键时,才会同步去更新v-model绑定的内容。

                number修饰符可以确保用户输入的内容会被转为数值类型,可以很好的处理一些计算。如果没有使用该修饰符,则v-model绑定的内容会是string类型。

                trim修饰符就像字符串中的trim一样,可以去除输入框中开头和结尾输入的空格。

6.vue的组件化开发

        6.1vue的组件化思想和使用

                组件化的思想,可以让一些经常使用得到,或者多个页面有同样样式的内容可以进行复用。将每一块每一个控件都视作组件。可以自定义控件名称,在挂载了vue的控件上直接使用。

                vue自定义组件有三步,第一步:定义组件的构造,样式以及内容。第二步:声明控件的名称,以及所对应的组件构造器。第三步:在挂载了vue的控件中使用。

        6.2vue的全局组件以及局部组件

                没有在声明的vue中声明使用的组件为全局组件,类似于全局作用域和局部作用域。如果在一个挂载的vue中进行声明,那么该自定义控件只能在挂载了该vue的控件内使用。

        6.3父组件和子组件

                包含关系,在组件中可以包含组件。包含组件的叫父组件,被包含的叫子组件。

                6.3.1  父组件与子组件的数据通信

                        当在父组件中定义了一个数据message,此时需要将该数据传给子组件。在子组件中使用props声明自己使用的数据,在子组件的template的html模板中使用该数据。在父组件中,通过v-bind的方式绑定子组件声明的props属性。

    <div id="app">
        <cpn v-bind:cmovies="movies"></cpn>
    </div>

    <template id="cpn">
        <div>
            <p>这是数组movies:{{cmovies}}</p>
            <p>这是消息message:{{cmessage}}</p>
        </div>
    </template>
    <script>
        // 父传子
        const cpn = {
            template: '#cpn',
            // 数组方式
            // props: ['cmovies', 'cmessage'],
            // 对象形式
            props: {
                // 1.限制类型
                // cmovies: Array,
                // cmessage: String

                // 2.设置默认值
                // 当属性类型是对象或者数组时,默认值必须是函数的返回值
                cmovies: {
                    type: Array,
                    default () {
                        return []
                    }
                },
                cmessage: {
                    type: String,
                    default: '这是消息的默认值',
                    // required: true       控制该属性是否必须传递
                }
            },
            data() {
                return {

                }
            },
            methods: {

            }
        }


        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊',
                movies: ['海王', '海贼王', '海尔兄弟']
            },
            components: {
                cpn
            }
        })
    </script>

props的设置,可以限制传输的类型以及默认值。设置了默认值之后,如果没有赋值,那么它将使用默认值。

除了父组件可以传值给子组件,子组件也可以通过方法的方式,向父组件传递信息。

                6.3.2  子组件传给父组件

                        一个子组件中有一个按钮,点击该按钮后,向父组件传递一些信息。此时需要使用$emit来发送信息。$emit可以接受两个参数,至少要有一个参数。第一个参数为事件名称,第二个为参数。$emit第一个参数的事件名称,需要父组件在使用的时候去监听处理,类似于点击事件等。

    <div id="app">
        <cpn v-on:item-click="cpnClick"></cpn>
    </div>
    <template id="cpn">
        <div>
            <button v-for="item in categories" @click="btnclick(item)">{{item.name}}</button>
        </div>
    </template>
    <script>
        const cpn = {
            template: '#cpn',
            data() {
                return {
                    categories: [{
                        id: 'aaa',
                        name: '热门推荐'
                    }, {
                        id: 'bbb',
                        name: '手机数码'
                    }, {
                        id: 'ccc',
                        name: '家用家电'
                    }, {
                        id: 'ddd',
                        name: '电脑办公'
                    }]
                }
            },
            methods: {
                btnclick(item) {
                    // 子组件发射一个事件
                    this.$emit('item-click', item);
                }
            }
        }

        const app = new Vue({
            el: '#app',
            data: {
                message: '你好啊'
            },
            components: {
                cpn
            },
            methods: {
                cpnClick(item) {
                    console.log('这里是vue对象的log', item);
                }
            }
        })

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值