微信小程序组件迁移到uni-app

1,883 阅读3分钟
原文链接: hexo.hainuo.info

近期在使用 uniapp, 但是并没后搞懂他是如何将小程序的组件应用再 uniapp 中的。
这个问题是我在使用了 vant 的小程序组件 (vant-weapp) 后发现的。

首先我创建了一个 自定义导航栏样式的 uniapp

操作:
在项目根目录下的 pages.json 文件中 定义全局样式 globalStyle 设置
"navigationStyle" : "custom"
然后在跳转之后的页面添加了一个自定义组件
操作:
在项目根目录下的 pages.json 文件,跳转的页面属性 styles 中增加设置

> {
>   "path" : "pages/about/about",
>   "style" : {
>       "usingComponents":{
>           "van-nav-bar":"/wxcomponents/vant/nav-bar/index"
>       }
>   }
> }
>

然后打开 pages/about/about.vue 文件
templae下的view节点中加入

> <vant-nav-bar  title="关于我们" left-text="返回" right-text="" left-arrow bind:click-left="goBack" />
>

<script></script>methods 属性中加入

> goBack(){
>   uni.navigateBack({delta:1})
> }
>

这个时候点击 navbar显示效果的 返回就会看到控制台报错
11:32:20.221 [WARN] : Component "pages/about/about" does not have a method "goBack" to handle event "click-left".
此问题已经提交到 dcloud

解决办法 手工创建一个组件

  1. 找到 vant-weappnav-bar组件
  2. index.wxml 的内容放到template
  3. index.js 的内容放到script
  4. index.wxss的内容放到 style
  5. 然后修改语法
    1. solt 节点删掉 (我用不到这个东西,如果你有用需要自行处理)
    2. block 改为 template
    3. wx:if 改为 v-if
    4. 样式关联修正
    5. class 关联修正
    6. 其他 weapp 和 vue 不同的地方
  6. 我的成品如下
<template>
	<view :class="{customClass:true, vanNavBar:true, 'van-hairline--bottom':true , 'van-nav-bar--fixed':fixed }">
	  <view class="van-nav-bar__left" @click="onClickLeft">
	    <template v-if="leftArrow||leftText">
	      <van-icon
	        v-if="leftArrow"
	        name="arrow"
	        custom-class="van-nav-bar__arrow"
	      />
	      <view v-if="leftText" class="van-nav-bar__text">{{ leftText }}</view>
	    </template>
	    <!-- <slot v-else name="left" /> -->
	  </view>
	  <view class="van-nav-bar__title title-class van-ellipsis">
	    <template v-if="title">{{ title }}</template>
	    <!-- <slot v-else name="title" /> -->
	  </view>
	  <view class="van-nav-bar__right" @click="onClickRight">
	    <view v-if="rightText" class="van-nav-bar__text">{{ rightText }}</view>
	    <!-- <slot v-else name="right" /> -->
	  </view>
	</view>
</template>
<script>
	export default {
		props:{
			fixed:Boolean,
			leftArrow:Boolean,
			leftText:String,
			title:String,
			rightText:String,
		},
		methods:{
			onClickLeft: function onClickLeft() {
				this.$emit('click-left');
			},
			onClickRight: function onClickRight() {
				this.$emit('click-right');
			}
		}
	}
</script>
<style>
.van-ellipsis {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.van-multi-ellipsis--l2 {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.van-multi-ellipsis--l3 {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}
.van-clearfix::after {
    content: '';
    display: table;
    clear: both;
}
.van-hairline,
.van-hairline--bottom,
.van-hairline--left,
.van-hairline--right,
.van-hairline--surround,
.van-hairline--top,
.van-hairline--top-bottom {
    position: relative;
}
.van-hairline--bottom::after,
.van-hairline--left::after,
.van-hairline--right::after,
.van-hairline--surround::after,
.van-hairline--top-bottom::after,
.van-hairline--top::after,
.van-hairline::after {
    content: ' ';
    position: absolute;
    pointer-events: none;
    box-sizing: border-box;
    -webkit-transform-origin: center;
    transform-origin: center;
    top: -50%;
    left: -50%;
    right: -50%;
    bottom: -50%;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    border: 0 solid #eee;
}
.van-hairline--top::after {
    border-top-width: 1px;
}
.van-hairline--left::after {
    border-left-width: 1px;
}
.van-hairline--right::after {
    border-right-width: 1px;
}
.van-hairline--bottom::after {
    border-bottom-width: 1px;
}
.van-hairline--top-bottom::after {
    border-width: 1px 0;
}
.van-hairline--surround::after {
    border-width: 1px;
}
.van-nav-bar {
    height: 46px;
    position: relative;
    -webkit-user-select: none;
    user-select: none;
    text-align: center;
    line-height: 46px;
    background-color: #fff;
}
.van-nav-bar__arrow {
    color: #1989fa;
    vertical-align: middle;
    -webkit-transform: rotate(180deg);
    transform: rotate(180deg);
}
.van-nav-bar__arrow + .van-nav-bar__text {
    margin-left: -20px;
    padding-left: 25px;
}
.van-nav-bar--fixed {
    top: 0;
    left: 0;
    width: 100%;
    position: fixed;
}
.van-nav-bar__title {
    margin: 0 auto;
    max-width: 60%;
    font-size: 16px;
    font-weight: 500;
}
.van-nav-bar__left,
.van-nav-bar__right {
    bottom: 0;
    font-size: 14px;
    position: absolute;
}
.van-nav-bar__left {
    left: 15px;
}
.van-nav-bar__right {
    right: 15px;
}
.van-nav-bar__text {
    color: #1989fa;
    margin: 0 -15px;
    padding: 0 15px;
    display: inline-block;
    vertical-align: middle;
}
.van-nav-bar__text:active {
    background-color: #e8e8e8;
}
</style>