天天看點

uni學習筆記分享

目錄介紹

  • 01.遇到問題彙總
  • 02.關于布局設定
  • 03.基礎文法總結
  • 04.關于互動問題
  • 06.關于回傳資料
  • 07.關于網絡請求
  • 08.關于頁面重新整理
  • 09.關于注意問題
  • 10.待解決和思考

  • 在我的頁面,給item設定分割線時,定義view的class為line出現問題,但是把名稱修改成cell-line就可以。猜想可能是設定class名稱時,用line有沖突。
  • 從A頁面跳轉B頁面,關閉B傳回到A,如何回傳資料?看了往上方案,發現都有問題,最後用存取值替代。
  • 比如切換頁面布局視圖重新整理時,我的頁面登陸,未登陸,會員,使用v-if替代v-show方式重新整理頁面。
  • 網絡請求,在學員資訊頁面,使用post送出資料,需要設定header請求頭,否則會出現請求異常
  • 資料綁定,比如動态改變view的背景顔色,建議用class設定替代style設定
  • 在data中給字段指派,建議指派方式是''字元串,即使是整型。比如使用sex : "3"替代sex : 3
  • 當父,子等多層控件都有點選事件的時候,為了避免冒泡事件沖突,可以加上@tap.stop阻止冒泡事件
  • 圖檔引入,設定相對路徑有時不生效,這是為什麼?根據柯佳的規範文檔,建議url的引入規則使用絕對路徑
  • 在省市區地區控件中,即使給scroll-view的父view設定了高度,仍然要給scroll-view設定高度,不然會撐滿頁面

  • flex布局屬性介紹
    • 這個是邊寫布局,邊查詢
    display: flex; //将對象作為彈性伸縮盒顯示
    display: inline-flex; //将對象作為内聯塊級彈性伸縮盒顯示 父元素預設根據子元素寬高自适應
     
    //主軸方向
    flex-direction: row; //項目排列方向為水準方向,從左端開始
    flex-direction: column; //主軸為垂直方向,起點在右端
     
    //如何換行
    flex-wrap: nowrap; //項目不換行排列
    flex-wrap: wrap; //換行排列,第一行在上方
    flex-wrap: reverse; //換行排列,第一行在下方
     
    //主軸對齊方式
    justify-content: flex-start //左對齊
    justify-content: flex-end //右對齊
    justify-content: center //居中
    justify-content: space-between //兩端對齊,項目之間間隔相等
    justify-content: space-around //每個項目兩側間隔相等
     
    //項目在交叉軸上對齊方式
    align-items: center; //垂直居中
    align-items: flex-start; //交叉軸起點對齊
    align-items: flex-end; //交叉軸終點對齊
     
    //多跟軸線的對齊方式
    align-content: center; //垂直居中
    align-content: flex-start; //交叉軸起點對齊
    align-content: flex-end; //交叉軸終點對齊           
  • 常用的樣式
    position:sticky //粘性定位(基于使用者的滾動位置來定位,使用時需指定特定門檻值,如top:0)
    position:static //預設定位(沒有定位)
    position:fixed //固定定位(固定在視窗位置,視窗滾動也不會移動)
    position:relative top:10px //相對定位(相對其正常位置定位)
    position:absolute //絕對定位(相對于最近的已定位父元素,如果沒有已定位父元素,則相對于<html>)
    
    border-radius:30upx; //圓角半徑
    text-indent:20px //首行縮進
    letter-spacing:1px //字間距
    vertical-align: middle; //圖檔垂直居中
    z-index //重疊元素的堆疊順序
    
    //https://www.cnblogs.com/skura23/p/6505352.html
    :active,元素被點選時變色,但顔色在點選後消失
    :focus, 元素被點選後變色,且顔色在點選後不消失           
  • css中font不支援簡寫
    //錯誤
    font:bold 28rpx;
    
    //正确
    font-size:28rpx;
    font-weight:bold;           
  • scroll-view需要設定高度
    • 在省市區地區控件中,給父view設定高度500rpx,如果不給地區scroll-view設定高度,則地區内容會盛滿控件,這樣會導緻切換省市區頁面抖動。
    • 解決辦法,給子scroll-view同樣需要設定高度。

  • v-if和v-show
    • 比如在我的頁面,有登陸狀态,會員狀态,還有未登陸狀态,且布局可以動态隐藏和顯示,這個時候就用到v-if
    • v-if 和 v-show 的差別:前者是否會在dom中被移除,後者 display:none
    • 針對重新整理切換視圖,比如登陸/為登陸,建議使用v-if。
    • 使用場景如果需要非常頻繁地切換,則使用 v-show 較好;如果在運作時條件很少改變,則使用 v-if 較好。 更多内容閱讀這篇文章
  • 關于資料綁定
    • 比如使用者中心選擇性别,選擇切換顔色,需要注意書寫規範。代碼如下所示:
    //正确寫法
    <text class="cell-sex" :class="{'cell-sex-select': isSelcetMan}" @click="clickMan">男</text>
    <text class="cell-sex" :class="{'cell-sex-select': !isSelcetMan}" @click="clickWoman">女</text>
    
    
    //錯誤寫法
    <text :style="{color:isSelcetMan?'#F88B32':'#666666'}" class="cell-sex" @click="clickMan">男</text>
    <text :style="{color:!isSelcetMan?'#F88B32':'#666666'}" class="cell-sex" @click="clickWoman">女</text>           
  • 關于data中指派注意
    • 在學員資訊頁面,在data中設定sex為整型的時候,發現送出學員資訊報500異常,但是如果指派改成"3",就發現可以呢。難道是即使綁定的是數字,網頁與移動端擷取到的也隻會是字元串
    export default {
        data() {
            return {
                //性别,1男,2女
                sex : "3",
                // sex : 3,
            };
        },
    }
    
    //送出學員資訊,sex參數是整型
    async updateUserInfo(name,sex,birthday,grade,school_id,entrance_year) {
        const data = {
            sex : sex,
        };
        let header = {
            'content-type': 'application/x-www-form-urlencoded'
        };
        const result = await this.$zwwl.api.updateUserInfo(data,header);
        //網絡請求成功
        if(result.data!=null && result.code == 200){
        }
    },           
  • 關于@tap.stop.prevent
    • 比如選擇城市清單控件中,省,市,區三級tab。點選省清單item,請求該省的市資料,然後切換到該市的tab頁面。同時,選擇完成後,點選控件關閉城市清單彈窗
    • 什麼叫做事件冒泡:點選外面的時候,不會觸發裡面元素的事件;但是點選裡面元素的時候,就會觸發外面元素的事件,這就是事件冒泡!! 具體可以看這篇部落格
    • 阻止事件冒泡時要在外層加一層标簽,直接在需要使用的方法上加.stop無效
    <view v-if="tabTitle.length > 0 && show" :class="[{'tabBlock__animation' :show},'tabBlock']" @tap.stop.prevent="onClickModule">
        <!-- 省市區,以及确定按鈕 -->
        <scroll-view scroll-x="true" scroll-with-animation :scroll-left="tabsScrollLeft" @scroll="scroll">
            <view :class="'tab'" id="tab_list" >
                <view v-for="(item, index) in tabTitle" :key="index" :class="['tab__item',{'tab__item--active':currentIndex === index}]" :style="{color: (currentIndex === index ? `${itemColor}`: '')}" id="tab_item" @tap.stop.prevent="onSelect(index)">
                    <view class="tab__item-title">
                         {{item.title}}
                    </view>
                </view>
                <view class="confirm" @tap.stop.prevent="onConfirm">
                    确定
                </view>
                <view class="tab__line" :style="{ background: lineColor, width: lineStyle.width, transform: lineStyle.transform,transitionDuration: lineStyle.transitionDuration}"></view>
            </view>
        </scroll-view>
        
        <!-- 地區資料 -->
        <scroll-view class="content-view" scroll-y="true">
            <view class="item-view" v-for="(item,ind) in areaListData" :key="ind" @tap.stop.prevent="onAreaItemClick(ind)">
                <view class="desc">{{item.name}}</view>
                <view class="cell-line"></view>
            </view>
        </scroll-view>
    </view>           
  • this作用域問題
    • 第一種解決方案
      • 解決辦法就是在閉包之外先把this指派給另一個變量
      //可以發現這樣操作就可以解決作用域問題
      changeTitle3(){
          //指派
          var me = this;
          uni.setStorage({
              key: 'storage_key',
              data: 'hello',
              success: function () {
                  me.title = "改變标題3";
                  console.log('changeTitle2------success');
              }
          });
      },           
    • 第二種解決方案
      • 使用箭頭函數也可以解決該問題,思考一下這是為什麼?但是不建議使用這種……
      changeTitle4(){
          uni.setStorage({
              key: 'storage_key',
              data: 'hello',
              success:() => {
                  this.title = "改變标題4";
                  console.log('changeTitle2------success');
              }
          });
      },           

  • 在省市區城市清單中
    • 出現問題
      • 當切換不同省,擷取城市數組的順序發生變更後,點選事件接收到的 index 索引并不會随着更新,還是數組順序發生變更前的索引值。
    • 解決方案
      • 當頁面需要同時存在兩個或兩個以上的v-for的時候,key的值就需要根據你最終應用的環境來正确設定。如果是适應多端平台的話,以下方法可以作為參考:
      • 1、把一些需要v-for的部分做成元件,這樣頁面上就不存在多個 v-for
      • 2、使用周遊的元素的某個字段值作為key,但是這個字段值必須是唯一的不重複的,如下:list.id等等
    • 為何需要key
      • 可以參考: 示範v-for為什麼要加key
      • 使用 v-for 循環整數時和其他平台存在差異,如 v-for="(item, index) in array" 中,在H5平台 item 從 1 開始,其他平台 item 從 0 開始,可使用第二個參數 index 來保持一緻。
      <!-- 省市區,以及确定按鈕 -->
      <scroll-view scroll-x="true" scroll-with-animation :scroll-left="tabsScrollLeft" @scroll="scroll">
          <view :class="'tab'" id="tab_list" >
              <view v-for="(item, index) in tabTitle" :key="index" :class="['tab__item',{'tab__item--active':currentIndex === index}]" :style="{color: (currentIndex === index ? `${itemColor}`: '')}" id="tab_item" @tap.stop.prevent="onSelect(index)">
                  <view class="item-title">{{item.title}}</view>
              </view>
          </view>
      </scroll-view>
      
      <!-- 地區資料 -->
      <scroll-view class="content-view" scroll-y="true">
          <view class="item-view" v-for="(item,ind) in areaListData" :key="ind" @tap.stop.prevent="onAreaItemClick(ind)">
              <view class="desc">{{item.name}}</view>
              <view class="cell-line"></view>
          </view>
      </scroll-view>           

  • 如何關閉目前頁面,傳回到上一頁面
    • 頁面傳回 調用uni.navigateBack、使用者按左上角傳回按鈕、安卓使用者點選實體back按鍵
  • 第一種回傳資料
    • 采用uni.$emit()與uni.$on()的方式。$emit是觸發事件,$on是接受事件,通過eventName比對。這種方式有點類似Android中eventBus事件通知
      • uni.$emit(eventName,OBJECT)
      uni.$emit('update',{msg:'頁面更新'})           
      • uni.$on(eventName,callback)
      uni.$on('update',function(data){ 
          console.log('監聽到事件來自 update ,攜帶參數 msg 為:'  + data.msg);  
      })           
    • 存在問題:需要接觸監聽,監聽事件會執行多次
  • 第二種回傳資料
    • 在b頁面操作
    var pages = getCurrentPages();
    //上一個頁面
    var prevPage = pages[pages.length - 2]; 
    prevPage.setData({
        sx1:"參數1",
        sx2:"參數2",
    })
    uni.navigateBack({
        delta:1
    });           
    • 在a頁面操作
    onShow(object){
        if(!!object){
            console.log('vue onShow' + object)
        }
    },           
    • 報錯問題:"message": "prevPage.setData is not a function"
  • 第三種回傳資料
    var pages = getCurrentPages();
    //上一個頁面
    var prevPage = pages[pages.length - 2]; 
    var object={
        sx1:"參數1",
        sx2:"參數2",
    }
    //重點$vm
    prevPage.$vm.otherFun(object);
    uni.navigateBack();           
    //這個方法寫在methons中
    otherFun(object){
        if(!!object){
            console.log(object)
        }
    }           
    • 報錯問題:"message": "prevPage.$vm.otherFun is not a function",
  • 目前如何回傳資料
    • 還沒有找到好方案,請教同僚說,先儲存資料,關閉頁面,然後在onShow方法擷取

  • 網絡請求指POST的坑
    • 在學員中心,使用者填完資料後,需要送出資料請求接口。使用到post請求,注意,一定需要添加請求header,否則無法上傳資料
    • 為何會出現這個錯誤
      • 以 POST 方式進行網絡請求時,如果不添加header頭是無法進行正常的網絡請求的,此時預設的請求方式content-type類型是application/json
    • let header = {
          'content-type': 'application/x-www-form-urlencoded'
      };
      const result = await this.$zwwl.api.updateUserInfo(data,header);           
    • 參考文章: uni-app 網絡請求指POST的坑
  • 如果不添加header頭
    • 可以直接檢視不添加header頭,預設的content-type是:application/json;charset=UTF-8
    • 添加header頭,設定為'content-type': 'application/x-www-form-urlencoded'
  • 這兩種差別
    • application/x-www-form-urlencoded表示表單,上傳參數的格式為key=value&key=value
    • application/json代表參數以json字元串傳遞給背景

  • 比如,在登陸頁面,有未登陸,登陸,會員等多種狀态view,使用者執行完某個動作,改變了某些狀态,需要重新重新整理頁面,以此來重新渲染頁面。
  • 第一種是用原始方法:location.reload();不過是強制重新整理頁面,會出現短暫的閃爍,使用者體驗效果不好。
  • 第二種是用vue自帶的路由跳轉:this.$router.go(0);和第一種一樣,強制重新整理。
  • 第三種使用到v-if,具體操作如下所示,隻需要改變isShow的屬性值即可重新整理
    <template>
    <view>
    <!-- v-if v-show 的差別:前者是否會在dom中被移除,後者 display:none -->
    <view v-show="isShow">
        now you see me haha
    </view>
    </view>
    </template>
    
    <script>
    export default {
    data() {
        return {
            isShow: true,
        };
    }
    }
    </script>
    
    <style>
    
    </style>           

  • 元件内引入圖檔要使用絕對路徑。使用這種/static/...是最好的
  • 首頁面的生命周期用onLoad代替created,onReady代替mounted。元件内使用原來的created與mounted
  • 不要引入體積大的js,如果是超過500k,工具編譯的時候會給提示
  • 比如,在地區選擇控件中,省,市,區是三個接口。避免滾動監聽請求接口資料,當監聽 scroll-view 的滾動事件時,視圖層會頻繁的向邏輯層發送資料

  • 關于頁面關閉,傳回上一頁面,需要傳遞資料,具體該如何操作才有效?
  • 長清單中如果每個item有一個加入購物車按鈕,點選後數字+1,如何才能不重新整理整個list?

繼續閱讀