Vue webAPP首頁開發(二)

来源:https://www.cnblogs.com/chenyingying0/archive/2020/04/03/12623653.html
-Advertisement-
Play Games

接上篇 https://www.cnblogs.com/chenyingying0/p/12612393.html Loading組件 在api--home.js中,添加代碼,使ajax獲取到輪播圖數據後,延遲一秒再顯示 import axios from 'axios'; import {SUCC ...


接上篇 https://www.cnblogs.com/chenyingying0/p/12612393.html

 

Loading組件

在api--home.js中,添加代碼,使ajax獲取到輪播圖數據後,延遲一秒再顯示

import axios from 'axios';
import {SUCC_CODE,TIMEOUT} from './config';

//獲取幻燈片數據 ajax
export const getHomeSliders=()=>{
    // es6使用promise代替回調
    // axios返回的就是一個promise
    // return axios.get('http://www.imooc.com/api/home/slider').then(res=>{
    //     console.log(res);
    //     if(res.data.code===SUCC_CODE){
    //         return res.data.slider;
    //     }

    //     throw new Error('沒有成功獲取到數據');
    // }).catch(err=>{
    //     console.log(err);
    //     //錯誤處理
    //     return [{       
    //         linkUrl:'www.baidu.com',
    //         picUrl:require('assets/img/404.png')
    //     }]
    // });

    //演示超時錯誤
    return axios.get('http://www.imooc.com/api/home/slider',{
        timeout:TIMEOUT
    }).then(res=>{
        console.log(res);
        if(res.data.code===SUCC_CODE){
            return res.data.slider;
        }

        throw new Error('沒有成功獲取到數據');
    }).catch(err=>{
        console.log(err);
        //錯誤處理
        return [{       
            linkUrl:'www.baidu.com',
            picUrl:require('assets/img/404.png')
        }]
    }).then(data=>{//獲取輪播圖數據後,延遲一秒再顯示
        return new Promise(resolve=>{
            setTimeout(()=>{
                resolve(data);
            },1000);
        })
    });
}

 

在base下創建loading文件夾,裡面創建index.vue

<template>
    <div class="mine-loading" :class="{'me-loading-inline':inline}">
        <span class="mine-loading-indicator" v-if="indicator==='on'" >
            <img src="./loading.gif" alt="">
        </span>
        <span class="mine-loading-text" v-if="text">{{text}}</span>
    </div>
</template>

<script>
export default {
   name:"MeLoading",
   props:{//過濾器
       indicator:{
           type:String,
           default:'on',
           validator(value){
               return ['on','off'].indexOf(value)>-1;
           }
       },
       text:{
           type:String,
           default:'載入中...'
       },
        inline:{
            type:Boolean,
            default:false
        }
   }
}
</script>

<style lang="scss" scoped>
    @import '~assets/scss/mixins';

    .mine-loading{
        width:100%;
        height:100%;
        @include flex-center(column);

        //圖文左右排列時
        &.me-loading-inline{
            flex-direction: row;
           
            .mine-loading-indicator ~ .mine-loading-text{
                margin-top:0px;
                margin-left:7px;
            }
        }

        .mine-loading-indicator{

        }

        // 存在.mine-loading-indicator和.mine-loading-text時
        .mine-loading-indicator ~ .mine-loading-text{
            margin-top:7px;
        }
    }
</style>

 

在base-loading文件夾下放入loadging.gif

 

在home--slider.vue中引入loading組件

<template>
    <div class="slider-wrapper">
        <!-- sliders沒載入時顯示loading -->
        <Meloading v-if="!sliders.length"></Meloading>
        <!-- 分開傳才能分開校驗,因此不直接傳入對象 -->
        <MeSlider 
            :direction="direction"
            :loop="loop"
            :interval="interval"
            :pagination="pagination"
            v-else
        >
            <swiper-slide v-for="(item,index) in sliders" :key="index">
                <a :href="item.linkUrl" class="slider-link">
                    <img :src="item.picUrl" class="slider-img">
                </a>
            </swiper-slide>
        </MeSlider>
    </div>
</template>

<script>
import MeSlider from 'base/slider';
import { SwiperSlide } from 'vue-awesome-swiper';
import { sliderOptions } from './config';
import { getHomeSliders } from 'api/home';
import Meloading from 'base/loading';

