Now read it roughly on the official website to understand some of its concepts and grammatical rules.
Then let's create a uniapp project. The development software we need is Hbuilder and wechat developer tools
Double click Hbuilder to open and create a uni app project
This is the default project structure after creation
pages.json is a page routing configuration. Almost all pages need to be declared in this file
The page folder stores pages (. vue files, standard front end)
App.vue that has learned java can be regarded as the startup class in springboot
Other files and folders are left aside for the time being
Next, learn to run a uni app project (wechat applet)
After running successfully, the wechat developer tool will be automatically called out
The above figure is the wechat developer tool automatically called out
We need to review some of the things we saw on the official website and have an impression in our mind
uni-app Components are basic constituent units. Each component has a start tag, an end tag, content, attributes and attribute values
The root node of each. vue file must be < template >, and there must be and only one < View > node under < template >
Next, understand what the colon before the attribute name means. The identification attribute value is not a string, but js. Digest it and we'll use it later
When the attribute value is js, add a colon in front of the attribute. For example: disable="false"
In the uni app, each component has these attributes: id ref class style hidden data-* @*
data-* Custom properties
@*Component events with event handlers
Well, you can start to create a new page. It is no longer an html page. Create it under the pages file and experience the colon syntax and the basic format of the. vue file. After learning the basic use of vue, it will be very easy to get started.
So if you read this article and haven't used vue, you'd better use and learn vue first
Components in uni app are divided into basic components and extension components. Extension components need to be imported before they can be used
The basic components are: View Scroll view scrolls the view container swiper slider view container (Carousel) text rich-text progress button checkbox editor form input lable picker pop up list selector navigator audio camera image video map ad
The components supported by uni app are divided into vue components and applet custom components
Here's a little bit of knowledge, because I'm a back-end programmer. I still don't understand ES6 when I touch the front-end. In fact, according to my boss, ES6 can be regarded as js. As long as it's clear that ES6 adds a let command to declare variables, the usage is similar to var, which is only valid in the code block where the let command is located
How to judge whether you are using es5 or es6? Let's start with whether there is a let command
Next, we advanced because the boss asked to make such a page (in fact, there are more than one, many, but don't worry, listen to me)
First, the first page
How do you start? To get started quickly, you should learn to learn from (copy) and imitate (attack)
You must have a question about how this page comes out. We can open pages.json and configure it
{ "pages": [ //The first item in the pages array represents the application startup page. Refer to: https://uniapp.dcloud.io/collocation/pages { "path" : "pages/order/order", "style" : { "navigationBarTitleText": "", "enablePullDownRefresh": false } }, { "path": "pages/loginWX/loginWX", "style": { "navigationBarTitleText": "uni-app" } }, { "path" : "pages/test1/test1", "style" : { "navigationBarTitleText": "", "enablePullDownRefresh": false } }, { "path": "pages/index/index", "style": { "navigationBarTitleText": "uni-app" } } ,{ "path" : "pages/itooktheorder/itooktheorder", "style" : { "navigationBarTitleText": "", "enablePullDownRefresh": false } } ,{ "path" : "pages/detail/detail", "style" : { "navigationBarTitleText": "", "enablePullDownRefresh": false } } ], "globalStyle": { "navigationBarTextStyle": "black", "navigationBarTitleText": "uni-app", "navigationBarBackgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8" }, "tabBar": { "color": "#C0C4CC", "selectedColor": "#b25858", "borderStyle": "black", "backgroundColor": "#ffffff", "list": [{ "pagePath": "pages/order/order", "iconPath": "static/tab-home.png", "selectedIconPath": "static/tab-home-current.png", "text": "I'm the receptionist" }, { "pagePath": "pages/test1/test1", "iconPath": "static/tab-home.png", "selectedIconPath": "static/tab-home-current.png", "text": "I'm the sender" } ] } }
Don't be afraid of such a large code block. In fact, the key section is in the screenshot. Needless to say, the page is the test1.vue file under test1 under pages.
<template> <view class="content"> <view class="navbar"> <view v-for="(item, index) in navList" :key="index" class="nav-item" :class="{current: tabCurrentIndex === index}" @click="tabClick(index)" > {{item.text}} </view> </view> <swiper :current="tabCurrentIndex" class="swiper-box" duration="300" @change="changeTab"> <swiper-item class="tab-content" v-for="(tabItem,tabIndex) in navList" :key="tabIndex"> <scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData"> <empty v-if="tabItem.loaded === true && tabItem.orderList.length === 0"></empty> <view v-for="(item,index) in tabItem.orderList" :key="index" class="order-item"> <view class="i-top b-b"> <text class="time">{{item.toCreateData}}</text> <text class="state" :style="{color: item.stateTipColor}">{{item.stateTip}}</text> <text v-if="item.toStatus===0" class="del-btn yticon icon-iconfontshanchu1" @click="deleteOrder(index)"></text> </view> <view class="order_title"> {{item.toTitle}} </view> <view class="price-box"> {{orderstatusMap[item.toStatus]}} <text class="price">{{item.toPrice}}</text> </view> <view class="action-box b-t" v-if="item.state != 9"> <button class="action-btn" @click="cancelOrder(item)" >cancellation of order</button> <button class="action-btn recom" v-show="item.toStatus===80001||item.toStatus===80002">Immediate payment</button> </view> </view> </scroll-view> </swiper-item> </swiper> </view> </template> <script> import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'; import empty from "@/components/empty"; import Json from '@/Json'; export default { components: { uniLoadMore, empty }, data() { return { orderstatusMap:{ 0:"Waiting list", 1:"have in hand", 2:"Completed", 3:"Cancelled", 4:"Received order", 6:"To be paid", 80001:"",}, tabCurrentIndex: 0, navList: [{ state: 0, text: 'whole', loadingType: 'nomore', orderList: [] }, { state: 9, text: 'Waiting list', loadingType: 'nomore', orderList: [] }, { state: 8, text: 'To be paid', loadingType: 'nomore', orderList: [] }, { state: 1, text: 'have in hand', loadingType: 'more', orderList: [] }, { state: 2, text: 'Completed', loadingType: 'nomore', orderList: [] }, { state: 3, text: 'Cancelled', loadingType: 'nomore', orderList: [] } ], }; }, onLoad(options){ /** * Fix the problem that the app endpoint does not load data when clicking the button except all orders * Replace the code under onLoad */ this.tabCurrentIndex = +options.state; // #ifndef MP this.loadData() // #endif // #ifdef MP if(options.state == 0){ this.loadData() } // #endif }, mounted(){ console.log(this.orderstatusMap["5"]) }, methods: { //Get order list loadData(source){ //Here is to attach the order to the tab list let index = this.tabCurrentIndex; let navItem = this.navList[index]; let state = navItem.state; // if(source === 'tabChange' && navItem.loaded === true){ // //The tab switch only needs to load data for the first time // return; // } // if(navItem.loadingType === 'loading'){ // //Prevent repeated loading // return; // } navItem.loadingType = 'loading'; navItem.orderList = [], setTimeout(()=>{ let orderList //Get order list get all data uni.request({ url:"http://192.168.1.108:8088/getWorkOrderByF", data:{ token:uni.getStorageSync('userToken'), status:state },method:"GET", success: (res) => { console.log(1111) console.log(res); orderList = res.data.data console.log("Get list of") console.log(orderList) orderList.forEach(item=>{ navItem.orderList.push(item); }) //The new loaded field is used to indicate that the data has been loaded. If it is empty, a blank page can be displayed this.$set(navItem, 'loaded', true); //Judge whether there is any data. Change it to more and not to noMore navItem.loadingType = 'nomore'; } }) }, 600); }, //swiper switching changeTab(e){ this.tabCurrentIndex = e.target.current; this.loadData('tabChange'); }, //Click the top tab tabClick(index){ this.tabCurrentIndex = index; }, //Delete order deleteOrder(index){ uni.showLoading({ title: 'Please wait' }) setTimeout(()=>{ this.navList[this.tabCurrentIndex].orderList.splice(index, 1); uni.hideLoading(); }, 600) }, //cancellation of order cancelOrder(item){ uni.showModal({ title: 'Tips', content: 'Are you sure to cancel?', success: function (res) { if (res.confirm) { console.log('The user clicks OK'); console.log(3333) console.log(item.toOrderNumber) setTimeout(()=>{ uni.request({ url:"http://192.168.1.108:8088/wo/updateStatusOwner", data:{ token:uni.getStorageSync('userToken'), toOrderNumber:item.toOrderNumber }, method:"POST", header: { 'content-type': 'application/x-www-form-urlencoded;charset=utf-8' }, success: (res) => { console.log(1111) console.log(res); console.log("Get list of") // orderList.forEach(item=>{ // navItem.orderList.push(item); // }) // //The new loaded field is used to indicate that the data has been loaded. If it is empty, a blank page can be displayed // this.$set(navItem, 'loaded', true); // //Judge whether there is any data. Change it to more and not to noMore // navItem.loadingType = 'nomore'; uni.showToast({ title: 'Cancellation succeeded', duration: 2000 }); } }) }, 600) } else if (res.cancel) { console.log('The user clicks cancel'); } } }); }, //Order status text and color orderStateExp(state){ let stateTip = '', stateTipColor = '#fa436a'; switch(+state){ case 1: stateTip = 'Pending payment'; break; case 2: stateTip = 'To be shipped'; break; case 9: stateTip = 'Order closed'; stateTipColor = '#909399'; break; //More customization } return {stateTip, stateTipColor}; } }, } </script> <style lang="scss"> page, .content{ background: $page-color-base; height: 100%; } .swiper-box{ height: calc(100% - 40px); } .list-scroll-content{ height: 100%; } .navbar{ display: flex; height: 40px; padding: 0 5px; background: #fff; box-shadow: 0 1px 5px rgba(0,0,0,.06); position: relative; z-index: 10; .nav-item{ flex: 1; display: flex; justify-content: center; align-items: center; height: 100%; font-size: 15px; color: $font-color-dark; position: relative; &.current{ color: $base-color; &:after{ content: ''; position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); width: 44px; height: 0; border-bottom: 2px solid $base-color; } } } } .uni-swiper-item{ height: auto; } .order-item{ display: flex; flex-direction: column; padding-left: 30upx; background: #fff; margin-top: 16upx; .i-top{ display: flex; align-items: center; height: 80upx; padding-right:30upx; font-size: $font-base; color: $font-color-dark; position: relative; .time{ flex: 1; } .state{ color: $base-color; } .del-btn{ padding: 10upx 0 10upx 36upx; font-size: $font-lg; color: $font-color-light; position: relative; &:after{ content: ''; width: 0; height: 30upx; border-left: 1px solid $border-color-dark; position: absolute; left: 20upx; top: 50%; transform: translateY(-50%); } } } /* Multiple items */ .goods-box{ height: 160upx; padding: 20upx 0; white-space: nowrap; .goods-item{ width: 120upx; height: 120upx; display: inline-block; margin-right: 24upx; } .goods-img{ display: block; width: 100%; height: 100%; } } /* Single commodity */ .goods-box-single{ display: flex; padding: 20upx 0; .goods-img{ display: block; width: 120upx; height: 120upx; } .right{ flex: 1; display: flex; flex-direction: column; padding: 0 30upx 0 24upx; overflow: hidden; .title{ font-size: $font-base + 2upx; color: $font-color-dark; line-height: 1; } .attr-box{ font-size: $font-sm + 2upx; color: $font-color-light; padding: 10upx 12upx; } .price{ font-size: $font-base + 2upx; color: $font-color-dark; &:before{ content: '¥'; font-size: $font-sm; margin: 0 2upx 0 8upx; } } } } .price-box{ display: flex; justify-content: flex-end; align-items: baseline; padding: 20upx 30upx; font-size: $font-sm + 2upx; color: $font-color-light; .num{ margin: 0 8upx; color: $font-color-dark; } .price{ font-size: $font-lg; color: $font-color-dark; &:before{ content: '¥'; font-size: $font-sm; margin: 0 2upx 0 8upx; } } } .action-box{ display: flex; justify-content: flex-end; align-items: center; height: 100upx; position: relative; padding-right: 30upx; } .action-btn{ width: 160upx; height: 60upx; margin: 0; margin-left: 24upx; padding: 0; text-align: center; line-height: 60upx; font-size: $font-sm + 2upx; color: $font-color-dark; background: #fff; border-radius: 100px; &:after{ border-radius: 100px; } &.recom{ background: #fff9f9; color: $base-color; &:after{ border-color: #f7bcc8; } } } } /* load-more */ .uni-load-more { display: flex; flex-direction: row; height: 80upx; align-items: center; justify-content: center } .uni-load-more__text { font-size: 28upx; color: #999 } .uni-load-more__img { height: 24px; width: 24px; margin-right: 10px } .uni-load-more__img>view { position: absolute } .uni-load-more__img>view view { width: 6px; height: 2px; border-top-left-radius: 1px; border-bottom-left-radius: 1px; background: #999; position: absolute; opacity: .2; transform-origin: 50%; animation: load 1.56s ease infinite } .uni-load-more__img>view view:nth-child(1) { transform: rotate(90deg); top: 2px; left: 9px } .uni-load-more__img>view view:nth-child(2) { transform: rotate(180deg); top: 11px; right: 0 } .uni-load-more__img>view view:nth-child(3) { transform: rotate(270deg); bottom: 2px; left: 9px } .uni-load-more__img>view view:nth-child(4) { top: 11px; left: 0 } .load1, .load2, .load3 { height: 24px; width: 24px } .load2 { transform: rotate(30deg) } .load3 { transform: rotate(60deg) } .load1 view:nth-child(1) { animation-delay: 0s } .load2 view:nth-child(1) { animation-delay: .13s } .load3 view:nth-child(1) { animation-delay: .26s } .load1 view:nth-child(2) { animation-delay: .39s } .load2 view:nth-child(2) { animation-delay: .52s } .load3 view:nth-child(2) { animation-delay: .65s } .load1 view:nth-child(3) { animation-delay: .78s } .load2 view:nth-child(3) { animation-delay: .91s } .load3 view:nth-child(3) { animation-delay: 1.04s } .load1 view:nth-child(4) { animation-delay: 1.17s } .load2 view:nth-child(4) { animation-delay: 1.3s } .load3 view:nth-child(4) { animation-delay: 1.43s } @-webkit-keyframes load { 0% { opacity: 1 } 100% { opacity: .2 } } </style>
Experience the variable relations and method calls inside by yourself. There's no more nonsense. I'll see you next time.