vue基础案例


题目列表

一、电影分类

需求:(全部 动作 喜剧 谍战 历史)点击谁谁加粗。

<body>
    <div id="app">
    //注意:template上面不能写 :key
        <template v-for="(item,index) in movies"> //遍历数组
            <strong :key="index" v-if="item == current">{{item}}</strong>
            <span :key="index" v-else @click="current=item">{{item}}</span>
        </template>
    </div>

    <script src="/lib/vue.js"></script>

    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    movies: ['全部', '动作', '喜剧', '谍战', '历史'],
                    current:'全部'
                }
            }
        })
    </script>
</body>

1.1 电影分类class版。

<style>
        //加边距 
        #app>* {
            margin-left: 20px;
        }
        //设置样式
        .active{
            color:#ffffff;
            background-color: tomato;
        }
    </style>
</head>
<body>
    <div id="app">
       <span v-for="item in movies" :key="item" :class="{active:item==current}" 
       @click="current=item"> {{item}} </span>
       //赋值运算符,将右边的值赋值给左边的变量。
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    movies: ['全部', '动作', '喜剧', '谍战', '历史'],
                    current: '全部'
                }
            }
        })
    </script>
</body>

二、购物车

需求:点击增加或减少,删除完显示购物车为空。在这里插入图片描述

<body>
    <div id="app">
        <thead>
            <table>
                <tr>
                    <td>商品编号</td>
                    <td>商品名称</td>
                    <td>商品单价</td>
                    <td>商品数量</td>
                    <td>商品总价</td>
                    <td>商品操作</td>
                </tr>
        </thead>
        <tbody>
            <tr>
                //1.数组every方法
                <td v-if="goodsData.every(item=>item.count==0)">购物车为空</td>
            </tr>

            <template v-for="(item,index) in goodsData">
                <!-- 设立判断条件:数量大于0为真就显示 -->
                <tr v-if="item.count >=0" :key="item._id">
                    <td>{{item._id}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.price}}</td>
                    <td>
                        <button @click="item.count--">-</button>
                        <span>{{item.count}}</span>
                        <button @click="item.count++">+</button>
                    </td>
                    <td>{{item.price*item.count}}</td>
                    //2.数组splice方法
                    <td><button @click="goodsData.splice(index,1)">删除</button></td>
                </tr>
            </template>
        </tbody>
        </table>
       //思考:为什么渲染totalPrice要加()
        <p>合计:{{totalPrice()}}</p>

    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                    goodsData: [
                        { _id: 1, name: '苹果', price: '20', count: 10 },
                        { _id: 2, name: '芒果', price: '10', count: 20 },
                        { _id: 3, name: '香蕉', price: '30', count: 30 },
                        { _id: 4, name: '梨子', price: '15', count: 40 }
                    ]
                }
            },
            //计算总价
            methods: {
                totalPrice() {
                    // 3.数组reduce累加方法
                    return this.goodsData.reduce((sum, item) => {
                        return sum + item.price * item.count;
                    }, 0)
                }
            },
        })
    </script>
</body>

2.1 数组every()方法

every()方法:对数组中的每一个元素进行比对,全为true结果返回true。some()方法则是只要有一个结果为true结果就返回true。

语法:array.every(function(currentValue,index,arr), thisValue)

  • value :必须,当前元素的值。

  • index:可选,当前元素的索引值。

  • arr:可选,当前元素属于的数组对象。

var arr=[10,30,40];
var flag = arr.every(function(value){
    return value > 9;
    //箭头函数写法:var flag = arr.every(value=> value > 9)
})
console.log(flag); //输出ture

2.2 数组splice()方法

splice()方法:用于添加或删除数组中的元素。
语法:array.splice(index,howmany,item1,.....,itemX)

index:起始下标位置(必选)。
例:
goodsData.splice(2,2)//从第三个位置删除后两个元素
goodsData.splice(2,1,"apple")//从第三个位置删除一个元素并添加apple

2.3 数组reduce()方法