export default {
   name:"HomeSlider",
   components:{
       MeSlider,
       SwiperSlide,
       Meloading
   },
    data(){
        return{
            direction:sliderOptions.direction,
            loop:sliderOptions.loop,
            interval:sliderOptions.interval,
            pagination:sliderOptions.pagination,
            sliders:[],//這是從伺服器讀取
            //這是靜態寫入
            // sliders:[
            //     {
            //        linkUrl:'www.baidu.com',
            //        picUrl:require('./1.jpg') //js中本地圖片引入必須加require
            //     },
            //     {
            //        linkUrl:'www.baidu.com',
            //        picUrl:require('./2.jpg') 
            //     },
            //     {
            //        linkUrl:'www.baidu.com',
            //        picUrl:require('./3.jpg') 
            //     },
            //     {
            //        linkUrl:'www.baidu.com',
            //        picUrl:require('./4.jpg') 
            //     }
            // ]
        }
    },
    created(){
        //一般在created里獲取遠程數據
        this.getSliders();
        
        
    },
    methods:{
        getSliders(){
            getHomeSliders().then(data=>{
                console.log(data);
                this.sliders=data;
            });
        }
    }
}
</script>

<style lang="scss" scoped>
    // 引入前面需要加波浪線,否則會報錯
    @import "~assets/scss/mixins";
    .slider-wrapper{
        width:100%;
        height:183px;
    }
    .slider-link{
        display:block;
    }
    .slider-link,
    .slider-img{
        width:100%;
        height:100%;
    }
    
</style>

 

目錄如下:

 

 

效果圖

 

滾動條組件

在base目錄下創建scroll目錄,新建index.vue

<template>
    <swiper :options="swiperOption">
        <swiper-slide>
            <slot></slot>
        </swiper-slide>
        <div class="swiper-scrollbar" v-if="scrollbar" slot="scrollbar"></div>
    </swiper>
</template>

<script>
// 組件首字母大寫,否則會報錯
import {Swiper,SwiperSlide} from 'vue-awesome-swiper';

export default {
    name:"MeScroll",
    components:{
        Swiper,
        SwiperSlide
    },
    props:{//過濾器
       scrollbar:{
           type:Boolean,
           default:true
       }
    },
    data(){
        return {
            swiperOption:{
                direction:'vertical',//垂直方向
                slidesPerView:'auto',//一次顯示幾張
                freeMode:true,//任意滑動多少距離
                setWrapperSize:true,//根據內容設置容器尺寸
                scrollbar:{
                    el:this.scrollbar?'.swiper-scrollbar':null,
                    hide:true //滾動條自動隱藏
                }

            }
        }
    }
}
</script>

<style lang="scss" scoped>
    @import '~assets/scss/mixins';

    .swiper-container{
        width:100%;
        height:100%;
        overflow:hidden;

        & .swiper-slide{
            height:auto;
        }  
    }
     
</style>

 

在home--index.vue中引入scroll組件

<template>
    <div class="home">
        <header class="g-header-container">
            <!-- 沒有內容自閉合即可-->
            <home-header/>
        </header> 
        <me-scroll>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
            <home-slider></home-slider>
        </me-scroll>
        <div class="g-backup-container"></div>
        <!-- 當前頁面存在二級頁面時需要使用router-view -->
        <router-view></router-view>
    </div>
</template>

<script>
import MeScroll from 'base/scroll';
import HomeHeader from './header';
import HomeSlider from './slider';


export default {
    name:"Home",
    components:{
        HomeHeader,
        HomeSlider,
        MeScroll
    }
}
</script>

<style lang="scss" scoped>
    // 引入前面需要加波浪線,否則會報錯
    @import "~assets/scss/mixins";
    .home{
        overflow:hidden;
        width:100%;
        height:100%;
        background:$bgc-theme;
    }

</style>

 

這裡添加這麼多組輪播圖是為了增高高度展示下輪播圖效果

 

導航面板

在home目錄中新建nav.vue

<template>
    <nav class="nav">
        <ul class="nav-list">
            <li class="nav-item" v-for="(item,index) in navs" :key="index">
                <a :href="item.linkUrl" class="nav-link">
                    <img :src="item.picUrl" alt="" class="nav-pic">
                    <span>{{item.text}}</span>
                </a>
            </li>
        </ul>
    </nav>
</template>

<script>
import {navItems} from './config.js';

export default {
    name:"HomeNav",
    components:{
        
    },
    props:{//過濾器
       
    },
    data(){
        return {
           
        }
    },
    created(){
        //不建議把這個數據放在data里,因為data里的數據都會添加getter和setter,而這裡的數據並不需要實時響應變化,放在data里對資源是一種浪費
        this.navs=navItems;
    }
}
</script>

