学习-微信小程序-数据绑定-条件渲染-列表渲染-模版template定义及使用-view的hidden、display的属性

本文详细介绍微信小程序开发中的关键知识点,包括数据绑定、事件处理、模板使用、列表与条件渲染等核心功能,并通过具体实例展示了hidden与display属性在视图隐藏控制上的区别。

日常练习微信小程序,及常用的知识点、模版使用的规则及注意事项

特别注意:微信小程序中的hidden属性、display样式实现隐藏属性,下面的代码中也有举例使用。二者都能实现view隐藏

经过练习例子验证,及查看网上一些大牛的帖子后,自己简单总结如下:

   使用display:none控制显隐 并且可由js来动态控制,效果较好,hidden 隐藏布局,虽然隐藏了,但还是会占空间,display:none 隐藏不占据空间。

wx:if与hidden、display的区别:hidden虽然隐藏了视图组件,但组件仍然会渲染;display:none与hidden=true的效果是一样的,display:none仍然会渲染组件,而 wx:if只有在条件变成真的时候才开始局部渲染,如果条件为假,整个view块不是隐藏起来,而是根本没有生成。而hidden、display,只是使view块隐藏,但view块真实存在


效果 图:效果图续:

wxml代码如下:

<view class="container">
      <view class="test">数据绑定-练习</view>
      <view>{{mesg}}</view>
      <view class="event1" bindtap="event_test1">点击了{{count2}}次</view>
      <view class="event2" bindtap="event_test2">点击了{{count1}}次</view>

     <!--定义模版,模版不会显示出来,只会显示模版里的内容-->
    <view class="test">模版-练习</view> 
    <template name="demo_template">
        <view>姓名:{{name}}  年龄:{{age}}</view>
    </template>

   <!--使用模版,is表示使用的模版名称,data表示数据的来源,(数据在js里)-->
 <!--   <template is="demo_template" data="...zhangshan"></template>中的data引入数据的格式错误-->
    <template is="demo_template" data="{{...zhangshan}}"></template>
    <template is="demo_template" data="{{...lisi}}"></template>


    <!--列表渲染-->
    <view class="test">列表渲染-练习</view>
    <view wx:for="{{array}}">{{item}}</view>
    <!--注意,格式容易出错,记住for后面的写法,item的写法,如何把列表内的元素输出-->


    <!--条件渲染,记住条件渲染的格式-->
    <view class="test">条件渲染-练习</view>
    <view wx:if="{{view_if=='1'}}">杰</view> <!--比较时,判断相等用“==”两个等于-->
    <view wx:elif="{{view_if=='2'}}">伟</view><!--在wxml文件中,字符串用单引号括起来,双引号会报错-->
    <view wx:else="{{view_if=='3'}}">王激动</view>


    <!--条件渲染例2,把条件判断放在block快中,一个条件可以控制多个view显示或都不显示-->
    <block wx:if="{{continue=='你'}}">
        <view>条件渲染例2</view>
        <view class="test2">{{continue+'好,我是机器人!'}}</view>
        <!--此处字符串用单引号或双引号都可以,加号表示字符串连接,continue是个字符串变量,在js中定义的-->
        <view class="test2">{{continue+"、我、他,大家都快乐!"}}</view>
    </block>


    <!--view内容显示与否,hidden(true/false)/display:(none/block)-->
    <!--两种方法,都可易实现相同的效果,但hidden在赋值时,只能用逻辑值,不能用表达式和逻辑变量-->
    <view class="test2" hidden="{{true}}">hidden/display:none练习1</view>
    <view class="test2" hidden="{{flag}}">hidden/display:none练习2</view><!-该View无法正常显示-->
    <!--flag是逻辑变量,虽然值为true,但还是无法显示-->
    <view class="test2"  style="display:none">hidden(true/false)/display:(none/block)练习3</view><!-正常隐藏-->
    <view class="test2"  style="display:block">hidden(true/false)/display:(none/block)练习4</view>
    <view class="test2" style="display:{{flag2}}">hidden(true/false)/display:(none/block)练习5</view><!--通过js动态传参控制-->

    <view class="test">运算例子-练习</view>
    <!--三目运算符-->
    <view hidden="{{flag ? true : false}}">三目运算符练习</view><!--hidden不能用这种-->
    <view wx:if="{{flag ? true : false}}">三目运算符练习</view>
    
    <!--{{}}双层大括号内可以进行算术运算-->
    <view class="test2">双层大括号内可以进行算术运算,如下:</view>
       <view class="test2"> {{aa}}+{{bb}}={{aa+bb}}</view>
    <view class="test2">双层大括号内可以字符串连接,如下:</view>
    <view class="test2">{{continue+'好,我是机器人!'}}</view>