reduce()方法:接收一个函数作为累加器。
语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
参数:

  • total:必需。初始值, 或者计算结束后的返回值。
  • currentValue :必需。当前元素
  • currentIndex :可选。当前元素的索引
  • arr:可选。当前元素所属的数组对象。
  • initialValue:可选。传递给函数的初始值

例:

var arr = [3,9,4,3,6,0,9];
var sum = arr.reduce((total,currentValue)=>{
    return total+currentValue
},0)
console.log(sum); //输出34

三、todolist

需求:点击切换。在这里插入图片描述

<style>
        .done {
            color: red;
            text-decoration: line-through;
        }
        .btns>*{
            margin-right: 10px;
        }
    </style>
</head>
<body>
    <div id="app">
        <ul>
           //遍历筛选后的数组
            <template v-for="item in filterLists">
                <li class="done" v-if="item.done" @click="item.done = !item.done">{{item.text}}</li>
                <li v-else @click="item.done = !item.done">{{item.text}}</li>
            </template>
//用v-bind:class绑定style样式改写:
//<li v-for="item in filterLists" :class="{done:item.done}"
//@click="item.done = !item.done"> {{item.text}} </li>
        </ul>

        <div class="btns">
            <template v-for="item in btns">
                <span v-if="item==current">{{item}}</span>
                <a href="#" v-else @click="current=item">{{item}}</a>
            </template>
            <br>
            <br>
            <span>已完成:{{doneTotal}}/{{lists.length}}</span>
        </div>
        
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                    //需要记录数据和其状态(完成或者未完成)因此用数组包对象
                    lists: [
                        { text: 'HTML', done: false },
                        { text: 'CSS', done: true },
                        { text: 'JS', done: false },
                    ],
                    btns: ['全部', '已完成', '未完成'],
                    current: '全部'
                }
            },
            //1.数组filter()方法
            //2.switch语句
            computed:{
                filterLists(){
                    switch (this.current){
                        case '已完成' : return this.lists.filter(item=>item.done);
                        //由于这里已经return了,因此不写break也可
                        break;
                        case '未完成' : return this.lists.filter(item=>!item.done);
                        break;
                        default:return this.lists;
                    }
                },
                //已完成的长度
                doneTotal(){
                    return this.lists.filter(item => item.done).length;
                }
            }
        })
    </script>
</body>
</html>

3.1 用v-model添加待办事项。

需求:在这里插入图片描述

<input type="text"  v-model="addText">
<button @click="addTodo">addTo</button>

data() {
     return {
       lists: [
            { text: 'HTML', done: false },
            { text: 'CSS', done: true },
            { text: 'JS', done: false },
         ],
          btns: ['全部', '已完成', '未完成'],
          current: '全部',
          addText:''     //设置输入框默认为空
      }
   },
   //省略大部分代码。。。
   methods: {
                addTodo(){
                    this.lists.push({
                        text:this.addText,
                        done:false
                    });
                    //输入后清空输入框
                    this.addText='';
                }
            },

push()方法:向数组末尾(添加到开头则用unshift)添加一个或多个元素,并返回新的长度。

语法:array.push(item1, item2, ... itemX)

3.2 数组filter()方法

filter()方法 :用于对数组进行过滤(创建一个新数组,不改变原数组;return后面的判断结果,取布尔值,true就添入新的filter数组中,false则不加)。

语法:array.filter(function(currentValue,index,arr), thisValue)

例:

//筛选数组中大于5的数
let arr = [1,2,3,4,5,6,7,8];
let newArr = arr.filter(arr=>{
    return arr > 5;
 //箭头函数省略return写法:
 //let newArr = arr.filter(arr => arr>5);
});
console.log(newArr);

3.3 filter()和map()的区别

  • map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。map() 方法按照原始数组元素顺序依次处理元素。
  • filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
  <script>
        const array = [1, 4, 9, 16];
        const m = array.map(x => x + 2);
        const f = array.filter(x => x + 2)
        
        console.log(m);   //[3,6,11,18]
        console.log(f);   //[1,4,9,16]  (全为true)
    </script>