<style lang="scss" scoped>
    @import '~assets/scss/mixins';

    .nav{
        width:100%;
        margin-top:15px;
    }
    .nav-list{
        display:flex;
        flex-wrap:wrap;
    }
    .nav-item{
        width:20%;
    }
    .nav-link{
        @include flex-center(column);
        margin-bottom:15px;
    }
    .nav-pic{
        width:60%;
        margin-bottom:7px;
    }
     
</style>

 

在index.vue中引入nav組件

<template>
    <div class="home">
        <header class="g-header-container">
            <!-- 沒有內容自閉合即可-->
            <home-header/>
        </header> 
        <me-scroll>
            <home-slider />
            <home-nav></home-nav>
        </me-scroll>
        <div class="g-backup-container"></div>
        <!-- 當前頁面存在二級頁面時需要使用router-view -->
        <router-view></router-view>
    </div>
</template>

<script>
import MeScroll from 'base/scroll';
import HomeHeader from './header';
import HomeSlider from './slider';
import HomeNav from './nav';


export default {
    name:"Home",
    components:{
        HomeHeader,
        HomeSlider,
        MeScroll,
        HomeNav
    }
}
</script>

<style lang="scss" scoped>
    // 引入前面需要加波浪線,否則會報錯
    @import "~assets/scss/mixins";
    .home{
        overflow:hidden;
        width:100%;
        height:100%;
        background:$bgc-theme;
    }

</style>

 

數據在config.js中

//暴露一個常量
export const sliderOptions={
    direction:"horizontal",
    loop:"loop",
    interval:1000,
    pagination:"pagination"
}

export const navItems=[
    {
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-1.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-2.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-3.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-4.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-5.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-6.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-7.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-8.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-9.png'),
        text:'團購'
    },{
        linkUrl:'www.baidu.com',
        picUrl:require('./img/nav-item-10.png'),
        text:'團購'
    }
];

 

效果圖

 

 

熱賣推薦--jsonp封裝

準備一個淘寶介面 

https://ju.taobao.com/json/tg/ajaxGetItemsV2.json  

安裝jsonp的庫

cnpm install --save jsonp

 

 

封裝jsonp方法

在assets--js下創建jsonp.js

import jsonp from 'jsonp';

/*data格式案例
{
    id:1,
    name:'cyy'
}
*/
const parseParam=param=>{
    /*將data格式轉換為
    [
        [id,1],
        [name,cyy]
    ]
    */
    let arr=[];
    for(const key in param){
        arr.push([key,param[key]]);
    }
    /*先將data格式轉換為
    [
        id=1,
        name=cyy
    ]
    */
   /*再將data格式轉換為
    id=1&name=cyy
    */
    return arr.map(value=>value.join("=")).join('&');
}

export default (url,data,options)=>{
    // 如果存在?,則url後面加&;如果不存在則加?
    url+=((url.indexOf('?')<0) ? '?' : '&' ) + parseParam(data);

    return new Promise((resolve,reject)=>{
        
        //jsonp用法,三個參數:jsonp(url,options,callback)
        jsonp(url,options,(err,data)=>{
            if(err){
                reject(err);
            }else{
                resolve(data);
            }
        })
    })
}

 

在api / home.js中調用jsonp方法獲取數據

import axios from 'axios';
import {SUCC_CODE,TIMEOUT,HOME_RECOMMEND_PAGE_SIZE,JSONP_OPTIONS} from './config';
import jsonp from 'assets/js/jsonp';

//獲取幻燈片數據 ajax
export const getHomeSliders=()=>{
    // es6使用promise代替回調
    // axios返回的就是一個promise
    // return axios.get('http://www.imooc.com/api/home/slider').then(res=>{
    //     console.log(res);
    //     if(res.data.code===SUCC_CODE){
    //         return res.data.slider;
    //     }

    //     throw new Error('沒有成功獲取到數據');
    // }).catch(err=>{
    //     console.log(err);
    //     //錯誤處理
    //     return [{       
    //         linkUrl:'www.baidu.com',
    //         picUrl:require('assets/img/404.png')
    //     }]
    // });

    //演示超時錯誤
    return axios.get('http://www.imooc.com/api/home/slider',{
        timeout:TIMEOUT
    }).then(res=>{
        //console.log(res);
        if(res.data.code===SUCC_CODE){
            return res.data.slider;
        }

        throw new Error('沒有成功獲取到數據');
    }).catch(err=>{
        console.log(err);
        //錯誤處理
        return [{       
            linkUrl:'www.baidu.com',
            picUrl:require('assets/img/404.png')
        }]
    }).then(data=>{//獲取輪播圖數據後,延遲一秒再顯示
        return new Promise(resolve=>{
            setTimeout(()=>{
                resolve(data);
            },1000);
        })
    });
}