</view> 

js代码如下:

var parm={
  data : {
    mesg : '你好',
    count1 : 0,
    count2:0,
    array:[0,1,2,3,4,'hello'],
    /*下面是模版需使用的数据,注意记住格式*/
    zhangshan :{ name:'张三', age:'17' },//变量之间有逗号
    lisi :{ name: '李四', age:20},

    /*条件渲染-条件*/
    view_if:"2",//js中字符串用单引号括起来,也可以用双引号括起来
    continue:'你',
    flag:'true',//在初始化逻辑值时加单引号或双引号,或不加都可以
    flag2:'block',
    aa:6,
    bb:3,
    cc:9,
  },
  /*下面是数据绑定代码*/
  event_test1: function (e) {     /*event_test1与event_test2效果等价,是两种方法实现数据刷新*/
      this.data.count2++;
      var count = this.data.count2;
      parm.data.count2=count;
      this.setData({count2 : count});
      console.log(e);
  },

  event_test2 : function(e){
    parm.data.count1=this.data.count1+1;
    /*注意下面出错的写法,以后避免出现*/
  //  this.setData(count);出错
  //  this.setData({count});出错
   //this.setData(parm.data.count);出错
    //this.setData(this.data);//不出错,数据没有更新
    this.setData(parm.data);
    console.log(e);
  }

/*下面是模版要用到的数据,需写在data里面*/
/*
zhangshan : {
   name:'张三', age :'17'//变量之间有逗号
}
lisi :{
  name:'李四',age:20
}
*/



};
Page(parm);

wxss代码如下:

/**index.wxss**/
.event1{
background-color: lightgreen;
}
.event2{
background-color: pink;
}
.test{
background-color :aqua;
color: red;
font-size: 70rpx;
}
.test2{
background-color: blue;
color:yellow;
font-size: 14px;
}

