• Vue,品牌列表案例(仅添加,删除,搜索,全局过滤器,私有过滤器,日期填充,自定义按键修饰符,全局自定义指令文本框获取焦点,bind函数拿到传递的颜色值,自定义私有指令和指令函数的简写)


    Vue,品牌列表案例(仅添加,删除,搜索,全局过滤器,私有过滤器,日期填充,自定义按键修饰符,全局自定义指令文本框获取焦点,bind函数拿到传递的颜色值,自定义私有指令和指令函数的简写)  p34 p35

      1 <!DOCTYPE html>
      2 <html>
      3     <head>
      4         <meta charset="utf-8">
      5         <title></title>
      6         <script src="../js/vue.js"></script>
      7         <link rel="stylesheet" type="text/css" href="../css/bootstrap.css" />
      8     </head>
      9     <body>
     10         <div id="app">
     11             
     12             
     13             <div class="panel panel-primary">
     14                 <div class="panel-heading">
     15                     <h3 class="panel-title">添加品牌</h3>
     16                 </div>
     17                 <!-- form-inline 填在父元素里, 里面的子元素 占一行 -->
     18                 <div class="panel-body form-inline">
     19                     <label>
     20                         Id:
     21                         <input type="text" class="form-control" v-model="id">
     22                     </label>
     23                     
     24                     <label>
     25                         <!-- @keyup.enter 回车键抬起是触发add方法 keyup监听键盘抬起事件 .enter是确定了回车键而不是别的键 -->
     26                         Name:
     27                         <input type="text" class="form-control" v-model="name" @keyup.f2="add">
     28                     </label>
     29                 
     30                     <!-- 在Vue中,使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号,就可以给函数传参了
     31                       不加()也可以, 只不过不能传参-->
     32                     <input type="button" class="btn btn-primary" value="添加" @click="add()"/>
     33                     
     34                     
     35                     <label>
     36                         搜索名称关键字:
     37                         <!-- 注意: Vue中所有的指令, 在调用的时候 都以 v- 开头 -->
     38                         <input type="text" class="form-control" v-model="keywords" v-focus v-color="'blue'"/>
     39                     </label>
     40                 </div>
     41             </div>
     42             
     43             
     44             <table class="table table-bordered table-hover table-striped">
     45                 <thead>
     46                     <tr>
     47                         <th>Id</th>
     48                         <th>Name</th>
     49                         <th>Ctime</th>
     50                         <th>Operation</th>
     51                     </tr>
     52                 </thead>
     53                 <tbody>
     54                     <!-- 之前, v-for 中的数据, 都是直接从 data 上的list中直接渲染过来的 -->
     55                     <!-- 现在, 我们自定义了一个 search 方法,同时, 把 所有的关键字,通过传参的形式,传递给了
     56                      search 方法 -->
     57                     <!-- 在 search 方法内部,通过 执行 for 循环, 把所有符合 搜索关键字的数据,保存到 一个新数组
     58                      中, 返回-->
     59                     <tr v-for="item in search(keywords)" :key="item.id">
     60                         <td>{{ item.id }}</td>
     61                         <td>{{ item.name }}</td>
     62                         <td>{{ item.ctime | dateFormat() }}</td>
     63                         <td>
     64                             <!-- 使用 .prevent 阻止默认行为, 否则超链接跳转页面  -->
     65                             <a href="#" @click.prevent="del(item.id)">删除</a>
     66                         </td>
     67                     </tr>
     68                 </tbody>
     69             </table>
     70         </div>
     71     
     72         <div id="app1">
     73             <h3 v-color="'pink'" >{{ dt | dateFormat}} + 利用了全局过滤器</h3>
     74         </div>
     75             
     76         <div id="app2">
     77             <h3  v-fontweight="800" v-fontsize="'30px'">{{ dt | dateFormat}} + 利用了私有过滤器</h3>
     78         </div>
     79     </body>
     80 </html>
     81 <script>
     82         // 全局的过滤器,进行时间的格式化
     83         // 所谓的全局过滤器, 就是所有的VM实例都共享的
     84         // 注意 pattern ="" 这块是传值的部分,如果后台传值 传的是 "yyyy-mm-ss"格式就会显示 "yyyy-mm-ss"格式, 如果是 "yyyy-mm-ss hh:mm:ss" 
     85          // 则会显示 "yyyy-mm-ss hh:mm:ss" 下面有 if 判断
     86            Vue.filter('dateFormat', function (dateStr, pattern =""){
     87             // 根据给定的时间字符串, 得到特定的时间
     88             var dt = new Date(dateStr)
     89             
     90             // 日期格式 yyyy-mm-dd
     91             //得到一个四位的年份
     92             var y = dt.getFullYear()
     93             
     94             //
     95             var m = dt.getMonth() + 1
     96             
     97             // getDate得到的是日期, getDay得到的是星期
     98             var d = dt.getDate()
     99             
    100             // return y + '-' + m + '-' + d
    101             
    102             // .toLowerCase 统一转成小写
    103             //判断在这里 依照格式判断
    104             if(pattern.toLowerCase() === 'yyyy-mm-dd'){
    105                 return `${y}-${m}-${d}`
    106             }else{
    107                 var hh = dt.getHours()
    108                 var mm = dt.getMinutes()
    109                 var ss = dt.getSeconds()
    110                 
    111                 return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
    112             }
    113         })
    114         
    115     
    116          //自定义全局按键修饰符
    117         Vue.config.keyCodes.f2 = 113
    118         
    119         // 使用 Vue.directive() 定义全局的指令 v-focus
    120         // 其中: 参数1 :  指令的名称, 注意, 在定义的时候, 指令的名称前面, 不需要加 v- 前缀
    121         // 但是: 在调用的时候, 必须 在指令名称前 加上 v- 前缀来进行调用
    122         // 参数2: 是一个对象, 这个对象身上, 有一些指令相关的函数, 这些函数可以在特定的阶段, 执行相关的操作
    123         Vue.directive('focus', {
    124             // 注意: 在每个 函数中, 第一个参数, 永远是 el , 表示 被绑定了指令的那个元素, 这个 el 参数, 是一个原生的JS对象(一个DOM对象) 
    125             bind: function(){  //每当指令绑定到元素上的时候, 会立即执行这个 bind 函数, 只执行一次
    126                 // 在元素 刚绑定了指令的时候, 还没有 插入到 DOM中去(还在内存中), 这时候, 调用了 focus 方法没有作用
    127                 // 因为, 一个元素, 只有插入DOM之后, 才能获取焦点
    128                 // el.focus()
    129             },
    130             inserted: function(el){  //inserted 表示元素 插入到DOM中的时候, 会执行 inserted 函数 [触发1次]
    131                 el.focus()
    132                 // 和 JS行为有关的操作, 最好在 inserted 中去执行, 放止 JS行为不生效
    133             },
    134             updated: function(){  //当VNode更新的时候, 会执行 updated, 可能会触发多次 (与bind一样, 还没有插入到DOM 元素中)
    135                 
    136             }
    137         })
    138         
    139         // 设置字体颜色的指令
    140         Vue.directive('color',{
    141             // 样式, 只要通过指令绑定给了元素, 不管这个元素有没有被插入到页面中去, 这个元素肯定有了一个内联的样式
    142             // 将来元素肯定会显示到页面中, 这时候, 浏览器的渲染引擎必然会解析样式, 应用给这个元素 
    143             bind: function(el, binding){
    144                 // el.style.color = 'red'
    145                 //和样式相关的操作, 一般都可以在 bind 执行
    146                 // console.log("name=" + binding.name)    // 拿到color
    147                 // console.log("value=" + binding.value)  // 拿到 blue
    148                 // console.log("expression=" + binding.expression)  // 拿到'blue'
    149                 
    150                 // 自定义指令时如何拿到参数值
    151                 // 拿到 38行的 v-color 的颜色
    152                 el.style.color = binding.value
    153                 
    154             }
    155         })
    156          
    157         //创建 Vue 实例, 得到 ViewModel
    158          var vm = new Vue({
    159             el: '#app',
    160             data:{
    161                 id:'',
    162                 name:'',
    163                 keywords:'',
    164                 list:[
    165                     { id: 1, name: '奔驰', ctime: new Date() },
    166                     { id: 2, name: '宝马', ctime: new Date() },
    167                     { id: 3, name: '五菱宏光', ctime: new Date() }
    168                 ]
    169             },
    170             methods:{
    171                 add(){
    172                     // console.log("5555")
    173                     //分析:
    174                     //1. 获取到 id 和 name , 直接从data 上面获取
    175                     //2. 组织出一个对象
    176                     //3. 把这个对象, 调用 数组的 相关方法, 添加到data 的 list 中
    177                     //4. 注意: 在Vue中, 已经实现了数据的双向绑定, 每当我们修改了 data 中的数据, Vue
    178                     // 默认监听 数据的改动, 自动把最新的数据, 应用到页面上;
    179                     
    180                     // 5. 当我们意识到上面的第四步的时候,就证明大家已经入门Vue了, 我们更多的是在进行 VM中
    181                     // Model 数据的操作, 同时, 在操作 Model数据的时候, 指定的业务逻辑操作
    182                 
    183                     var car = { id: this.id, name: this.name, ctime: new Date() }
    184                     this.list.push(car)
    185                     
    186                     // 将输入框清空, 否则输入的内容还在
    187                     this.id = this.name = ''
    188                 },
    189                 del(id){
    190                     // 分析:
    191                     // 1. 如何根据Id, 找到要删除这一项的索引
    192                     // 2. 如果找到索引了, 直接调用 数组的 splice 方法
    193                     
    194                     // 方法一:
    195                     // some 根据指定的条件判断 (循环)
    196                     // this.list.some((item, i) => {
    197                     //     if(item.id == id) {
    198                     //         //从索引为 i的位置开始删, 删1个
    199                     //         this.list.splice(i, 1)
    200                     //         // 在 数组的 some 方法中,如果 return true,就会立即终止这个数组的后续循环
    201                     //         return  true;
    202                     //     }
    203                     // })
    204                     
    205                     // 方法二
    206                     //数组查找当前索引
    207                     var index = this.list.findIndex(item => {
    208                         if (item.id == id) {
    209                             return true;
    210                         }
    211                     })
    212                     console.log(index)
    213                     
    214                     this.list.splice(index, 1)
    215                 },
    216             search(keywords){  //搜索
    217                 
    218                 // 方法一
    219                 /* var newlist = []
    220                 this.list.forEach( item => {
    221                     if ( item.name.indexOf(keywords) != -1) {
    222                         newlist.push(item)
    223                     }
    224                 })
    225                 return newlist */
    226                 
    227                 //方法二
    228                 // 注意:  forEach   some   filter   findIndex   这些都属于数组的新方法
    229                 //  都会对数组中的每一项, 进行遍历, 执行相关操作 
    230                 
    231                 return this.list.filter( item => {
    232                 // var newlist = this.list.filter( item => {
    233                     // if(item.name.indexOf(keywords) != -1)
    234                     
    235                     // 注意 : ES6中, 为字符串提供了一个新方法, 叫做 String.prototype.includes('要包含的字符串')
    236                     //如果包含, 则返回 true , 否则返回 false
    237                     //jq 中有个类似的方法是 contain
    238                     if(item.name.includes(keywords)){
    239                         return item
    240                     }
    241                 })
    242                 
    243                 // return newlist
    244             },
    245         }
    246     });
    247 
    248         //利用了全局过滤器    
    249         var vm2 =new Vue({
    250             el: '#app1',
    251             data:{
    252                 dt: new Date()
    253             }
    254         })    
    255         
    256         //如何自定义一个私有的过滤器(局部)
    257         var vm3 = new Vue({
    258             el: '#app2',
    259             data:{
    260                 dt: new Date()
    261             },
    262             methods:{},
    263             filters:{
    264                    // 定义私有过滤器  过滤器有两个  条件   [过滤器名称 和 处理函数]
    265                 //过滤器调用的时候, 采用的是就近原则, 如果私有过滤器和全局过滤器名称一致了, 这时候 优先调用私有过滤器
    266                 dateFormat: function (dateStr, pattern = ''){
    267                     //根据给定的时间字符串,得到特定的时间
    268                     var dt = new Date(dateStr)
    269                     
    270                     //日期格式 yyyy-mm-dd
    271                     //得到一个四位的年份
    272                     var y = dt.getFullYear()
    273                     
    274                     //得到月份
    275                     // String.prototype.padStart(maxlength, fillString='')  填充字符串
    276                     //maxlength 是填充完总长度多少  fillString='' 表示用什么填充
    277                     var m = (dt.getMonth() + 1).toString().padStart(2, '0') 
    278                     
    279                     //getDate 得到的是日期 getDay得到的是星期
    280                     var d = dt.getDate().toString().padStart(2, '0') 
    281                     
    282                     // return y + '-' + m + '-' + d
    283                     
    284                     // .toLowerCase 统一转成小写
    285                     // 判断在这里 依照格式判断
    286                     if(pattern.toLowerCase() === 'yyyy-mm-dd'){
    287                         return `${y}-${m}-${d}`
    288                     }else{
    289                         var hh = dt.getHours().toString().padStart(2, '0') 
    290                         var mm = dt.getMinutes().toString().padStart(2, '0') 
    291                         var ss = dt.getSeconds().toString().padStart(2, '0') 
    292                         
    293                         return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
    294                     }
    295                 }
    296             },
    297             directives:{ // 自定义私有指令
    298               'fontweight': {  //设置字体粗细的
    299                   bind: function (el, binding){
    300                       el.style.fontWeight = binding.value
    301                   }
    302               },
    303               'fontsize': function(el, binding){  // 注意: 这个 function 等同于 把 代码写到了 bind 和 update 中去
    304                   // 如果后台传的是一个字符串, 如: 30px , 则无法接到值, 如果只是一个30 才能接到
    305                   // el.style.fontsize = binding.value
    306                   
    307                   // 这种写法无论传的是 30px 还是 30 都可以接到
    308                   el.style.fontSize = parseInt(binding.value) + 'px'    
    309               }
    310             },
    311         })
    312 
    313             // 过滤器的定义语法
    314             // Vue.filter('过滤器的名称', function(){})
    315             
    316             // 过滤器中的 function ,第一个参数, 已经被规定死了, 永远都是 过滤器 管道符前面 传递过来的数据
    317             // Vue.filter('过滤器的名称', function(data) {
    318             //     return data + '123'
    319             // })
    320             
    321         // 自动获取焦点, 但是Vue不推荐这么做    
    322         // document.getElementById('search').focus()    
    323             
    324 </script>
    325 
    326 
    327 <!-- 过滤器调用的格式   {{ name | nameope}}   再调用name 之前先调用nameope 进行处理 --> 
    'fontsize': function(el, binding){}     的写法等同于
    'fontsize':{
                       bind:function(el){ },
          updated: function(el){ }          
                    }

    主要新增代码

  • 相关阅读:
    jsonrpc
    第十章:多线程
    第九章:IO流
    第八章:集合
    第七章:常用类
    第六章:异常机制
    第四章:数组
    第三章:流程控制语句
    第二章:数据类型和运算符
    第五章:面向对象4
  • 原文地址:https://www.cnblogs.com/wo1ow1ow1/p/11056799.html
Copyright © 2020-2023  润新知