//獲取熱門推薦數據
export const getHomeRecommend=(page=1,psize=HOME_RECOMMEND_PAGE_SIZE)=>{
    const url='https://ju.taobao.com/json/tg/ajaxGetItemsV2.json';
    const params={
        page,
        psize,
        type:0,
        frontCatId:''//type和frontCatId是根據給定的淘寶介面來添加的
    }

    //調用jsonp獲取數據
    return jsonp(url,params,JSONP_OPTIONS).then(res=>{
        if(res.code==='200'){
            return res;
        }

        throw new Error('沒有成功獲取到數據');
    }).catch(err=>{
        if(err){
            console.log(err);
        }
        
    }).then(res=>{
        //延遲一秒返回數據
        return new Promise(resolve=>{
            setTimeout(()=>{
                resolve(res);
            },1000);
        })
    })
    
}

 

api / config.js中添加常量

//獲取輪播圖
export const SUCC_CODE=0;
export const TIMEOUT=10000;

//獲取熱門推薦
export const HOME_RECOMMEND_PAGE_SIZE=20;
export const JSONP_OPTIONS={
    param:'callback',
    timeout:TIMEOUT
};

 

在pages/home/recommend.vue中添加代碼

<template>
    <div class="recommend">
        <h3 class="recommend-title">熱賣推薦</h3>
        <div class="loading-container" v-if="!recommends.length">
            <!-- 完整寫法是 inline:inline ,不過布爾值類型可以直接寫 inline -->
            <me-loading inline />
        </div>
        <ul class="recommend-list">
            <li class="recommend-item" v-for="(item,index) in recommends" :key="index">
                <router-link class="recommend-link" :to="{name:'home-product',params:{id:item.baseinfo.itemId}}">
                    <p class="recommend-pic"><img class="recommend-img" :src="item.baseinfo.picUrl" alt=""></p>
                    <p class="recommend-name">{{item.name.shortName}}</p>
                    <p class="recommend-oriPrice"><del>¥{{item.price.origPrice}}</del></p>
                    <p class="recommend-info">
                        <span class="recommend-price">¥<strong class="recommend-price-num">{{item.price.actPrice}}</strong></span>
                        <span class="recommend-count">{{item.remind.soldCount}}件已售</span>
                    </p>
                </router-link>
            </li>
        </ul>
    </div>
</template>

<script>
import {getHomeRecommend} from 'api/home';
import MeLoading from 'base/loading';

export default {
    name:"HomeRecommend",
    data(){
        return {
           recommends:[],
           curPage:1,
           totalPage:1
        }
    },
    components:{
        MeLoading
    },
    created(){
        this.getRecommends();        
    },
    methods:{
        getRecommends(){
            
            if(this.curPage>this.totalPage) return Promise.reject(new Error('沒有更多了'));

            getHomeRecommend(this.curPage).then(data=>{
                return new Promise(resolve=>{
              
                    if(data){
                        console.log(data);
                        
                        this.curPage++;
                        this.totalPage=data.totalPage;

                        // concat合併數組內容,每次獲取的數據都追加進來
                        this.recommends=this.recommends.concat(data.itemList);

                        resolve();
                    }
                })
            });
        }
    }
}
</script>

<style lang="scss" scoped>
    @import '~assets/scss/mixins';

    .recommend{
        position:relative;
        width:100%;
        padding:10px 0;
        font-size:$font-size-l;
        text-align:center;

        &:before,
        &:after{
            content:"";
            display:block;
            position:absolute;
            top:50%;
            width:40%;
            height:1px;
            background:#ddd;
        }

        &:before{
            left:0;        
        }

        &:after{
            right:0;
        }
    }
    .recommend-list{
        @include flex-between();
        flex-wrap:wrap;
    }
    .recommend-title{
        margin-bottom:8px;
    }
    .recommend-item{
        width:49%;
        background:#fff;
        box-shadow:0 1px 1px 0 rgba(0,0,0,0.12);
        margin-bottom:8px;
    }
    .recommend-link{
        display:block;
    }
    .recommend-pic{
        position:relative;
        width:100%;
        padding-top:100%;// 可以實現高度與寬度一致
        margin-bottom:5px;
    }
    .recommend-img{
        width:100%;
        position:absolute;
        top:0;
        left:0;
        height:100%;
    }
    .recommend-name{
        height:40px;
        padding:0 5px;
        margin-bottom:8px;
        line-height:1.5;
        @include multiline-ellipsis();
        text-align:left;

    }
    .recommend-oriPrice{
        padding:0 5px;
        margin-bottom:8px;
        color:#ccc;

        del{

        }
    }
    .recommend-info{
        @include flex-between();
        padding:0 5px;
        margin-bottom:8px;
    }
    .recommend-price{
        color:#e61414;

        &-num{
            font-size:20px;
        }
    }
    .recommend-count{
        color:#999;
    }
    .loading-container{
        padding-top:150px;
    }
     
