Vue 第三天

Vue 第三天

练习

第二天学了路由配置、编写按钮组件和按钮的点击事件。

先练习一遍~

按钮自定义点击事件

昨天写的按钮的点击事件中,将按钮事件写成了默认的 alert(this.msg) ,如果有些按钮想要异化,按钮的点击事件也是支持自定义的。

pageQuiButton.vue

//监听子组件的事件(子组件:quiButton.vue)
<qui-btn v-on:btnClickEvent="doSth" msg="我可以点击"></qui-btn>

上述代码在引用组件的时候,注册了一个事件,这个btnClickEvent是之前我们在 quiButton.vue 中绑定按钮的click事件,然后我们给这个事件一个自定义的方法doSth,同时在script标签中声明这个自定义方法:

//页面中引用子组件并监听子组件的事件
<script>
    import quiBtn from '../components/quiButton.vue'
    
	export default { 
        name: 'pageQuiButton',
        components: { 
            'qui-btn': quiBtn /* 注册自定义标签 */
        },
        methods: { 
            doSth:function (){ 
                alert('你点击了组件的click:btnClickEvent');
            }
        }
    }
</script>

这种做法专业来说叫做监听,由父组件(也就是引用方)监听子组件的内置方法,同时在子组件中,需要触发这个事件:

quiButton.vue

//子组件中代码
<script>
   export default{ 
		props:{ 
            msg:{ 
                default:'下载'
            }
        },
        methods:{    //绑定点击事件
            btnClickEvent: function(){ 
                alert('先弹出默认文案');
                this.$emit('btnClickEvent'); //此为关键代码,父组件触发自定义事件
            }
        }
	}
</script>

上述代码中 $emit 就是关键代码,也叫触发机制,父组件监听,子组件触发。

学会了这招后,引用方就可以给不同的子组件调用不同的事件处理了:

pageQuiButton.vue

<template>
  <div id="pageQuiButton">
    <qui-button v-on:btnClickEvent="doSth" msg="我可以点击" ></qui-button>
    <qui-button v-on:btnClickEvent="doSth1" msg="确定"></qui-button>
    <qui-button v-on:btnClickEvent="doSth2" msg="取消"></qui-button>
  </div>
</template>

<script>
    import quiBtn from '../components/quiButton.vue'

    export default { 
        name: 'pageQuiButton',
        components: { 
            'qui-button': quiBtn /* 注册自定义标签 */
        },
        methods:{ 
            doSth:function () { 
                alert('你点击了组件的click:btnClickEvent');
            },
            doSth1:function () { 
                alert("你点击了确定按钮");
            },
            doSth2:function () { 
                alert("你点击了取消按钮");
            }
        }
    }
</script>

给按钮加图标

一般特殊按钮,比如 收藏下载 按钮都是图标+文字类型的,而且图标还可能不一样,所以vue提供了 slot 标签:

quiButton.vue

<template>
    <button class="qui-btn" @click="btnClickEvent">
        <slot name="icon"></slot>  <!--加图标-->
		<span> { { msg}} </span>
    </button>
</template>

上述代码中,加入了关键字 solt 标签并赋予了一个name值,然后我们就可以在父组件中引用了:

pageQuiButton.vue

<qui-button v-on:btnClickEvent="doSth3" msg="下载" class="with-icon">
    <img slot="icon" class="ico" src="http://qzonestyle.gtimg.cn/aoi/sola/20170214175951_TA6qW1X7ob.png">
</qui-button>

上述代码中,img 标签中有个关键字 slot="icon",对应子组件中 slot 标签中 name="icon" ,会将img整个替换掉组件中的对应name的 slot 标签,slot翻译后的意思是 插槽,相当于把 img 这块的内容插到一个name为 icon 的插槽中去

script标签中:

<script>
  //....省略前面的代码
  doSth3:function(){ 
      alert("你点击了下载按钮,下载中....")
  }    
</script>

我们可以看到页面效果:
《Vue 第三天》

接下来学习一下Vue中对于for循环的巧妙使用:

导航组件quiNav.vue

在现实项目中,导航的tab个数是不定的,所以制作组件的时候,可以暴露一个属性来支持导航的tab个数,而tab的长相和应用其实是一样的,这时候可以用一个for循环来输出每一个tab。

<template>
  <div class="qui-nav nav-type-1">
    <a v-for="(item, index) in items">  <!--关键代码 v-for-->
      <span class="nav-txt"> { { item.text}} </span>
    </a>
  </div>
</template>

<script>
    export default { 
        data: function () { 
            return { 
                items: [
                    { 
                        text: '首页',
                        active: true
                    },
                    { 
                        text: '列表',
                        active: false
                    },
                    { 
                        text: '关于',
                        active: false
                    },
                    { 
                        text: '招聘',
                        active: false
                    }
                ]
            }
        }
    }
