天天看點

weex學習之路(二)---元件封裝(1)

不管是為了解耦還是為了代碼的複用,元件封裝都是必須要的。

因為weex使用flex布局,是以每個頁面都可以抽象成 頭部(頂部導航),身體(主體内容),腳(底部),

當然,并不是所有的頁面存在這3個要素,是以元件需要支援一些配置,具體代碼如下:

<template>
<div class="app" :style="viewStyle">
    <div class="app_header" :style="headerStyle" v-if="view.useHeader">
        <slot name="app-header"></slot>
    </div>
    <scroller v-if="view.bodyScroll" show-scrollbar="false" :style="view.scrollerStyle">
        <slot name="app-body"></slot>
    </scroller>
    <div class="app_body" :style="bodyStyle" v-else>
        <slot name="app-body"></slot>
    </div>
    <div class="app_footer" :style="footerStyle" v-if="view.useFooter">
        <slot name="app-footer"></slot>
    </div>
 </div>
 </template>

  <script>
  import fadeIn from '../mixins/FadeIn';
  export default{
     mixins: [fadeIn],
    props: {
        view: {
            type: Object,
            default: function () {
                return {
                    viewStyle:{flex:"1"},
                    bodyScroll: false,   //頁面主體是否可以滾動
                    bodyPadding: true,   //頁面主體是否需要左右padding (預設20)
                    bodyIsCenter: true,  //頁面主體内容是否居中(水準和垂直)
                    bodyBackgroundColor: "#f2f2f2", //頁面主體背景色
                    useHeader: true,     //是否使用頁面頭部
                    useFooter: true,     //是否使用頁面底部
                    headerHeight: "100px", //頁面頭部高度
                    footerHeight: "80px",   //頁面底部高度
                    scrollerStyle:{flex:"1"}
                }
            }
        }
    },
    data(){
        const {headerHeight, footerHeight, bodyBackgroundColor, bodyPadding, bodyIsCenter} = this.view;
        const headerStyle = {
            height: headerHeight
        };
        const footerStyle = {
            height: footerHeight,
            backgroundColor: bodyBackgroundColor
        };
        const bodyStyle = {
            backgroundColor: bodyBackgroundColor,
        };
        if (bodyPadding) {
            bodyStyle.paddingLeft = "20px";
            bodyStyle.paddingRight = "20px";
        }
        if (bodyIsCenter) {
            bodyStyle.justifyContent = "center";
            bodyStyle.alignItems = "center";

        }
        return {
            headerStyle,
            bodyStyle,
            footerStyle
        }
    }
}

 </script>

<style scoped>
.app {
    flex-direction: column;
}

.app_header {
    justify-content: flex-start;
}
.app_body {
    flex: 1;
    flex-direction: column;
}

.app_footer {
    justify-content: flex-end;
}
</style>
           

然而頭部的導航欄一般也是比較通用的也可以抽象一下

<template>
<div>
    <div v-if="ios" class="ios_top" :style="iosTopStyle"></div>
    <div class="header" :style="style">
        <div @click="clickBackButton" :style="backStyle" class="left-back" v-if="useBack">
            <image class="back" :src="backIconUrl"></image>
            <text v-if="leftText" :style="leftTextStyle">{{leftText}}</text>
        </div>
        <text v-if="title.length>0"
              :style="titleStyle"
              @click="clickText"
              :value="title"></text>
        <text v-if="rightText.length>0"
              class="right-content"
              @click="clickRight"
              :style="rightTextStyle"
              :value="rightText">
        </text>
        <image v-if="rightIcon.length>0"
               class="right-content"
               @click="clickRight"
               :style="rightIconStyle"
               :src="rightIcon">
        </image>
    </div>
</div>
 </template>

 <script>
   import weexUtils from "../../utils/WeexUtils";
   import GlobalApiConfig from "../../api/config/GlobalAipConfig";

const appHeaderConfig = GlobalApiConfig.APP_HEADER_CONFIG;

export default {
    name: "app-header",
    props: {
        useBack: {default: true},
        title: {
            default: ""
        },
        rightText: {default: ""},
        rightIcon: {default: ""},
        leftText: {default: ""},
        leftTextStyle: {
            default: {
                fontSize: "32px",
                color: "#ffffff"
            }
        },
        leftStyle: {
            default: {
                width: "100px"
            }
        },
        backIconUrl: {default: weexUtils.getResourcesURL(appHeaderConfig.backImage, weex)},
        headerStyle: {default: {}},
        headerIosTopStyle: {default: {}},
        headerTitleStyle: {default: {}},
        headerRightStyle: {default: {}}
    },
    data() {
        let result = appHeaderConfig.data;
        result.ios = false;
        return Object.assign({
            backStyle: {height: "100px"},
            rightTextStyle: {
                right: "15px",
                fontSize: "32px",
                color: ": #ffffff"
            },
            rightIconStyle: {
                right: "22px",
                top: "22px",
                width: " 56px",
                height: "56px"
            }
        }, result);
    },
    methods: {
        clickBackButton: function () {
            this.$emit("backPage");
        },
        clickText() {
            this.$emit("clickHeaderText");
        },
        clickRight() {
            this.$emit("clickHeaderRightText");
        }
    },
    created() {
        this.ios = weex.config.env.platform.toLowerCase() === "ios";
        this.style = Object.assign({}, this.style, this.headerStyle);
        this.backStyle = Object.assign(this.backStyle, this.leftStyle);
        if (this.style.height) {
            this.backStyle.height = this.style.height;
        }
        this.iosTopStyle = Object.assign({}, this.iosTopStyle, this.headerIosTopStyle);
        this.titleStyle = Object.assign({fontSize:"36px"}, this.titleStyle, this.headerTitleStyle);
        if (this.rightText.length > 0) {
            this.rightTextStyle = Object.assign({}, this.rightTextStyle, this.headerRightStyle);
        } else {
            this.rightIconStyle = Object.assign({}, this.rightIconStyle, this.headerRightStyle);
        }
    }
}
   </script>

 <style scoped>
.ios_top {
    flex: 1;
}

.header {
    flex-direction: row;
    justify-content: center;
    align-items: center;
    position: relative;
    border-bottom-width: 1px;
    border-bottom-style: solid;

}

.back {
    width: 40px;
    height: 40px;
}

.left-back {
    flex-direction: row;
    position: absolute;
    justify-content: center;
    align-items: center;
    left: 0;
    top: 0;
}

.right-content {
    position: absolute;
}

 </style>
           

其他的也類似(頁面底部,主體内容)都可以抽象一些通用的東西出來,具體的可以參考

https://github.com/fengwuxp/weex_componets