vue之组件封装(2)

跑马灯组件

<template>
    <div>
        <div class="demo" :style="{background:c}" v-for="(c,idx) in colors" :key=idx></div>
        <!-- 等同于如下写法 -->
        <!-- <div class="demo" style="background:black"></div>
        <div class="demo" style="background:red"></div>
        <div class="demo" style="background:green"></div> -->
    </div>
</template>
<script>
export default {
    name: 'HorseRaceLamp',
    data() {
        return {
            colors:['black','red','green'],
            timer:null
        }
    },
    created(){
    },
    computed:{
    },
    methods:{
    },
    mounted() {
        // 思路: 依次删除第一个 添加到最后一个
        // setTimeout(() => {
        //     this.colors = ['red','green','black']
        // }, 1000);   
        this.timer =  setInterval(() => {
            let last = this.colors.pop()
            console.log(last);
            this.colors.unshift(last)
        }, 1000);  
    },
    beforeDestroy() {
        // 注意定时器的销毁
        clearInterval(this.timer)
        this.timer = null
    },
}
</script>
<style lang="scss" scoped>
.demo{
    width: 50px;
    height: 50px;
    border: 1px solid #ddd;
}
</style>

使用 效果根据项目而定

选项卡组件(1)

<template>
    <div class="container">
        <ul class="titles">
            <li v-for="(item,idx) in titles" :key="idx"
            :class="{active:idx===active}"
            @click="active=idx"
            >{{item}}</li>
        </ul>
        <div>
            <slot></slot>
        </div>
    </div>
</template>
<script>
export default {
    name: 'TabControl',
    props:{
        value:{
            type:Number,
            required:true,
            default:0
        }
    },
    data() {
        return {
            titles:[],
            active:0
        }
    },
    created(){
    },
    computed:{
    },
    methods:{
    },
    mounted() {
        console.log(this.$children)
        // 当前组件中的孩子组件的个数
        // this.$children[2].show = true
        this.$children[this.active].show = true
    },
    watch: {
        active(idx){
            this.$children.forEach((item,j)=>{
                item.show = idx === j
            })
            // 或者写法如下
            // this.$children.forEach(item=>{
            //     item.show  = false
            // })
            // this.$children[idx].show = true

            // 把当前的i传递给外面
            this.$emit('input',idx)
        }
    },
}
</script>
<style lang="scss" scoped>
.container{
    width: 600px;
    border: 1px solid red;
}
.container .titles{
    display: flex;
    justify-content: center;
    align-items: center;
}
.container .titles li{
    flex: 1;
    text-align: center;
    padding: 20px;
}
.container .titles .active{
    background: red;
    color: #fff;
}
</style>
<template>
    <div v-show="show">
        <slot></slot>
    </div>
</template>
<script>
export default {
    name: 'TabItem',
    props:{
        label:{
            type:String
        }
    },
    data() {
        return {
            show:false
        }
    },
    created(){
        // 当前组件中的父亲组件中的参数
        console.log(this.$parent.titles)
        this.$parent.titles.push(this.label)
    },
    computed:{

    },
    methods:{

    },
}
</script>
<style lang="scss" scoped>

</style>

使用组件

<template>
    <div>
        {{index}}
        <!-- 这里的style可以设置大小 会自动添加到组件样式中 -->
        <TabControl v-model="index" style="width:400px">
            <tabItem label="全部"></tabItem>
            <tabItem label="已购买"></tabItem>
            <tabItem label="未购买"></tabItem>
            <tabItem label="待发货"></tabItem>
        </TabControl>
    </div>
</template>

<script>
import TabControl from '../../components/TabControl';
import tabItem from '../../components/TabItem';
export default {
    name: 'detailsCenter',
    components:{
        TabControl,
        tabItem
    },
    data() {
        return {
            index:0
        }
    },
    created(){
    },
    computed:{
    },
    methods:{

    },
}
</script>
<style lang="scss" scoped>

</style>

选项卡组件(2)

<template>
    <div class="container">
        <div class="wrapper">
            <div>
                {{label}}
            </div>
            <ul class="item-li">
                <li :class="{active:idx===active}" 
                    v-for="(item,idx) in itemCount" :key="idx"
                    @click="active=idx"
                ></li>
            </ul>
            <div class="flex btns">
                <div class="arrow" @click="active--"></div>
                <div class="arrow"  @click="active++"></div> 
            </div>
        </div>

        <div>
            <slot></slot>
        </div>
    </div>
</template>
<script>
export default {
    name: "TabControl",
    props: {
        value: {
            type: Number,
            required: true,
            default: 0,
        },
        label:{
            type:String,
        }
    },
    data() {
        return {
            titles: [],
            active: 0,
            itemCount:0
        };
    },
    methods: {},
    computed: {
    },
    created() {},
    mounted() {
        console.log(this.$children);
        // 当前组件中的子组件的个数
        this.itemCount = this.$children.length

        this.$children[0].show = true
    },
    watch: {
        active(idx){
        	// 下一个、上一个的切换判断
            let max = this.$children.length
            if(idx < 0) this.active = max - 1
            else if(idx >= max) this.active = 0
            this.$children.forEach((item,j)=>{
                item.show = idx === j
            })
            // 或者写法如下
            // this.$children.forEach(item=>{
            //     item.show  = false
            // })
            // this.$children[idx].show = true
            // 把当前的i传递给外面
            this.$emit('input',idx)
        }
    },
};
</script>
<style lang="scss" scoped>
.flex{
    display: flex;
    justify-content: center;
    align-items: center;
}
.container {
    width: 600px;
    border: 1px solid red;
}
.container .item-li {
    display: flex;
    justify-content: center;
    align-items: center;
}
.container .item-li li {
    text-align: center;
    padding: 20px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #ddd;
    cursor: pointer;
}
.container .item-li .active {
    color: red;
    background: #aaa;
}
.wrapper {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-content: center;
}
.btns{
    margin: 0 10px;
    cursor: pointer;
}
.btns .arrow{
    padding: 0 10px;
}
</style>