</script>
<style scoped>
  @import './css/reset.import.css';
  @import './css/qui-nav.import.css';
</style>

上述代码的关键地方在于a标签上 v-for 关键字,可以把它理解为js中的 for in 循环,items使我们在data里面定义的对象。v-for="(item,index) in items" 暴露了item 和 index两个接口,这是Vue提供的,代表items中的每一项以及该项对应的下标,然后我们就可以在标签中使用绑定 { {item.text}} 了。

再延伸一个动态添加class的概念,我们希望每个tab都有默认的class类名(比如 nav-item 类),在点击每个tab的时候,当前tab添加active类,其他的tab删除这个tab类。

动态类名

quiNav.vue

<template>
  <div class="qui-nav nav-type-1">
    <a v-for="(item, index) in items" :class="[commonClass,item.active ? activeClass : '']" >
      <span class="nav-txt">{ { item.text}}</span>
    </a>
  </div>
</template>

<script>
  export default { 
    data:function(){ 
      return { 
        commonClass:'nav-item',
        activeClass:'active',
        items:[
            ...//数据
        ]
      }
    }
  }
</script>

在template中添加了一句关键代码:

:class="[commonClass,item.active ? activeClass : '']"

:class 给组件绑定一个class属性,这里是缩写,它的全拼是v-bind: ,最前面有个冒号,**:class=XXXclass=XXX 的区别在于不带冒号的是静态的字符串绑定,带冒号的是动态的变量绑定 **。

我们给class绑定了一个数组,这个数组带有变量,先看commonClass,这个变量在data中定义了,然后数组的第二个元素是一个js的三元运算符: item.active ? activeClass : '' ,当每个item中的active值为true时,绑定activeClass变量对应的类,如果为false,则为空。

结果就是当item.active的值为true时,tab的class值为 nav-item active ,当为false,就只有 nav-item

我们切换tab的active类,就转换为修改每个item里面的active的值(数据驱动)。给每个tab绑定一个点击事件,当点击事件触发的时候,修改当前tab对应item的active值。

quiNav.vue

<template>
  <div class="qui-nav nav-type-1">
    <a v-for="(item, index) in items" :class="[commonClass,item.active ? activeClass : '']" v-on:click="navClickEvent(items,index)" >
      <span class="nav-txt">{ { item.text}}</span>
    </a>
  </div>
</template>

<script>
  export default { 
    data:function(){ 
      return { 
        commonClass:'nav-item',
        activeClass:'active',
        items:[
          { 
            text: '首页',
            active : true
          },
          ......
        ]
      }
    },
    methods:{ 
      navClickEvent:function(items,index){ 
        /*默认切换类的动作*/
        items.forEach(function(el){ 
          el.active = false;
        });
        items[index].active = true;
        /*开放用户自定义的接口*/
        this.$emit('navClickEvent',items,index);
      }
    }
  }
</script>

利用for循环给每个a标签绑定了一个click事件,对应methods中定义的navClickEvent,接收两个参数 items 和 index(也可以传入 item 和 index),然后当点击的时候,把items中的每个item.active置为false,把当前的tab的active值置为true,这样就可以动态切换active类了。最后再触发一次自定义事件(同按钮制作自定义事件)。

pageQuiNav.vue

//index.vue
<template>
  <div id="pageQuiNav">
    <qui-nav v-on:navClickEvent="dosth"></qui-nav>
  </div>
</template>

<script>
  import quiNav from '../components/quiNav.vue'
  export default { 
    name: 'pageQuiNav',
    components: { 
      'qui-nav': quiNav
    },
    methods:{ 
      dosth:function(items,index){ 
        console.log(items[index].text + index);
      }
    }
  }
</script>

<style scoped>

</style>

别忘了配置路由,否则看不到效果哦!

src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'

import index from '../pages/index'
import pageQuiButton from "../pages/pageQuiButton";
import pageQuiNav from "../pages/pageQuiNav"
import HelloWorld from '@/components/HelloWorld'

Vue.use(Router)

export default new Router({ 
  routes: [
    { 
      path: '/',
      name: 'index',
      component: index
    },
    { 
      path: '/btn',
      name: 'btn',
      component: pageQuiButton
    },
    { 
      path: '/nav',
      name: 'nav',
      component: pageQuiNav
    },
    { 
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    }
  ]
})

页面效果:
《Vue 第三天》

回顾

for循环输出每个tab,为每个tab绑定动态的class类名,同时在点击事件中动态切换类(底部的小黄条其实就是利用active类做的css)

总结

  1. 按钮组件自定义事件 $emit
  2. 按钮组件自定义子块slot
  3. for循环实现导航组件
  4. 动态类名
    原文作者:java最强的男人
    原文地址: https://blog.csdn.net/weixin_42719412/article/details/102500837
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