<script>
        const array = [1, 4, 9, 16];
        const m = array.map(x => x > 2);
        const f = array.filter(x => x > 2)
        
        console.log(m); //[false, true, true, true]
        console.log(f); //[4,9,16]
    </script>

3.4 switch语句

语法:

switch(expression) {
    case n:
        代码块
        break;
    case n:
        代码块
        break;
    default:
        默认代码块
}

expression:必须。指定计算的表达式。表达式只计算一次。表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行。

//num=1时,打印出:正确
//num=3时,打印出:我不知道
  var num = 3;
    switch (num) {
        case 0:
            console.log('错误');
            break;
        case 1:
            console.log('正确');
            break;
        case 2:
            console.log('错误');
            break;
        default:
            console.log('我不知道');
    }
//若没有break,则从正确匹配的位置开始,依次向下执行。
//例如:num=1时,控制台打印出:正确 错误 我不知道
//num=0时,控制台打印出:错误 正确 错误 我不知道                
   var num = 1;
    switch (num) {
        case 0:
            console.log('错误');
        case 1:
            console.log('正确');
        case 2:
            console.log('错误');
        default:
            console.log('我不知道');
    }

四、图书管理

需求:
在这里插入图片描述

<body>
    <div id="app">
        <button  @click="booksTpye='全部'">全部</button>
        <button  @click="booksTpye='已借阅'">已借阅</button>
        <button  @click="booksTpye='未借阅'">未借阅</button>
        <table>
            <thead>
                <tr>
                    <th>图书名称</th>
                    <th>图书作者</th>
                    <th>图书价格</th>
                    <th>图书出版社</th>
                    <th>图书状态</th>
                    <th>图书操作</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(item, index) in  fliterBooks" :key="index">
                    <td>{{item.name}}</td>
                    <td>{{item.auther}}</td>
                    <td>{{item.price}}</td>
                    <td>{{item.press}}</td>
                    <td>
                        <span v-if="item.borrow == true" style="color: red;" >已借阅</span>
                        <span v-else >未借阅</span>
                    </td>
                    <td>
                        <button v-if="item.borrow == true" @click="item.borrow=!item.borrow">归还</button>
                        <button v-else @click="item.borrow=!item.borrow">借阅</button>
                    </td>
                </tr>
            </tbody>
            <p>总计{{booksData.length}}本书,当前可借阅{{canBorrow}}本书。</p>
        </table>
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data(){
                return{
                    booksData:[
                        {name:'JS程序设计',auther:'小明',price:'99',press:'机械工业出版社',borrow:false},
                        {name:'JS权威指南',auther:'小红',price:'78',press:'人民邮电出版社',borrow:false},
                        {name:'ES6入门',auther:'小黄',price:'67',press:'电子工业出版社',borrow:true},
                        {name:'JS设计模式',auther:'小刚',price:'49  ',press:'机械工业出版社',borrow:false},
                    ],
                    booksTpye:'全部'
                }
            },
            computed:{
                canBorrow(){
                    return this.booksData.filter(item => !item.borrow).length
                },
                fliterBooks(){
                    switch(this.booksTpye){
                        case '已借阅' : return this.booksData.filter(item => item.borrow);
                        case '未借阅' : return this.booksData.filter(item => !item.borrow);
                        default:return this.booksData
                    }
                }
            }
        })
    </script>
</body>

五,成绩查询

需求:分数范围筛选和各学科名次排序。在这里插入图片描述

//css样式:竖条分数变黄
    <style>
        .active {
            color: orange;
        }
    </style>
    