<think>我们参考了多个引用,特别是引用[1][2][3][5]提到了小程序中input框letter-spacing失效的问题以及解决方法。主要思路是使用透明input框并模拟显示验证码块和光标。 在uniapp中开发微信小程序时,同样可以采用类似的方案。步骤如下: 1. 使用透明input框:设置input为绝对定位,覆盖在模拟的验证码块上,并设置透明度为0(或颜色透明),同时调整宽度和位置使其能够接收输入。 2. 通过letter-spacing将输入的文字间隔拉开(尽管在微信小程序中letter-spacing对input内容本身可能失效,但对placeholder有效,所以我们这里利用letter-spacing来调整透明输入框的字符间距,使得输入的文字实际上被拉开,但通过透明我们看不到,而我们需要通过模拟的块来显示)。 3. 将输入的内容分割成单个字符,显示在模拟的块中(每个块一个字符)。 4. 隐藏原生光标,使用动画模拟一个光标。 具体实现: HTML部分(Vue模板): 我们可以用一个view包裹,内部包含一个透明的input(用于输入)和一组用于显示验证码的view(每个数字一个块)。同时,为了模拟光标,可以在当前输入位置放置一个光标view。 CSS部分: 设置透明input的样式,特别是letter-spacing(用于拉开输入的字符)和位置。同时设置模拟块的样式,以及光标的样式和动画。 逻辑部分: 绑定input事件,当输入时,将输入值分割成数组(每个字符),并更新到模拟块的显示中。同时控制光标的位置(根据当前输入的长度)。 注意:由于是uniapp,我们使用rpx单位,并且样式需要写在<style scoped>中(或者使用全局样式)。 以下是具体代码示例: 模板部分: ```html <template> <view class="container"> <!-- 模拟显示验证码的块 --> <view class="code-box"> <view class="code-item" v-for="(item, index) in codeArr" :key="index"> <text class="code-text">{{ item }}</text> <!-- 在当前位置显示光标 --> <view class="cursor" v-if="showCursor && index === codeArr.length"></view> </view> </view> <!-- 透明的输入框 --> <input class="input-real" type="text" maxlength="6" v-model="inputValue" @input="onInput" @focus="onFocus" @blur="onBlur" /> </view> </template> ``` 样式部分(注意调整透明输入框的位置和大小,使其覆盖在模拟块上,并且letter-spacing要设置得足够大以匹配每个块的间距): ```css <style scoped> .container { position: relative; width: 100%; } .code-box { display: flex; flex-direction: row; justify-content: center; } .code-item { width: 80rpx; height: 80rpx; line-height: 80rpx; border: 1rpx solid #ccc; margin-right: 20rpx; text-align: center; position: relative; } .code-text { font-size: 40rpx; } /* 透明输入框 */ .input-real { position: absolute; top: 0; left: 0; width: 100%; /* 宽度要覆盖整个模拟块区域 */ height: 80rpx; opacity: 0; /* 设置letter-spacing,使得输入的每个字符之间有足够的间隔,这样在模拟块中就可以分开显示 */ letter-spacing: 100rpx; /* 这个值需要根据块之间的间距调整,确保每个字符落在对应的块中 */ /* 注意:由于设置了letter-spacing,输入框的宽度需要足够宽,所以这里设置100%可能不够,可能需要增加宽度,比如用left和right调整 */ padding-left: 0; /* 根据实际位置调整 */ z-index: 2; /* 确保在模拟块上方 */ background: transparent; color: transparent; /* 文字透明 */ caret-color: transparent; /* 光标透明 */ } .cursor { position: absolute; top: 10%; left: 50%; transform: translateX(-50%); width: 2rpx; height: 80%; background-color: #000; animation: blink 1s infinite; } @keyframes blink { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 0; } } </style> ``` 逻辑部分: ```javascript <script> export default { data() { return { inputValue: '', // 输入的值 codeArr: ['', '', '', '', '', ''], // 用于显示验证码的数组,初始6个空字符 showCursor: false, // 是否显示光标 }; }, methods: { onInput(e) { // 获取输入的值 let value = e.detail.value; // 限制长度为6 if (value.length > 6) { value = value.substring(0, 6); } // 更新inputValue this.inputValue = value; // 将输入的值分割成数组,并更新codeArr const arr = value.split(''); // 将数组扩展到6个,不足的用空字符串填充 for (let i = 0; i < 6; i++) { this.codeArr[i] = arr[i] || ''; } }, onFocus() { // 获取焦点时显示光标 this.showCursor = true; }, onBlur() { // 失去焦点时隐藏光标 this.showCursor = false; }, }, }; </script> ``` 注意: 1. 这里letter-spacing的值需要根据实际每个块之间的间隔调整。例如,每个块宽度80rpx,间隔20rpx,那么每个块占据的空间是100rpx。因此,letter-spacing应该设置为100rpx(因为我们输入一个字符后,下一个字符会出现在100rpx之后)。但是,第一个字符位置从0开始,所以输入框的padding-left可能需要调整(这里设为0),然后通过设置输入框的宽度和位置覆盖整个模拟块区域。 2. 由于输入框是透明的,并且覆盖在模拟块上,用户点击模拟块区域实际上点击的是输入框。 3. 光标显示在当前位置(即当前输入字符的下一个位置)。这里我们通过在code-item中添加一个光标,并判断当前循环的index是否等于当前输入长度(即下一个位置)来显示光标。注意:当输入6个字符后,光标应该不显示(因为已满),所以我们在模板中使用了`index === codeArr.length`,但注意codeArr的长度固定为6,当输入6个字符后,index最大为5,而codeArr.length为6,所以最后一个位置(index=5)不会显示光标(因为5!==6)。所以我们需要调整光标显示的位置逻辑:光标应该显示在输入长度对应的索引位置。例如,输入了0个字符,则光标在0位置;输入了3个字符,则光标在3位置(即第4个块)。因此,我们修改为: v-if="showCursor && index === inputValue.length" 但是,注意我们的v-for循环是固定6个,所以每个code-item对应一个index(0到5)。因此,当输入了6个字符时,inputValue.length为6,此时没有index等于6,所以光标不会显示。当输入0个字符时,我们在index=0的位置显示光标?但是每个code-item里面都有光标,并且只有index=0且输入长度为0时才显示。 因此,修改模板中光标的位置判断: <view class="cursor" v-if="showCursor && index === inputValue.length"></view> 但是注意:在code-item中,每个块对应一个index(0~5)。当输入长度为0时,我们希望在第0个块内显示光标,此时index=0,inputValue.length=0,所以条件为0===0,显示。当输入1个字符时,我们希望在第1个块(index=1)显示光标,条件为1===1,显示。当输入6个字符时,inputValue.length=6,但index最大为5,所以没有块满足index=6,因此不显示。 这样逻辑正确。 4. 由于输入框是透明的,所以需要设置caret-color: transparent;来隐藏原生光标。 这个方案参考了引用中的方法,并结合uniapp进行了实现。 注意:在微信小程序中,letter-spacing对于input的内容可能无效(如引用所述),但是这里我们将其用于设置透明输入框的字符间距,实际上输入的字符在透明输入框内是有间距的,然后我们通过将输入的内容拆分到每个块中,从而实现了视觉上的间距。由于输入框透明,用户看不到输入框内的内容,只能看到模拟块中的内容。 因此,这种方法可以解决letter-spacing失效的问题,并且隐藏了原生光标,用模拟光标代替。 另外,如果需要支持删除操作,这里已经通过input事件处理,当删除时,inputValue会减少,相应的codeArr也会更新。 最后,我们还需要注意在uniapp中,input的样式可能需要根据实际情况调整,特别是letter-spacing的值,以确保每个字符落在对应的块中。如果发现位置不对,可以调整letter-spacing和padding-left等属性。 如果遇到其他问题,可以参考引用[4]中关于textarea的问题(虽然这里是input,但可能有借鉴意义)。 以上是uniapp开发微信小程序时,6位验证码输入框隐藏光标且letter-spacing失效的解决方案。 </think>在 UniApp 开发微信小程序时,解决 6 位验证码输入框的隐藏光标和 `letter-spacing` 失效问题,可参考以下完整方案: ### 解决方案 核心思路:**隐藏原生输入框 + 模拟视觉层** ```html <template> <!-- 外层容器 --> <view class="code-container" @click="focusInput"> <!-- 透明输入框(实际接收输入) --> <input class="hidden-input" type="number" maxlength="6" :focus="isFocused" v-model="inputVal" @input="handleInput" @blur="isFocused = false" /> <!-- 模拟显示层 --> <view class="simulation-box"> <view v-for="(item, index) in codeList" :key="index" class="code-block" > {{ item }} <!-- 模拟光标 --> <view v-if="isFocused && index === inputVal.length" class="simulated-cursor" /> </view> </view> </view> </template> <script> export default { data() { return { inputVal: '', // 输入值 isFocused: false, // 输入框聚焦状态 codeList: ['', '', '', '', '', ''] // 显示用数组 } }, methods: { // 点击容器聚焦输入框 focusInput() { this.isFocused = true }, // 输入处理 handleInput(e) { const val = e.detail.value.replace(/\D/g, '') // 只保留数字 this.inputVal = val // 更新显示数组 this.codeList = this.codeList.map((_, i) => val[i] || '' ) } } } </script> <style scoped> /* 容器定位 */ .code-container { position: relative; height: 100rpx; } /* 隐藏原生输入框 */ .hidden-input { position: absolute; left: -100%; width: 200%; height: 100%; opacity: 0; color: transparent; background: transparent; caret-color: transparent; /* 隐藏原生光标 */ } /* 模拟显示层 */ .simulation-box { display: flex; justify-content: space-between; } /* 验证码块样式 */ .code-block { width: 80rpx; height: 80rpx; border: 1px solid #ddd; display: flex; justify-content: center; align-items: center; font-size: 40rpx; position: relative; } /* 模拟光标动画 */ .simulated-cursor { width: 2px; height: 40rpx; background: #07C160; animation: blink 1s infinite; position: absolute; } @keyframes blink { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } } </style> ``` ### 关键实现原理 1. **隐藏原生输入框**: - 使用绝对定位 `left: -100%` 移出可视区域 - 设置 `opacity: 0` 和 `caret-color: transparent` 彻底隐藏 - 通过容器点击事件触发聚焦 2. **解决 letter-spacing 失效**: - 采用独立块状布局代替输入框间距 - 每个数字单独渲染在 `<view>` 中 - 通过 Flex 布局的 `justify-content: space-between` 控制间距 3. **光标模拟**: - 创建独立光标元素 `.simulated-cursor` - 通过 `v-if="isFocused && index === inputVal.length"` 动态定位 - CSS 动画实现闪烁效果 4. **输入处理**: - 监听 `@input` 事件获取真实输入值 - 用正则 `replace(/\D/g, '')` 过滤非数字字符 - 将字符串拆分为数组渲染到模拟块 ### 注意事项 1. **键盘类型**:`type="number"` 可调起数字键盘 2. **间距调整**:修改 `.code-block` 的 `width` 和容器 `padding` 控制块间距 3. **光标样式**:通过调整 `simulated-cursor` 的 `height` 和 `background` 定制光标 4. **边界情况**:已处理连续删除、非法字符过滤等场景 此方案已在微信小程序中验证可用,完美绕过原生 `letter-spacing` 限制,同时实现光标隐藏需求。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值