Vue基础篇-内置指令

Vue基础篇-内置指令

第五章

5.1基本指令

5.1.1 v-cloak

<style>
 [v-cloak]{
    display: none;
}
</style>

<body>
    <div id="app">
        <div v-cloak>
         {{message}}
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            // el: document.getElementById('app'),
            data() {
                return {
                    message:'解决屏幕闪动'
                }
            }
        })
    </script>
</body>
当网速较慢时,加载或者刷新页面的时候回出现{{message}}字样
使用v-cloak可以解决初始化慢导致页面闪动的最佳实践,对于简单的项目很实用。

但是在工程化文件中,项目的html结构只有一个空的div元素
剩下的内容都是由路由挂载不同的组件完成的,所以不再需要v-cloak。

5.1.2 v-once

<body>
    
<div id="app">
    <p v-once>{{msg}}</p>  //msg不会改变
    <p>{{msg}}</p>
    <p>
        <input type="text" v-model = "msg" name="">
    </p>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            // el: document.getElementById('app'),
            data() {
                return {
                    msg:'解决屏幕闪动'
                }
            }
        })
    </script>
</body>
当输入框值改变,即绑定的msg改变,使用了v-once的标签一直都是初始值
不会随着改变。

5.2 条件渲染指令

5.2.1 v-if、v-else-if、v-else

与js的条件渲染语句ifelse ifelse类似,条件指令决定节点是否渲染上页面。
<body>
    
<div id="app">
    <p v-if="status===1">status为1显示</p>
    <p v-else-if="status===2">status为2显示</p>
    <p v-else="status===3">status为3显示</p>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            // el: document.getElementById('app'),
            data() {
                return {
                    status:2
                }
            }
        })
    </script>
</body>
示例
<body>
    
<div id="app">
   <template v-if="type==='name'">
       <label for="">用户名:</label>
       <input type="text" placeholder="请输入用户名">
   </template>
   <template v-else>
    <label for="">邮箱:</label>
    <input type="text" placeholder="请输入邮箱">
</template>
<button @click="handler()">切换输入类型</button>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            // el: document.getElementById('app'),
            data() {
                return {
                    type:'name'
                }
            },
            methods:{
                handler(){
                    this.type=this.type==='name'?'mail':'name';
                }
            }
        })
    </script>
</body>
点击切换按钮来回切换姓名和邮箱之间的输入

5.2.2 v-show

v-show和v-if用法基本上一致,但是v-show是改变了css的样式
v-show='false'相当于display:none.
注意一点 v-show不能在template上使用。

两者之间的区别:
v-if是真正意义上的条件渲染,如果条件为假,则一开始就不会渲染节点,适用于不经常切换条件时。
v-show只是简单的css样式的改变,无论条件真假都会渲染。适用于频繁切换条件。

5.3 列表渲染指令v-for

5.3.1 遍历数组

当需要将一个数组遍历或者枚举一个对象循环显示时,就会用到v-for<style>
 [v-cloak]{
    display: none;
}
</style>

<body>
    
<div id="app">
  <ul>
      <li v-cloak v-for="(item,index) in items" :key="item.index">{{item.name}}</li>
  </ul>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            // el: document.getElementById('app'),
            data() {
                return {
                   items:[
                       {id:1,name:'vue基础'},
                       {id:2,name:'vue进阶'},
                       {id:3,name:'vue高阶'},
                       {id:4,name:'vue实战'},
                   ]
                }
            },
            methods:{
            }
        })
    </script>
</body>
此处也可以用of作为迭代器
<li v-cloak v-for="(item,index) of items" :key="item.index">{{item.name}}</li>
此外,也可以将v-for放在template上但是不能将:key放在template上
这样可以实现多个元素进行渲染。
<style>
 [v-cloak]{
    display: none;
}
</style>

<body>
    
<div id="app">
  <ul>
      <template v-cloak v-for="(item,index) of items">
        <li :key="item.index">书名:{{item.name}}</li>
        <li :key="item.index">作者:{{item.anthor}}</li>
      </template>
  </ul>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            // el: document.getElementById('app'),
            data() {
                return {
                   items:[
                       {id:1,name:'vue基础',anthor:'like'},
                       {id:2,name:'vue进阶',anthor:'lisi'},
                       {id:3,name:'vue高阶',anthor:'zhangsan'},
                       {id:4,name:'vue实战',anthor:'lingling'},
                   ]
                }
            },
            methods:{
            }
        })
    </script>
</body>

5.3.2 枚举对象

<style>
 [v-cloak]{
    display: none;
}
</style>

<body>
    
<div id="app">
  <ul>
 <li v-cloak v-for="(value,key,index) in items" :key="index">{{index}}-{{key}}:{{value}}</li>
  </ul>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            // el: document.getElementById('app'),
            data() {
                return {
                   items:{
                       name:'like',age:'24',gender:'male'
                   }
                }
            },
            methods:{
            }
        })
    </script>
