超简单实现自定义弹窗

快应用promt.showDialog接口提供的弹框只能显示文字、按钮简单的元素,无法实现复杂的页面效果。但往往产品经理设计的弹框页面效果很炫,怎么办呢?

比如实现如下弹窗效果:展示一个列表,左边显示图片,右边显示具体介绍,见图1;提示用户查看应用隐私协议弹窗效果,里面内容有超链接效果,能点击,见图2: 

 

图1  列表弹窗                                 图2  超链接弹窗

此问题一般是开发者对快应用组件、样式属性使用不熟悉导致的。

解决方法

基于stack组件+position:fixed css样式可以实现自定义弹窗,弹窗显示隐藏基于if/show指令来控制,具体代码如下:

  1.  初始化数据模型:

1
2
3
4
5
6
7
8
data() {
      return {
        list: [1, 2, 3],
        isShow: false,
        ifShow1: false,
        ifShow2: false
      }
    },

2. 页面布局:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<text onclick="showToast1">自定义弹窗样式1</text>
    <text onclick="showToast2">自定义弹窗样式2</text>
    <!-- 弹窗 -->
    <div if="{{isShow}}" class="modal center-modal">
      <div class="toast-box password-box">
        <block>
          <stack class="eyes-input-box">
            <div style="flex-direction: column; 100%;" if="{{ifShow1}}">
              <div style=" 100%;">
                <text style="font-size: 32px;font-weight: 500;">交通违法</text>
                <text style="font-size: 25px;text-align: right;padding-left: 400px" onclick="hide">隐藏</text>
              </div>
              <list style="height: 550px">
                <list-item type="list" for="list" style="height: 160px;margin-top: 20px">
                  <div style="padding-top: 1px;">
                    <image src="/Common/icon.png" style="border-radius: 100%; 100px;height: 100px;"></image>
                    <div style="flex-direction: column; margin-left: 20px">
                      <text style="font-size: 28px;font-weight: 600;">二级标题</text>
                      <text style="font-size: 26px;margin-top: 10px">相关内容展示,例如商品属性、价格、上架日期等信息展示</text>
                      <div style="height: 2px;bottom: 0;margin-top: 25px" if="{{$idx<2}}">
                    </div>
                    </div>
                     
                  </div>
                </list-item>
              </list>
            </div>
            <div style="flex-direction: column; 100%;" if="{{ifShow2}}">
              <text style="font-size: 31px;font-weight: 700;">城市服务</text>
              <text style="font-weight: 400;"><span>点击“同意”,即表示您同意上述内容及</span><a style="color: #0000ff;" onclick="toast">应用名称的用户协议</a>
                <span>、</span><a style="color: #0000ff;" onclick="toast">关于应用名称与隐私的声明</a></text>
              <div style=" 100%;">
              <text style=" 50%; text-align: center; color: #0000ff;" onclick="hide">确认</text>
              <text style=" 50%; text-align: center; color: #0000ff;" onclick="hide">取消</text>
              </div>
            </div>
          </stack>
        </block>
      </div>
    </div>

页面样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    .body {
         100%;
        height: 100%;
        flex-direction: column;
        align-items: center;
        .img {
            margin-top: 500px;
        }
        .txt {
            margin-top: 570px;
        }
    }
  
    // 弹窗样式