<body>
    <div id="app">
        <div>
            <span>搜索:</span>
            <input type="text" v-model="min">
            <span>~</span>
            <input type="text" v-model="max">
        </div>
        <div>
           //知识点1:单选按钮radio,怎么设置默认值,怎么实现只能选择一项。
            <span>排名方式:</span>
            //name的作用是只能选一个选框,v-model绑定同一个变量也可以只选一个选,就可以不用name了.
            <input type="radio" v-model="rank" value="total">
            <laber>总分</laber>
            <input type="radio" v-model="rank" value="math">
            <laber>数学</laber>
            <input type="radio" v-model="rank" value="chinese">
            <laber>语文</laber>
            <input type="radio" v-model="rank" value="english">
            <laber>英语</laber>
        </div>
        <table>
            <thead>
                <tr>
                    <th>排名</th>
                    <th>姓名</th>
                    <th>数学</th>
                    <th>语文</th>
                    <th>英语</th>
                    <th>总分</th>
                </tr>
            </thead>
            <tbody>
            //这后面是先筛选再排序,遍历排序后的数组,这样筛选和排序都有了
                <tr v-for="(item,index) in sortScoresData" :key="index">
                    <td>{{index+1}}</td>
                    <td>{{item.name}}</td>
                    <td :class="{active:rank=='math'}">{{item.math}}</td>
                    <td :class="{active:rank=='chinese'}">{{item.chinese}}</td>
                    <td :class="{active:rank=='english'}">{{item.english}}</td>
                    <td :class="{active:rank=='total'}">{{oneTotal(item)}}</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    scoresData: [
                        { name: '张三', math: 97, chinese: 89, english: 67 },
                        { name: '李四', math: 67, chinese: 52, english: 98 },
                        { name: '王五', math: 72, chinese: 87, english: 89 },
                        { name: '赵钱', math: 92, chinese: 87, english: 59 },
                        { name: '孙李', math: 47, chinese: 85, english: 92 },
                    ],
                    rank: 'total',//纪录当前用户选择排名的方式
                    min: '0',
                    max: '300'
                }
            },
            
            computed: {
             //计算属性的传参使用:oneTotal上不能传,但是下面的函数可以。
                oneTotal(){
                    return function(item){
                        return item.math+item.chinese+item.english
                    }
                },
                //计算属性得到筛选后的数组
                //由于math在scoresData中实际上是字符串,因此能用item.math,而rank为变量,则不能用item.rank,访问变量要加中括号item[rank]
                //由于,scoresData中无total数据,所以item中没有total属性,则不能使用item[this.rank]访问到,需要用if做判断。
                filterScoresData(){
                    return this.scoresData.filter(item=>{
                        if(this.rank=='total'){
                            return (this.oneTotal(item))>=this.min&&(this.oneTotal(item))<=this.max;
                        }
                            return item[this.rank]>=this.min&&item[this.rank]<=this.max;
                    });
                },
                //计算属性得到排序后的数组
                //知识点2:数组sort()方法
                sortScoresData() {
                    switch (this.rank) {
                        case 'total': return this.filterScoresData.sort((a, b) => (this.oneTotal(b)) - (this.oneTotal(a)))
                            break;
                        case 'math': return this.filterScoresData.sort((a, b) => b.math - a.math)
                            break;
                        case 'chinese': return this.filterScoresData.sort((a, b) => b.chinese - a.chinese)
                            break;
                        case 'english': return this.filterScoresData.sort((a, b) => b.english - a.english)
                            break;
                    }
                },                
            }
        })
    </script>
</body>

5.1 input输入框

单选框:<input type="radio">出现在多选一的页面设定中,提交到处理页的是value值。
注意:name值一定要相同,否则就不能多选一。当然提交到处理页的也还是value值。

//name相同才能实现单选按钮。
 <input type="radio" name="question1" value="boy"><input type="radio" name="question1" value="girl">//如果用v-model绑定,则无需name参数。
 <input type="radio" v-model="rank" value="total">
 <input type="radio" v-model="rank" value="math">

5.2 v-model的使用

1.复选框
  • 单个复选框

在单个复选框上绑定 v-model 属性,可以通过 v-model 属性值的 true 或 false,来控制复选框的选中或未选中,同时,操作复选框的选中或未选中,也会同步更新 v-model 属性值的 true 或 false。

