小程序(三)

七、自定義組件2

1. mixin

//導出一個混入對象exportdefaultBehavior({//組件公共的數據data:{name:"我是一個自定義組件..."},//組件公共的方法methods:{sayHi(){console.log('hi...');}}})

2. tabBox組件

<viewclass="tab_box"><!-- 組件中的slot標簽,用于定義插槽。使用組件時,兩個組件標簽中間的內容都會放到插槽中 --><slot></slot><viewclass="flex"><viewclass="tab {{active===index?'active':''}}"wx:key="index"wx:for="{{data}}"bindtap="click"data-i="{{index}}">{{item.title}}</view></view><viewclass="list"><viewclass="item {{active===index?'show':''}}"wx:key="index"wx:for="{{data}}">{{item.content}}</view></view></view>

@import'../../app.wxss';.tab_box{margin:10rpx;padding:10rpx;border:1pxsolid#eeeeee}.tab{padding:10rpx20rpx;border:1pxsolid#eeeeee;margin:02px;}.tab.active{background:orangered;color:#ffffff;}.list{border:1pxsolid#eeeeee;margin-top:10rpx;padding:10rpx;}.item{display:none;}.item.show{display:block;}

//導入混入對象importmixinfrom'../mixin'Component({//behaviors,用于給當前組件混入公共的內容behaviors:[mixin],//組件的生命周期lifetimes:{attached:function(){// 在組件實例進入頁面節點樹時執行console.log('加載該組件...');console.log(this.data.version);console.log(this.data.name);this.sayHi()},detached:function(){// 在組件實例被從頁面節點樹移除時執行console.log('移除該組件...');},},

//監聽器:可以監聽組件中的數據是否發生變化observers:{//這里根據數據的名稱,定義同名的方法,用于監聽該數據是否發生變化//該方法的參數,返回的是數據的最新值//當前數據的值發生變化時,需要做些什么的時候,通常會使用監聽器。active(val){console.log(val);}},/**

? * 組件的屬性列表

? */properties:{data:{type:Array},active:{type:Number,value:0}},/**

? * 組件的初始數據

? */data:{version:'1.0'},/**

? * 組件的方法列表

? */methods:{click(e){let{i}=wx.$key(e)this.setData({active:i})//組件內部觸發事件this.triggerEvent("change",i)},}})

3. table組件

<viewclass="table"><viewclass="header"><viewclass="item"wx:key="index"wx:for="{{column}}">{{item.title}}</view></view><viewclass="content"wx:key="index"wx:for="{{data}}"><viewclass="item"wx:key="index1"wx:for="{{column}}"wx:for-index="index1"wx:for-item="item1">{{item[item1.key]}}</view></view></view>

.table{margin:10rpx0;}.header,.content{display:flex;}.header.item,.content.item{padding:2px0;flex:1;text-align:center;border:1pxsolid#eeeeee;}

/**

? * 組件的屬性列表

? */properties:{//表格的列信息column:{type:Array},//表格的數據信息data:{type:Array}},

4. 頁面中使用

"usingComponents":{"tabBox":"../../components/tabBox/tabBox","table":"../../components/table/table"},

{{country_active}}--{{goods_active}}<tabBoxdata-key="country_active"data="{{country_data}}"active="{{country_active}}"bind:change="$syncData"><viewstyle="text-align:center;color:red;padding:5rpx0">國家信息</view></tabBox><tabBoxdata-key="goods_active"data="{{goods_data}}"active="{{goods_active}}"bind:change="$syncData"><buttonstyle="width:200rpx">商品信息</button></tabBox><tablecolumn="{{table_column}}"data="{{table_data}}"></table><tablecolumn="{{column2}}"data="{{table2}}"></table>

/**

? ? * 頁面的初始數據

? ? */data:{//ajax請求,獲取一份數據country_data:[{title:"中國",content:"中國的乒乓球很厲害"},{title:"美國",content:"中國的籃球很厲害"},{title:"日本",content:"中國的動漫很厲害"}],country_active:0,goods_data:[{title:"薯條",content:"薯條屬于油炸食品,長期食用,可能會引發疾病"},{title:"餅干",content:"餅干很脆"},{title:"吐司",content:"吐司其實就是一種面包"}],

goods_active:1,//定義表格的列數據table_column:[{title:"學號",key:"no"},{title:"姓名",key:"name"},{title:"年齡",key:"age"},{title:"性別",key:"gender"}],//定義表單的數據table_data:[{no:"1001",name:"王俊凱",age:"22",gender:"男"},{no:"1002",name:"易烊千璽",age:"21",gender:"男",},{no:"1003",name:"王源",age:"22",gender:"男",}],column2:[{title:"城市",key:"city",},{title:"地址",key:"address"}],table2:[{city:"北京",address:"長安街108號"},{city:"上海",address:"南京路108號"}]}

八、ECharts

1. 引入ECharts

第一步:下載ecomfe/echarts-for-weixin 項目

第二步:拷貝 ec-canvas 目錄

第三步:

"usingComponents":{"ec-canvas":"../../components/ec-canvas/ec-canvas"}

2. 在頁面中使用ECharts

<viewclass="container"><ec-canvasid="mychart-dom-line"canvas-id="mychart-line"ec="{{ ec }}"></ec-canvas></view>

.container{width:95vw;height:400rpx;border:1pxsolidred;margin:2pxauto;}ec-canvas{width:100%;height:100%;}

//導入echarts對象import*asechartsfrom'../../components/ec-canvas/echarts';//初始化echarts的方法functioninitChart(canvas,width,height,devicePixelRatio){//初始化echarts對象constchart=echarts.init(canvas,null,{width,height,devicePixelRatio});//在畫布中設置echarts對象canvas.setChart(chart);//ajax請求,獲取一份數據letdata=[{year:'2015',cost:200,sale:400,},{year:'2016',cost:300,sale:500,},{year:'2017',cost:500,sale:400,},{year:'2018',cost:300,sale:400,},{year:'2019',cost:600,sale:700,},{year:'2020',cost:500,sale:400,}]//定義echarts的選項varoption={//標題/* title: {

? ? ? //標題文本

? ? ? text: '我的echarts圖表',

? ? ? //副標題

? ? ? subtext:'2021-2-2',

? ? ? //對齊方式

? ? ? left: 'center'

? ? }, *///顏色列表color:["#c04851","#2486b9","#10aec2","#5dbe8a"],// 圖例組件/*? legend: {

? ? ? data: ['A', 'B', 'C'],

? ? ? top: 50,

? ? ? left: 'center',

? ? ? backgroundColor: 'red',

? ? ? z: 100

? ? }, */// 設置邊距grid:{top:10,left:10,right:20,bottom:10,//是否包含LabelcontainLabel:true},//提示框tooltip:{show:true,trigger:'axis',//格式化提示框formatter:function(val){letstr="? ? "+val[0].name+" 年";val.forEach(({seriesName,value,seriesIndex})=>{str+=`\n{marker${seriesIndex}at0|} `+seriesName+":"+value+" 萬元";})returnstr}},//X軸xAxis:{type:'category',boundaryGap:false,//X軸的數據// data: ['2015','2016','2017','2018','2019','2020'],data:data.map(r=>r.year)// show: false},//y軸yAxis:{x:'center',type:'value',//分隔線splitLine:{//分隔線類型lineStyle:{type:'dashed'//虛線}}// show: false},//系列series:[{name:'成本',//類型:line,bar,pietype:'line',// 設置面積折線圖樣式// areaStyle:{},//潤滑曲線smooth:true,//系列數據// data: [18, 36, 65, 30, 78, 40, 33]data:data.map(r=>r.cost)},{name:'銷售',type:'line',smooth:true,// areaStyle:{},// data: [12, 50, 51, 35, 70, 30, 20]data:data.map(r=>r.sale)}]};//設置echarts的選項chart.setOption(option);//返回echarts對象returnchart;}Page({/**

? * 頁面的初始數據

? */data:{//定義頁面中渲染的數據ec:{onInit:initChart}},/**

? * 生命周期函數--監聽頁面加載

? */onLoad:function(options){},})

3. ECharts配合選擇器

<van-fieldvalue="{{ value }}"placeholder="請選擇城市"border="{{ true }}"bindtap="showPopup"readonly/><viewclass="container"><ec-canvasid="mychart-dom-line"canvas-id="mychart-line"ec="{{ ec }}"></ec-canvas></view><van-popupshow="{{ show }}"bind:close="onClose"position="bottom"><van-pickershow-toolbartitle="請選擇城市"columns="{{ columns }}"bind:cancel="onClose"bind:confirm="onConfirm"/></van-popup>

//導入echarts對象import*asechartsfrom'../../components/ec-canvas/echarts';//定義echarts對象letchart=nullPage({//選擇器確定按鈕點擊方法onConfirm(event){const{value}=event.detail;this.setData({value,show:false})//調用設置echarts選項的方法this.setChartOptions(value)},//顯示彈出層showPopup(){this.setData({show:true});},//關閉彈出層onClose(){this.setData({show:false});},/** * 頁面的初始數據

? */data:{//獲取的城市名稱value:'北京',//選擇器顯示的數據columns:['北京','上海','深圳','廣州','成都','重慶','南京','杭州'],//設置彈出層是否顯示show:false,//定義頁面中渲染的數據ec:null},/**

? * 生命周期函數--監聽頁面加載

? */onLoad:function(options){this.setData({//頁面加載時,給ec賦值ec:{//初始化echarts的方法onInit:(canvas,width,height,devicePixelRatio)=>{//初始化echarts對象chart=echarts.init(canvas,null,{width,height,devicePixelRatio});//在畫布中設置echarts對象canvas.setChart(chart);//調用設置echarts選項的方法this.setChartOptions('默認城市')//返回echarts對象returnchart;}}})},//設置echarts選項的方法setChartOptions(val){//根據val的值,發送ajax請求,獲取對應的數據letdata=[{year:'2015',cost:Math.random()*200,sale:Math.random()*400,},{year:'2016',cost:Math.random()*300,sale:Math.random()*500,},{year:'2017',cost:Math.random()*500,sale:Math.random()*400,},{year:'2018',cost:Math.random()*300,sale:Math.random()*400,},{year:'2019',cost:Math.random()*600,sale:Math.random()*700,},{year:'2020',cost:Math.random()*500,sale:Math.random()*400,}]//定義echarts的選項varoption={//顏色列表color:["#c04851","#2486b9","#10aec2","#5dbe8a"],// 設置邊距grid:{top:10,left:10,right:20,bottom:10,//是否包含LabelcontainLabel:true},//提示框tooltip:{show:true,trigger:'axis',//格式化提示框formatter:function(val){letstr="? ? "+val[0].name+" 年";val.forEach(({seriesName,value,seriesIndex})=>{str+=`\n{marker${seriesIndex}at0|} `+seriesName+":"+value+" 萬元";})returnstr}},//X軸xAxis:{type:'category',boundaryGap:false,//X軸的數據data:data.map(r=>r.year)},//y軸yAxis:{x:'center',type:'value',//分隔線splitLine:{//分隔線類型lineStyle:{type:'dashed'//虛線}}// show: false},//系列series:[{name:'成本',type:'line',//潤滑曲線smooth:true,//系列數據data:data.map(r=>r.cost)},{name:'銷售',type:'line',smooth:true,data:data.map(r=>r.sale)}]};//設置echarts的選項chart.setOption(option);}})

九、位置API

1. 頁面

<van-fieldtitle-width="80rpx"model:value="{{ address }}"centerclearablelabel="位置"placeholder="請輸入位置"border="{{ true }}"type="textarea"autosize><van-buttonwx:if="{{show}}"bindtap="choose"icon="location-o"slot="button"size="small"type="primary"></van-button><van-buttonwx:elsebindtap="choose1"icon="location-o"slot="button"size="small"type="primary"></van-button></van-field><van-fieldtitle-width="80rpx"model:value="{{ address2 }}"centerclearablelabel="位置"placeholder="請輸入位置"border="{{ true }}"type="textarea"autosize><van-buttonbindtap="choose2"icon="location-o"slot="button"size="small"type="primary"></van-button></van-field>

2. 后臺

//選擇方法choose(){//獲取當前位置/* wx.getLocation({

? ? ? success:({latitude,longitude})=>{

? ? ? ? console.log(latitude,longitude);

? ? ? }

? ? }) *///選擇位置wx.chooseLocation({//成功后的回調success:({address,name})=>{this.setData({address:address+' '+name})},//失敗后的回調fail:({errMsg})=>{if(errMsg==="chooseLocation:fail auth deny"){this.setData({show:false})}// wx.$msg('通過右上角設置權限',2000,'none')}})},//該方法,用于打開設置界面choose1(){//打開設置界面wx.openSetting({success:({authSetting})=>{//判斷是否勾選了獲取用戶位置權限if(authSetting['scope.userLocation']){this.setData({show:true})//直接調用選擇位置方法this.choose()}}})},choose2(){//獲取用戶的當前設置wx.getSetting({//返回權限設置success:({authSetting})=>{//判斷用戶,如果拒絕過獲取位置權限,打開設置界面if(authSetting['scope.userLocation']===false){//打開設置界面wx.openSetting({success:({authSetting})=>{//判斷用戶,如果勾選了獲取位置權限,打開選擇位置界面if(authSetting['scope.userLocation']===true){//打開選擇位置界面wx.chooseLocation({//成功后的回調success:({address,name})=>{this.setData({address2:address+' '+name})},})}}})}else{//authSetting['scope.userLocation'] 返回 undefined 或 true 時執行 else//打開選擇位置界面wx.chooseLocation({//成功后的回調success:({address,name})=>{this.setData({address2:address+' '+name})},})}}})},asyncchoose2(){letres=awaitwx.$chooseLocationWithSetting();this.setData({address2:res})},

3. location.js

//選擇位置的方法exportlet$chooseLocation=()=>{returnnewPromise((resolve,reject)=>{//打開選擇位置界面wx.chooseLocation({//成功后的回調success:({address,name})=>{resolve(address+' '+name)},})})}

//打開設置的方法exportlet$openSetting=()=>{returnnewPromise((resolve,reject)=>{//打開設置界面wx.openSetting({success:async({authSetting})=>{//判斷用戶,如果勾選了獲取位置權限,打開選擇位置界面if(authSetting['scope.userLocation']===true){resolve()}}})})}//通過設置選擇位置的方法exportlet$chooseLocationWithSetting=()=>{returnnewPromise((resolve,reject)=>{//獲取用戶的當前設置wx.getSetting({//返回權限設置success:async({authSetting})=>{//判斷用戶,如果拒絕過獲取位置權限,打開設置界面if(authSetting['scope.userLocation']===false){//先打開設置await$openSetting()//再獲取位置信息letres=await$chooseLocation()resolve(res)}else{//獲取位置信息letres=await$chooseLocation()resolve(res)}}})})}//將位置相關的方法,注冊給微信對象wx.$chooseLocation=$chooseLocationwx.$openSetting=$openSettingwx.$chooseLocationWithSetting=$chooseLocationWithSetting

十、購物車案例

1. 頁面

<viewclass="container"><viewclass="item flex j-s a-c"wx:for="{{goodslist}}"wx:key="index"><view><icondata-id="{{item.id}}"bindtap="check"class="ck iconfont {{item.ischecked?'iconfuxuankuang_xuanzhong1':'iconfuxuankuang_xuanzhong'}}"></icon></view><view><imageclass="img"src="{{item.img}}"/></view><viewclass="content"><viewclass="title">{{item.name}}</view><viewclass="price">¥{{item.price}}</view></view><counterdata-id="{{item.id}}"bind:change="change"count="{{item.count}}"></counter></view></view><viewclass="total flex j-s"><view><iconbindtap="checkAll"class="ck iconfont {{isCheckAll?'iconfuxuankuang_xuanzhong1':'iconfuxuankuang_xuanzhong'}}"></icon></view><viewclass="price">總計:¥{{total}}</view></view>

2. 樣式

@import'../../assets/iconfont/iconfont.wxss';page{background:#eeeeee;}.container{padding:010rpx;margin-bottom:100rpx;}.item{width:98%;margin:10rpxauto;background:#ffffff;padding:10rpx20rpx;box-sizing:border-box;}.ck{font-size:40rpx;color:#248067;}.img{width:200rpx;height:200rpx;margin:010rpx;}.content{flex:1;}.contentview{margin:10rpx;}.title{color:#248067;font-weight:bold;}.price{color:#f1939c}.total{width:100%;padding:20rpx40rpx;box-sizing:border-box;position:fixed;left:0;right:0;bottom:0;background:#ffffff;}

3. 后臺

//導入Mock對象importMockfrom'mockjs'//直接使用Mock對象隨機生成一份數據letmockData=Mock.mock({'goodslist|4-10':[{'id|+1':1001,name:'@ctitle(2,4)',img:'@image(100x100)',price:'@float(10,100,2,2)',count:'@natural(1,10)',ischecked:false}]})//單獨使用Mock隨機返回一個數據// console.log(Mock.Random.cname(2,4));//使用Mock對象攔截ajax請求,隨機返回一份數據Mock.mock('http://baidu.com','get',function(){returnMock.mock({'goodslist|4-10':[{'id|+1':1001,name:'@ctitle(2,4)',img:'@image(100x100)',price:'@natural(10,100)',count:'@natural(1,10)',ischecked:false}]})})Page({//計算總價的方法totalPrice(){lettotal=0//循環商品數組,累加消費總金額this.data.goodslist.filter(r=>r.ischecked).forEach(r=>{total+=r.price*r.count})//重新渲染頁面this.setData({total:total.toFixed(2)})},//數量加減后調用的方法change(e){//獲取對應商品的編號let{id}=wx.$key(e)//獲取最新的數量letcount=e.detail//將最新的數量更新給對應的商品this.data.goodslist.find(r=>r.id===id).count=count;//調用計算總價的方法this.totalPrice()},//全選復選框選擇方法checkAll(){//更新isCheckAll的狀態this.data.isCheckAll=!this.data.isCheckAll//循環商品數組,更新所有商品的狀態this.data.goodslist.forEach(r=>r.ischecked=this.data.isCheckAll)//重新渲染頁面this.setData({isCheckAll:this.data.isCheckAll,goodslist:this.data.goodslist})//調用計算總價的方法this.totalPrice()},//復選框選擇方法check(e){//獲取到idlet{id}=wx.$key(e)//根據id獲取對應的商品letgoods=this.data.goodslist.find(r=>r.id===id)//商品的選中狀態取反goods.ischecked=!goods.ischecked//每次判斷,所有商品是否全部選中this.data.isCheckAll=this.data.goodslist.every(r=>r.ischecked)//重新渲染頁面this.setData({goodslist:this.data.goodslist,isCheckAll:this.data.isCheckAll})//調用計算總價的方法this.totalPrice()},/**

? * 頁面的初始數據

? */data:{//是否全選isCheckAll:false,//總價total:(0).toFixed(2),//商品數組goodslist:[]/* goodslist:[{

? ? ? id:1001,

? ? ? name:'可比克',

? ? ? img:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=331839707,1109674904&fm=26&gp=0.jpg',

? ? ? price:9,

? ? ? count:5,

? ? ? ischecked:false

? ? },{

? ? ? id:1002,

? ? ? name:'樂事',

? ? ? img:'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=681102179,4036489030&fm=26&gp=0.jpg',

? ? ? price:8,

? ? ? count:3,

? ? ? ischecked:false

? ? },{

? ? ? id:1003,

? ? ? name:'奧利奧',

? ? ? img:'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4180506903,453032051&fm=26&gp=0.jpg',

? ? ? price:6,

? ? ? count:8,

? ? ? ischecked:false

? ? },{

? ? ? id:1004,

? ? ? name:'奶茶',

? ? ? img:'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4015669984,136058038&fm=26&gp=0.jpg',

? ? ? price:20,

? ? ? count:2,

? ? ? ischecked:false

? ? }] */},/**

? * 生命周期函數--監聽頁面加載

? */onLoad:function(options){this.setData({goodslist:mockData.goodslist})},})

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容