</body>

5.3.3 迭代整数

<span v-cloak v-for="n in 10">{{n}}</span>

5.3.4 数组更新

vue的核心就是数据的双向绑定,当我们修改数组时,vue会监测到数据的变化
所以用v-for渲染的视图也会立即更新
vue包含了一些数组的变异方法,使用它们改变数组也会触发视图更新。
1.push()
2.pop()
3.unshift()
4.shiftf()
5.spice()
6.sort()
7.reverse()
不改变原数组的情况
filter()筛选
concat()组合
slice()
以下变动的数组中,vue是不能检测到的,也不会触发视图更新。
通过索引直接设置项,比如app.books[3]={name:'css探索',author:'lea Verou'}
修改数组的长度,比如app.books.length=1

解决第一个问题可以用两种方法实现
第一种是vue的内置set方法
Vue.set(app.books,3,{name:'css探索',author:'lea Verou'})
第二中方法是
app.books。splice(3,1,{name:'css探索',author:'lea Verou'})

5.3.5 过滤与排序

<style>
 [v-cloak]{
    display: none;
}
</style>

<body>
    
<div id="app">
     <ul>
 <li v-cloak v-for="(book,index) in filterbooks" :key="book.index">{{book.name}}</li>
     </ul>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            // el: document.getElementById('app'),
            data() {
                return {
                   books:[
                       {name:'html'},
                       {name:'java'},
                       {name:'js'},
                       {name:'vue'}
                   ]
                }
            },
            computed:{
                filterbooks(){
                    return this.books.filter(function(book){
                        return book.name.match(/js/)
                    })
                }
            }
        })
        
    </script>
</body>
通过调用filter的方法返回正则匹配后的进行渲染

5.4 修饰符

.stop  
.prevent
.capture
.self
.once

<span @click.stop="handler()"></span> //阻止单击事件冒泡
<form @submit.prevent='handle()'></form> //提交事件不再重载页面
<a @click.stop.prevent="handler()"></a>  //修饰符可以串联
<div @click.capture="handler()"></div>

键盘事件
<input @keyup.13='dosomething'>
按下回车触发事件

5.5 购物车开发

5.5.1 index.html

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>shopping car</title>
    <link rel="stylesheet" href="./index.css">
</head>

<body>
    <div id="app" v-cloak>
        <template v-cloak v-if="items.length">
            <table>
                <thead>
                    <tr>
                        <th>商品编号</th>
                        <th>商品名称</th>
                        <th>商品单价</th>
                        <th>购买数量</th>
                        <th>总价</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(item,index) in items" :key="item.index">
                        <td>{{index+1}}</td>
                        <td>{{item.name}}</td>
                        <td>{{item.price}}</td>
                        <td>
                            <button :disabled='item.count===1' @click="decrease(index)">-</button>
                            {{item.count}}
                            <button @click="increase(item)">+</button>
                        </td>
                        <td>{{item.count*item.price}}</td>
                        <td>
                            <button @click="remove(index)">移除</button>
                        </td>
                    </tr>
                </tbody>
            </table>
            <span>总价:{{totalprices}}</span>
        </template>
        <div v-else>购物车为空</div>
    </div>
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="./index.js"></script>
</body>

</html>

5.5.2 index.css

table {
    text-align: center;
    background-color: tomato;
    border: 1px solid #e9e9e9;
    border-collapse: collapse;
    border-spacing: 0;
    empty-cells: show;
}
th,td{
    padding:8px 16px;
    border: 1px solid #e9e9e9;
}
th{
    background: #f7f7f7;
    color: #5c6b77;
    font-weight: 600;
    white-space: nowrap;
}
button {
    border: none;
    outline: none;
    border-radius: 20px;
}

5.5.3 index.js

var app = new Vue({
  el: "#app",
  data() {
    return {
      items: [
        { id: 1, name: "apple", price: 5555, count: 2 },
        { id: 2, name: "pear", price: 5, count: 2 },
        { id: 3, name: "orange", price: 4, count: 2 },
        { id: 4, name: "apple", price: 5, count: 2 }
      ]
    };
  },
  methods: {
    decrease(index) {
        if(this.items[index].count===1) return;
         this.items[index].count--;
    },
    increase(item) {
      item.count++;
    },
    remove(index) {
      this.items.splice(index, 1);
    }
  },
  computed:{
      totalprices(){
          var total=0;
          for (let index = 0; index < this.items.length; index++) {
            total+=this.items[index].price*this.items[index].count;    
          }
          return total.toString().replace(/\B(?=(\d{3})+$)/g,',')
          //千分位分隔符的方法
      }
  }
});

发布了42 篇原创文章 · 获赞 29 · 访问量 3893

猜你喜欢

转载自blog.csdn.net/weixin_43279985/article/details/104235395
今日推荐