使用

<template>
    <div>
        {{index}}
        <!-- 这里的style可以设置大小 会自动添加到组件样式中 -->
        <tab v-model="index" label="电影" style="width:600px">
            <tabItem>想见你</tabItem>
            <tabItem>火影忍者</tabItem>
            <tabItem>当幸福来敲门</tabItem>
            <tabItem>肖克申的救赎</tabItem>
        </tab>

        <tab v-model="index" label="书籍" style="width:400px">
            <tabItem>平凡的世界</tabItem>
            <tabItem>高级编码规范</tabItem>
            <tabItem>马克思理论</tabItem>
            <tabItem>邓小平思想</tabItem>
        </tab>
    </div>
</template>

<script>
import tab from '../../components/Tab';
import tabItem from '../../components/TabItem';
export default {
    name: 'detailsCenter',
    components:{
        tabItem,
        tab
    },
    data() {
        return {
            index:0
        }
    },
    created(){
    },
    computed:{
    },
    methods:{

    },
}
</script>
<style lang="scss" scoped>
</style>

在这里插入图片描述

分页的下拉框组件

基于框架使用,可根据ant 或者element 中组件来封装使用
在这里插入图片描述
在这里插入图片描述

<template>
    <div>
      <a-popover placement="bottomLeft" trigger="click" v-model="visible">
            <template slot="content">
                <ul class="list">
                    <li v-for="(item,idx) in options" :key="idx" @click="setVal(item)">{{item.areaName}}</li>
                </ul>
                {{pageIndex}}
                <a-pagination size="small" v-model="pageIndex" :total="total" :page-size="pageSize" />
            </template>
            <template slot="title">
                <span>Title</span>
            </template>
            <div class="sb-select-pager flex">
                <div>{{currentItem.areaName}}</div>
                <a-icon type="down" class="select-icon" :class="{up:visible}"></a-icon>
            </div>
        </a-popover>
    </div>
</template>
<script>
// 注意这里需要进一步根据情况封装请求接口
import {getPageData} from '../api/test'
export default {
    name: 'SelectWithPager',
    props:{
        value:{
            type:Number || String,
            default:0
        },
        actionUrl:{
            type:String,
            required:true,
        }
    },
    data() {
        return {
            visible:false,
            currentItem:[],
            options:[],
            pageIndex:1,
            pageSize:10,
            total:0,
        }
    },
    created(){
        // 请求分页数据
        this.getList()
        this.currentItem = this.options.find((r)=>{
            r.id ===  this.value
        }) || {}
      
    },
    watch: {
        // 当pageIndex变化时调用函数
        pageIndex(){
            this.getList()
        }
    },
    computed:{
    },
    methods:{
        setVal(val){
            this.currentItem = val
            console.log(val);
            this.visible = false
            this.$emit("change",{...this.currentItem})
            this.$emit("input",val.id)
        },
        // 请求分页数据
        async getList(){
            let params = {
                page : this.pageIndex, 
                limit: this.pageSize,
                city: '',
                district:'',
                r: '',
                lon: '',
                lat:'',
                tmt: '',
                secondTmt: '',
                dayExposure: '',
                ratio: '',
                // actionUrl:actionUrl
                // actions-url 地址可以传递进去 方便修改地址不同,请求的数据不同
            }
            let {data} = await getPageData(params)
            console.log(data)
            // 注意这里可以将接口中的字段改为组件所需要的字段 map转换
            this.options = data.advertInfoList
            this.total = Number(data.total)
        }
    },
}
</script>
<style lang="scss" scoped>
.flex{
    display: flex;
    justify-content: space-evenly;
    align-items: center;
}
.list li:hover{
    cursor: pointer;
    background: #ccc;
}
.sb-select-pager{
    width: 200px;
    height: 40px;
    border: 1px solid #ccc;
    margin: 50px;
}
.select-icon{
   transition: 0.5s; 
}
.up{
    transform:rotate(180deg);
}
</style>

使用

<template>change
    <div>
        {{select}}
        <!-- 这里的 action-url 是为了请求接口时的url地址 -->
        <SelectWithPager @change="change" v-model="select" action-url="/aaa/bbb/ccc"></SelectWithPager>
    </div>
</template>
<script>
import SelectWithPager from '../../components/SelectWithPager'
export default {
    name: 'mine',
    components:{
        SelectWithPager
    },
    data() {
        return {
           select:2,
        }
    },
    created(){
    },
    computed:{
    },
    methods:{
        change(val){
            console.log(val);
        }
       
    },
}
</script>
<style lang="scss" scoped>

</style>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值