<body>
    <div id="app">
        <input type="checkbox" v-model="isChecked">
    </div>
    
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data() {
                return {
                   isChecked:true
                }
            },
        })
    </script>
</body>
  • 多个复选框

在多个复选框上绑定同一个 v-model 属性,通过判断复选框自己的 value 值是否在 v-model 的数组里面,来控制复选框的选中或未选中。同时,操作复选框的选中或未选中,也会同步更新复选框的 value 值在数组中添加或删除。

<body>
    <div id="app">
        <input type="checkbox" value="eat" v-model="checkeds">吃饭
        <input type="checkbox" value="sleep" v-model="checkeds">睡觉
        <input type="checkbox" value="hit" v-model="checkeds">打豆豆
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    checkeds: ['sleep'],
                }
            },
        })
    </script>
</body>

显示:在这里插入图片描述

2.单选框

在单选框上绑定 v-model 属性,通过判断单选框自己的 value 值是否和 v-model 的值相等,来控制单选框的选中或未选中。

<body>
    <div id="app">
        <input type="radio" value="男" v-model="gender"><input type="radio" value="女" v-model="gender"></div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    gender: '男',
                }
            },
        })
    </script>
</body>
3.下拉列表

在 select 身上绑定 v-model 属性,通过判断 option 的 value 值和 v-model 的值是否相等,来决定被选中的 option。

<body>
    <div id="app">
        <select v-model="city">
            <option value="四川">四川</option>
            <option value="上海">上海</option>
            <option value="北京">北京</option>
            <option value="云南">云南</option>
       </select>
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    city: '北京'
                }
            },
        })
    </script>
</body>

5.3 sort()方法

sort()方法会改变原数组。语法:array.sort(sortfunction),若无参数sortfunction则按字母升序排列。字母倒序排列则用reserve()。

//例:a-b是从小到大排列,b-a是从大到小。
 var num = [74, 35, 74, 95, 33, 56, 84, 32, 21, 34];
 num.sort((a, b) => b - a);
    console.log(num);

5.4 获取对象属性点方法和中括号法的区别

  1. 中括号法可以用变量作为属性名,而点方法不可以
 var obj = {};
 obj.name = '张三';
 var myName = 'name';
 console.log(obj.myName); //undefined,访问不到对应的属性
 console.log(obj[myName]); //张三
  1. 中括号法可以用数字作为属性名,而点语法不可以
  2. 中括号法可以使用js的关键字和保留字作为属性名,而点语法不可以

六,this总结

首先,this只有在函数function中才需要去判断它的指向。如果是在全局环境中,this永远指向全局对象。浏览器环境中,全局对象为“window对象”,Nodejs环境中,全局对象为“Global对象”。

6.1 普通函数中的this

//普通函数中的this,永远指向window对象。
function foo(){
   console.log(this);
}
foo();

6.2 对象方法中的this

//对象方法中的this,指向调用该方法的对象
 const student = {
            name: 'zhangsan',
            sayName: function () {
                console.log(this);
            }
        };
        const person = { name: 'lisi' };
        person.sayName = student.sayName
        person.sayName();
        
 //这里的this指向调用调用sayName方法的对象person

6.3 事件中的this

//事件中的this,指向绑定该事件的元素
const father = document.getElementById('father');
        father.onclick = function (event){
            console.log(this);
        }
        
//这里指向绑定onclick事件的元素father

6.4 构造函数中的this

//构造函数中的this,指向new调用时得到的函数对象
 function Person() {
     console.log(this);
  }
     const p = new Person(); //这里this指向p
     const b = new Person(); //这里this指向b

6.5 箭头函数中的this

箭头函数没有自己的this,因此在箭头函数中范围this时,实际访问的是父级(箭头函数创建时所在范围)的this。

const student = {
 foo: function(){
         return()=>{      //箭头函数的父极是foo
              console.log(this);
       }
  }
}
const bar = student.foo();//调用,将函数foo的返回值赋值给bar
bar();//这里调用的是函数的返回值,也就是箭头函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值