zoukankan      html  css  js  c++  java
  • 《Vue.j实战》一书 p117 页练习 1 & 2 试做源代码

    Demo 在线效果浏览

    练习1 : 给pane 组件新增一个prop: closable 的布尔值, 来支持是否可以关闭这个pane , 如
    果开启, 在tabs 的标签标题上会有一个关闭的按钮。

    提示:初始化pane 时我们是在 mounted里通知的,关闭时,你会用到 beforedestroy

    练习2 : 尝试在切换pane 的显示与隐藏时,使用滑动的动画。提示: 可以使用css 3 的transform:
    translateX 。

    IDE:VScode

    项目由 main.js, app.vue, tabs.vue, pane.vue 4个文件构成。

    main.js(略)

    app.vue:

    <template>
      <div id="app">
        <tabs v-model="activeKey" @on-click="handleOnclick" @on-close="handleOnclose">
          
          <pane v-for="item in pans" 
          :key="item.mes"
          :label="item.label"
          :name="item.name"
          :closable="item.closable"
          >
            {{item.mes}}
          </pane>
        </tabs>
      </div>
    </template>
    <script>
    import tabs from './components/tabs';
    import pane from './components/pane';
    export default {
      components:{
        tabs,
        pane
      },
      data(){
        return{
          activeKey:'1',
          pans:[
            {
              label:'标签一',
              name:'1',
              closable:true,
              mes:'标签一的内容'
            },
            {
              label:'标签二',
              name:'2',
              closable:true,
              mes:'标签二的内容'
            },
            {
              label:'标签三',
              name:'3',
              closable:true,
              mes:'标签三的内容'
            },
          ]
        }
      },
    
      methods:{
        handleOnclick(name){
    
        },
        handleOnclose(name){
            var index=0;
            for(var i=0;i<this.pans.length;i++)    {
              if(this.pans[i].name===name){
                index=i;
                break;
              }
            }
            this.pans.splice(index,1);
        }
      },
      beforeDestroy(){
        this.$off('on-click',this.handleOnclick);
        this.$off('on-close',this.handleOnclose);
      }
    }
    </script>

    tabs.vue(不含style)

    <template>
        <div class="tabs">
            <div class="tabs-bar">
    
                <div
                :class="tabCls(item)"
                v-for="(item, index) in navList"
                :key="item.name"
                @click.self="handleChange(index)">
                {{ item.label }}
                <template v-if="item.closable">
                <a href="#" class="del" v-show="item.name===currentValue"
                @click="handleClose(item,index)"
                >x</a>
                </template>
                </div>
    
             </div>
                <div class="tabs-content">
                    <slot></slot>
                </div>
        </div>
    </template>
    <script>
    export default {
        props:{
            value:{
                type:[String, Number]
            },
        },
        data(){
            return{
                currentValue:this.value,
                navList:[]
            }
        },
        methods:{
            handleClose(item,index){
                this.navList.splice(index,1);
                //console.log(this.navList.length);
                var name = item.name;
                //console.log(name)
                this.handleChange(0)
                this.$emit('on-close',name);            
            },
            tabCls(item){
                return[
                    'tabs-tab',
                    {
                        'tabs-tab-active':item.name === this.currentValue
                    }
                ]
            },
            getTabs(){
                return this.$children.filter(function(item){
                    return item.$options.name === 'pane';
                });
            },
            updateNav(){
                this.navList=[];
                var _this = this;
    
                this.getTabs().forEach(function(pane, index){
                    _this.navList.push({
                        label:pane.label,
                        name: pane.name || index,
                        closable:pane.closable
                    });
                    if(!pane.name) pane.name = index;
                    if(index === 0){
                        if(!_this.currentValue){
                            _this.currentValue = pane.name || index;
                        }
                    }
                });
                this.updateStatus();
            },
            updateStatus(){
                var tabs = this.getTabs();
                var _this = this;
    
                tabs.forEach(function(tab){
                    return tab.show = tab.name === _this.currentValue;
                })
            },
            handleChange(index){
                if(this.navList.length){
                var nav = this.navList[index];            
                var name = nav.name;
                //console.log(name)
                this.currentValue = name;
                this.$emit('input',name);
                this.$emit('on-click',name);
                }
            }
        },
        watch:{
            value(val){
                this.currentValue = val;
            },
            currentValue(){
                this.updateStatus();
            }
        },
    
    }
    </script>

    pane.vue

    <template>
    <transition name="fade" mode="out-in">
    
        <div class="pane" v-show="show">
            <slot></slot>
        </div>
    
    </transition>
    </template>
    <script>
    export default {
        name:'pane',
        data(){
            return{
                show:true
            }
        },
        props:{
            name:{
                type:String
            },
            label:{
                type:String,
                default:''
            },
            closable:{
                type:Boolean,
                default:true
            }
        },
        methods:{
            updateNav(){
                this.$parent.updateNav();
            }
        },
        watch:{
            label(){
                this.updateNav();
            },
    
        },
        mounted(){
            this.updateNav();
        },
        beforeDestroy(){
            
        }
    }
    </script>
    <style>
    .pane{
        display: inline-block;
    }
     .fade-enter-active,.fade-leave-active{
         position: absolute;
         transition: all .8s ease;
    }
    .fade-enter, .fade-leave-to{
        transform: translateX(100px);
        opacity: 0;
    }
    </style>
  • 相关阅读:
    timescaledb 几个方便的api
    k8s PersistentVolume hostpath 简单使用
    timescaledb replication 使用
    timesacledb 测试demo数据运行
    conan c&&c++ 包管理工具使用
    graphql-yoga interface && union 使用
    JFrog Artifactory CE c&&c++ 包管理工具
    graphcool-framework 一个基于graphql的后端开发框架
    graphql-yoga 项目简单使用&&集成docker
    nsq 安装试用
  • 原文地址:https://www.cnblogs.com/sx00xs/p/11322346.html
Copyright © 2011-2022 走看看