</style>

 

src/pages/product.vue

<template>
    <div class="product">
        product
    </div>
</template>

<script>
export default {
   name:"Product"
}
</script>

<style lang="scss" scoped>
    @import '~assets/scss/_mixins';

    .product{
        overflow:hidden;
        position:absolute;
        top:0;
        left:0;
        width:100%;
        height:100%;
        background:#fff;
        z-index:$product-z-index;
    }
</style>

 

效果圖

 

 

 

更新滾動條

由於熱門推薦是非同步載入的,熱門推薦還沒載入完時,滾動條已經載入完畢,因此滾動條無法獲取到正確的熱門推薦區域的高度,導致滾動條效果失效

因此當熱門推薦載入完畢時,需要再次更新滾動條

 

1、recommend.vue中,熱門推薦載入完成後,觸發loaded消息並傳遞recommends數據

 

 2、接收觸發的消息loaded,觸發getRecommends函數

 

 3、在getRecommends函數中更新recommends數據

 

 4、讓滾動條接收到recommends數據

 

 5、滾動條檢測到數據變化,開始更新滾動條

 

 6、這裡用到了swiper實例,需要在swiper元素上獲取到

 

 7、滾動條效果回來啦!

 

圖片的懶載入

1、安裝lazyload插件  cnpm install --save vue-lazyload

 

2、在main.js中引入組件

 

 3、在recommend.vue中將:src改為v-lazy

 

 完美實現懶載入!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 環境 MySQL5.6 表結構及數據 sql DROP TABLE IF EXISTS ; CREATE TABLE ( int(11) NOT NULL AUTO_INCREMENT, varchar(20) NOT NULL, varchar(20) NOT NULL, double(10, 3 ...
  • SQL語句還是多去用才能掌握,再多理論,白搭 SQL概述 SQL的產生與發展 SQL的特點 SQL功能十分強大,針對數據的操作,核心功能只用9個動詞就可以完成。而且其語句有點類似英語口語一看基本就能明白它要表達的意思。 SQL語言對資料庫三級模式的支持 SQL語言作為大多數資料庫使用的共同數據存取語 ...
  • 導讀 在開發中一定會用到統計一張表的行數,比如一個交易系統,老闆會讓你每天生成一個報表,這些統計信息少不了 sql 中的count函數。 但是隨著記錄越來越多,查詢的速度會越來越慢,為什麼會這樣呢?Mysql內部到底是怎麼處理的? 今天這篇文章將從Mysql內部對於count函數是怎樣處理的? 本文 ...
  • 事情的起因呢,是因為朋友問我的。幾經周折,自己粗心大意了很多細節,不廢話,直接開始 一、redis的安裝我就略過了, 二、修改redis的配置文件 redis.conf 1. bind 設置為 0.0.0.0 2. protected-mode 設置為no (也就是關閉保護模式) 3. daemon ...
  • 一、ListView 該組件是android中最常用的一個UI組件,用於實現在屏幕上顯示​多個內容,以便於我們用手指來回翻轉。 先在layout中進行佈局我們的組件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/and ...
  • 對初學者來說,看完這篇文章,我想你腦瓜子一定是嗡嗡的,這都說的是什麼啊。 不要急躁,開始的我和你是一樣的,第一遍看完,完全不知道在說什麼,不明白不要緊,請先收藏此文章,然後先去學習下Flutter內置的25種動畫組件。 地址: "http://laomengit.com/flutter/module ...
  • 網站主題灰度顯示 在style.css文件頂端添加下行代碼即可 ​ 2020開年一切都是那麼的不平凡,這段時間我見證了太多的不可思議:修建”火神山“、”雷神山“醫院,大批醫療人員志願者奔赴湖北;各國政府及組織捐贈防控物資;各地省內省際長途關閉、火車實行隔座,航班限次;封城封村封小區;各地實行健康碼, ...
  • 本文直接從防禦方式開始討論,防禦CSRF有4種方法: 使用POST替代GET 檢驗HTTP Referer 驗證碼 Token 使用POST替代GET 一些程式員在開發的時候都是用GET、POST通用的函數來接收客戶端的數據,這樣也是某些介面有CSRF的原因之一,但是將全部介面都改成只允許POST方 ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...