.modal {
    position: fixed;
    flex-direction: column;
    justify-content: flex-end;
     100%;
    height: 100%;
    padding: 0 34px 34px;
    rgba(0, 0, 0, 0.18);
    animation-name: Modal;
    animation-duration: 130ms;
    animation-timing-function: ease-in;
    .toast-box {
       100%;
      padding: 25px 50px 20.8px;
      border-radius: 34px;
      white;
      flex-direction: column;
      .toast-title {
        font-size: 41.6px;
        line-height: 56px;
        font-weight: 500;
        font-family: HWtext-65ST;
        color: #000000;
      }
      .toast-tip {
        font-family: HWtext-55ST;
        font-size: 29px;
        color: rgba(0, 0, 0, 0.6);
        line-height: 40px;
        margin-top: 3.6px;
        margin-bottom: 25px;
      }
      .label-box {
        height: 100px;
        border-bottom: 1px solid rgba(0, 0, 0, 0.1);
        .label {
          color: #000000;
           100%;
          font-family: HWtext-55ST;
          font-size: 34px;
        }
        input {
          margin-right: -11px;
        }
      }
      .manage {
        height: 100px;
        font-family: HWtext-65ST;
        font-size: 29.12px;
        color: #007dff;
        font-weight: 500;
      }
      .cancel {
         100%;
        height: 75px;
        margin-top: 37.44px;
        text-align: center;
        font-family: HWtext-65ST;
        font-size: 33.28px;
        color: #007dff;
        font-weight: 500;
      }
      .btn-box {
        justify-content: space-between;
        align-items: center;
        .bind {
           47%;
          height: 60px;
          border-radius: 10px;
          font-family: HWtext-65ST;
          text-align: center;
          font-size: 33.28px;
          color: #007dff;
          margin: 16px 0;
          font-weight: 500;
        }
        .line {
          height: 50px;
           1px;
          rgba(0, 0, 0, 0.2);
        }
        .quit {
           47%;
          height: 60px;
          border-radius: 10px;
          text-align: center;
          font-family: HWtext-65ST;
          font-size: 33.28px;
          color: #007dff;
          margin: 16px 0;
          font-weight: 500;
        }
        .bind:active {
          rgba(0, 0, 0, 0.1); // 待高保真修改
        }
        .quit:active {
          rgba(0, 0, 0, 0.1); // 待高保真修改
        }
      }
      .nocar-tip {
        height: 99.84px;
        font-size: 33.28px;
        font-family: HWtext-55ST;
        color: #000000;
        border-bottom: 1px solid rgba(0, 0, 0, 0.1);
      }
    }
    .password-box {
      margin-top: -110px;
      padding: 30.63px 50px 20.8px;
      .toast-title {
        height: 55.64px;
        margin-bottom: 30.12px;
      }
      .password-tip {
        flex-direction: column;
        margin-top: 3.6px;
        margin-bottom: 25px;
        .control-tip {
          font-family: HWtext-55ST;
          font-size: 24.96px;
          color: rgba(0, 0, 0, 0.6);
        }
      }
      .error-password-tip {
        font-family: HWtext-55ST;
        font-size: 24.96px;
        color: #fa2a2d;
        height: 32.76px;
        margin-bottom: 37.4px;
        margin-top: 0;
      }
      .btn-box {
        .bind {
          margin-top: 8px;
          margin-bottom: 8px;
        }
        .quit {
          margin-top: 8px;
          margin-bottom: 8px;
        }
      }
   
      .eyes-input-box {
         100%;
        flex-direction: row;
        justify-content: flex-end;
        .input-password {
           100%;
          height: 94.64px;
          border: 1px solid #ffffff;
          border-bottom-color: #000000;
          padding: 11.44px 0;
          margin-bottom: 20.8px;
        }
        .password-text {
           100%;
          height: 94.64px;
          padding: 11.44px 0;
          border-bottom: 1px solid #000000;
          margin-bottom: 20.8px;
          color: #000000;
          font-size: 36px;
        }
        .eyes-img {
           49.92px;
          height: 49.92px;
          margin-top: 23px;
        }
      }
   
      .password-loading-box {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        height: 150px;
        .loading-text {
          font-family: HWtext-55ST;
          font-size: 33.28px;
          color: rgba(0, 0, 0, 0.96);
        }
        .loading-circular {
           102px;
          height: 102px;
          color: #666666;
        }
      }
    }
  }
}

事件绑定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
showToast1() {
      this.isShow = true;
      this.ifShow1 = true
      this.ifShow2 = false
    },
    showToast2() {
      this.isShow = true;
      this.ifShow1 = false
      this.ifShow2 = true
    },
    hide(){
      this.isShow = false;
    },
    toast() {
      prompt.showToast({
        message: '查看隐私协议'
      })
}

欲了解更多详情,请参阅:

快应用开发指导文档:https://developer.huawei.com/consumer/cn/doc/development/quickApp-Guides/quickapp-whitepaper

快应用Style样式:

https://developer.huawei.com/consumer/cn/doc/development/quickApp-References/quickapp-style

快应用通用样式:

https://developer.huawei.com/consumer/cn/doc/development/quickApp-References/quickapp-common-settings#h1-1575449213432

原文地址:https://www.cnblogs.com/developer-huawei/p/14609602.html