Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 久久久久久久久久免观看,国产一区精品视频,国产精品久久久久久久专区

          整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢(xún)熱線:

          CSS3 @font-face

          CSS3 @font-face

          font-face是CSS3中的一個(gè)模塊,他主要是把自己定義的Web字體嵌入到你的網(wǎng)頁(yè)中,隨著@font-face模塊的出現(xiàn),我們?cè)赪eb的開(kāi)發(fā)中使用字體不怕只能使用Web安全字體,你們當(dāng)中或許有許多人會(huì)不自然的問(wèn),這樣的東西IE能支持嗎?當(dāng)我告訴大家@font-face這個(gè)功能早在IE4就支持了你肯定會(huì)感到驚訝。我的Blog就使用了許多這樣的自定義Web字體,比如說(shuō)首頁(yè)的Logo,Tags以及頁(yè)面中的手寫(xiě)英文體,很多朋友問(wèn)我如何使用,能讓自己的頁(yè)面也支持這樣的自定義字體,一句話這些都是@font-face實(shí)現(xiàn)的,為了能讓更多的朋友知道如何使用他,今天我主要把自己的一點(diǎn)學(xué)習(xí)過(guò)程貼上來(lái)和大家分享。

          首先我們一起來(lái)看看@font-face的語(yǔ)法規(guī)則:

          @font-face {
           font-family: <YourWebFontName>;
           src: <source> [<format>][,<source> [<format>]]*;
           [font-weight: <weight>];
           [font-style: <style>];
           }
          

          取值說(shuō)明

          1. YourWebFontName:此值指的就是你自定義的字體名稱(chēng),最好是使用你下載的默認(rèn)字體,他將被引用到你的Web元素中的font-family。如“font-family:"YourWebFontName";”
          2. source:此值指的是你自定義的字體的存放路徑,可以是相對(duì)路徑也可以是絕路徑;
          3. format:此值指的是你自定義的字體的格式,主要用來(lái)幫助瀏覽器識(shí)別,其值主要有以下幾種類(lèi)型:truetype,opentype,truetype-aat,embedded-opentype,avg等;
          4. weight和style:這兩個(gè)值大家一定很熟悉,weight定義字體是否為粗體,style主要定義字體樣式,如斜體。

          兼容瀏覽器

          說(shuō)到瀏覽器對(duì)@font-face的兼容問(wèn)題,這里涉及到一個(gè)字體format的問(wèn)題,因?yàn)椴煌臑g覽器對(duì)字體格式支持是不一致的,這樣大家有必要了解一下,各種版本的瀏覽器支持什么樣的字體,前面也簡(jiǎn)單帶到了有關(guān)字體的幾種格式,下面我就分別說(shuō)一下這個(gè)問(wèn)題,讓大家心里有一個(gè)概念:

          一、TureTpe(.ttf)格式:

          .ttf字體是Windows和Mac的最常見(jiàn)的字體,是一種RAW格式,因此他不為網(wǎng)站優(yōu)化,支持這種字體的瀏覽器有【IE9+,Firefox3.5+,Chrome4+,Safari3+,Opera10+,iOS Mobile Safari4.2+】;

          二、OpenType(.otf)格式:

          .otf字體被認(rèn)為是一種原始的字體格式,其內(nèi)置在TureType的基礎(chǔ)上,所以也提供了更多的功能,支持這種字體的瀏覽器有【Firefox3.5+,Chrome4.0+,Safari3.1+,Opera10.0+,iOS Mobile Safari4.2+】;

          三、Web Open Font Format(.woff)格式:

          .woff字體是Web字體中最佳格式,他是一個(gè)開(kāi)放的TrueType/OpenType的壓縮版本,同時(shí)也支持元數(shù)據(jù)包的分離,支持這種字體的瀏覽器有【IE9+,Firefox3.5+,Chrome6+,Safari3.6+,Opera11.1+】;

          四、Embedded Open Type(.eot)格式:

          .eot字體是IE專(zhuān)用字體,可以從TrueType創(chuàng)建此格式字體,支持這種字體的瀏覽器有【IE4+】;

          五、SVG(.svg)格式:

          .svg字體是基于SVG字體渲染的一種格式,支持這種字體的瀏覽器有【Chrome4+,Safari3.1+,Opera10.0+,iOS Mobile Safari3.2+】。

          這就意味著在@font-face中我們至少需要.woff,.eot兩種格式字體,甚至還需要.svg等字體達(dá)到更多種瀏覽版本的支持。

          為了使@font-face達(dá)到更多的瀏覽器支持,Paul Irish寫(xiě)了一個(gè)獨(dú)特的@font-face語(yǔ)法叫Bulletproof @font-face:

           @font-face {
          	font-family: 'YourWebFontName';
          	src: url('YourWebFontName.eot?') format('eot');/*IE*/
          	src:url('YourWebFontName.woff') format('woff'), url('YourWebFontName.ttf') format('truetype');/*non-IE*/
           }
          

          但為了讓各多的瀏覽器支持,你也可以寫(xiě)成:

           @font-face {
          	font-family: 'YourWebFontName';
          	src: url('YourWebFontName.eot'); /* IE9 Compat Modes */
          	src: url('YourWebFontName.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
           url('YourWebFontName.woff') format('woff'), /* Modern Browsers */
           url('YourWebFontName.ttf') format('truetype'), /* Safari, Android, iOS */
           url('YourWebFontName.svg#YourWebFontName') format('svg'); /* Legacy iOS */
           }
          

          說(shuō)了這么多空洞的理論知識(shí),大家一定有點(diǎn)心癢癢了,那么我們先來(lái)看看W3CPLUS首頁(yè)中導(dǎo)航部分的蘭色字體是如何實(shí)現(xiàn)的,假如我們有一個(gè)這樣的DOM標(biāo)簽,需要應(yīng)用自定義字體:

          HTML Code:

          <h2 class="neuesDemo">Neues Bauen Demo</h2>
          

          通過(guò)@font-face來(lái)定義自己的Web Font:

          @font-face {
           font-family: 'NeuesBauenDemo';
           src: url('../fonts/neues_bauen_demo-webfont.eot');
           src: url('../fonts/neues_bauen_demo-webfont.eot?#iefix') format('embedded-opentype'),
           url('../fonts/neues_bauen_demo-webfont.woff') format('woff'),
           url('../fonts/neues_bauen_demo-webfont.ttf') format('truetype'),
           url('../fonts/neues_bauen_demo-webfont.svg#NeuesBauenDemo') format('svg');
           font-weight: normal;
           font-style: normal;
          }
          

          我在這里采用的是相對(duì)路徑,當(dāng)然大家也可以使用絕路徑。到這里我們就需要把定義好的字體應(yīng)用到我們實(shí)際頁(yè)面中去:

          h2.neuesDemo {
           font-family: 'NeuesBauenDemo'
          }
          

          效果:

          看到上面的效果,我想大家會(huì)感到@font-face很神奇,同時(shí)也想爭(zhēng)著做做看,可是一動(dòng)手才發(fā)現(xiàn),特殊字體我要怎樣才能得到,那些.eot,.woff,.ttf,.svg這些字體格式又怎么獲取呢?有些朋友可能就不知道如何運(yùn)手了,那么我們就帶著這些問(wèn)題來(lái)一個(gè)全程完成的實(shí)例吧:

          一、獲取特殊字體:

          我們拿下面這種single Malta字體來(lái)說(shuō)吧:

          要得到single Malta字體,不外乎兩種途徑,其一找到付費(fèi)網(wǎng)站購(gòu)買(mǎi)字體,其二就是到免費(fèi)網(wǎng)站DownLoad字體。當(dāng)然要給錢(qián)的這種傻事我想大家都不會(huì)做的,那我們就得到免費(fèi)的地方下載,在哪有呢?我平時(shí)都是到Google Web Fonts和Dafont.com尋找自己需要的字體,當(dāng)然網(wǎng)上也還有別的下載字體的地方,這個(gè)Demo使用的是Dafont.com的Single Malta字體,這樣就可以到這里下載Single Malta:

          Single Malta下載下來(lái)后,需要把它解壓縮出來(lái):

          二、獲取@font-face所需字體格式:

          特殊字體已經(jīng)在你的電腦中了,現(xiàn)在我們需要想辦法獲得@font-face所需的.eot,.woff,.ttf,.svg字體格式。要獲取這些字體格式,我們同樣是需要第三方工具或者軟件來(lái)實(shí)現(xiàn),下面我給大家推薦一款我常用的一個(gè)工具fontsquirrel,別的先不多說(shuō),首跟我點(diǎn)這里進(jìn)入到下面這個(gè)界面吧。

          如果你進(jìn)入頁(yè)面沒(méi)有看到上圖,你可以直接點(diǎn)擊導(dǎo)航:

          如果你看到了上面的界面,那就好辦了,我們來(lái)看如何應(yīng)用這個(gè)工具生成@font-face需要的各種字體,先把我們剛才下載的字體上傳上去:

          上傳后按下圖所示操作:

          現(xiàn)在從Font Squirrel下載下來(lái)的文件已經(jīng)保存在你本地的電腦上了,接著只要對(duì)他進(jìn)行解壓縮,你就能看到文件列表如下所示:

          大家可以看到,解壓縮出來(lái)的文件格式,里面除了@font-face所需要的字體格式外,還帶有一個(gè)DEMO文件,如果你不清楚的也可以參考下載下來(lái)的DEMO文件,我在這里不對(duì)DEMO說(shuō)明問(wèn)題,我主要是給大家介紹如何把下載下來(lái)的文件有價(jià)值的運(yùn)用到我們的項(xiàng)目中。

          例如在自己的本地創(chuàng)建了一個(gè)fontface項(xiàng)目:

          為了讓項(xiàng)目結(jié)構(gòu)更清晰,我們?cè)陧?xiàng)目中單獨(dú)創(chuàng)建一個(gè)fonts目錄,用來(lái)放置解壓縮出來(lái)@font-face所需的字體格式:

          現(xiàn)在@font-face所需字體已經(jīng)加載到本地項(xiàng)目,現(xiàn)在本地項(xiàng)目中的style.css中附上我們需要的@font-face樣式

          @font-face {
           font-family: 'SingleMaltaRegular';
           src: url('../fonts/singlemalta-webfont.eot');
           src: url('../fonts/singlemalta-webfont.eot?#iefix') format('embedded-opentype'),
           url('../fonts/singlemalta-webfont.woff') format('woff'),
           url('../fonts/singlemalta-webfont.ttf') format('truetype'),
           url('../fonts/singlemalta-webfont.svg#SingleMaltaRegular') format('svg');
           font-weight: normal;
           font-style: normal;
          }
          

          到這里為止,我們已經(jīng)通過(guò)@font-face自定義好所需的SingleMalta字體,離最后效果只差一步了,就是把自己定義的字體應(yīng)用到你的Web中的DOM元素上:

          h2.singleMalta {
           font-family: 'SingleMaltaRegular'
          }
          

          效果:

          看到上面的效果,那大家就知道我們實(shí)現(xiàn)成功了。那么關(guān)于@font-face幫你打造特殊效果的字體,到這里基本上就完成了,我在這里需要提醒使用者:

          1、如果你的項(xiàng)目中是英文網(wǎng)站,而且項(xiàng)目中的Logo,Tags等應(yīng)用到較多的這種特殊字體效果,我建議你不要使用圖片效果,而使用@font-face,但是你是中文網(wǎng)站,我覺(jué)得還是使用圖片比較合適,因?yàn)榧虞d英文字體和圖片沒(méi)有多大區(qū)別,但是你加載中文字體,那就不一樣了,因?yàn)橹形淖煮w太大了,這樣會(huì)影響到項(xiàng)目的某些性能的優(yōu)化;

          2、致命的錯(cuò)誤,你在@font-face中定義時(shí),文件路徑?jīng)]有載對(duì);

          3、你只定義了@font-face,但并沒(méi)有應(yīng)用到你的項(xiàng)目中的DOM元素上;

          以上幾點(diǎn)都是在平時(shí)制作中常出現(xiàn)的問(wèn)題,希望大家能小意一些,另外我們沒(méi)有辦法在購(gòu)買(mǎi)所有字體,就算你實(shí)力雄厚,那也沒(méi)有辦法在一臺(tái)服務(wù)器主機(jī)上放置你所有項(xiàng)目需要的字體。因此我給大家提供幾個(gè)免費(fèi)字體下載的網(wǎng)址:Webfonts,Typekit,Kernest,Google Web Fonts,Kernest,Dafont,Niec Web Type,不然你點(diǎn)這里將有更多的免費(fèi)字體。前面幾個(gè)鏈接是幫助你獲取一些優(yōu)美的怪異的特殊字體,但下面這個(gè)工具作用更是無(wú)窮的大,他能幫你生成@font-face所需要的各種字體,這工具就是Font Squirrel。

          最后在提醒一下,使用@font-face別的可以忘了,但Font Squirrel千萬(wàn)不能忘,因?yàn)樗軒湍闵葽font-face所需的各種字體格式。

          到此關(guān)于@font-face就介紹完了,不知道大家喜歡不喜歡,如果喜歡的話趕快動(dòng)手實(shí)踐一下,有Blog的可以馬上運(yùn)用上去,也可以炫一下。

          學(xué)習(xí)從來(lái)不是一個(gè)人的事情,要有個(gè)相互監(jiān)督的伙伴,想要學(xué)習(xí)或交流前端問(wèn)題的小伙伴可以私信“學(xué)習(xí)”小明加群獲取2019web前端最新入門(mén)資料,一起學(xué)習(xí),一起成長(zhǎng)!

          -2 SPU和SKU詳解

          ??商城系統(tǒng)中的商品信息肯定避免不了SPU和SKU這兩個(gè)概念,本節(jié)就給大家詳細(xì)介紹下這塊的內(nèi)容

          1、掌握SKU和SPU關(guān)系

          SPU=Standard Product Unit (標(biāo)準(zhǔn)化產(chǎn)品單元)

          SPU是商品信息聚合的最小單位,是一組可復(fù)用、易檢索的標(biāo)準(zhǔn)化信息的集合,該集合描述了一個(gè)產(chǎn)品的特性。通俗點(diǎn)講,屬性值、特性相同的商品就可以稱(chēng)為一個(gè)SPU。

          SKU=stock keeping unit(庫(kù)存量單位)

          SKU即庫(kù)存進(jìn)出計(jì)量的單位, 可以是以件、盒、托盤(pán)等為單位。

          SKU是物理上不可分割的最小存貨單元。在使用時(shí)要根據(jù)不同業(yè)態(tài),不同管理模式來(lái)處理。在服裝、鞋類(lèi)商品中使用最多最普遍。

          舉個(gè)例子:

          購(gòu)買(mǎi)手機(jī)的時(shí)候,你可以選擇華為Mate40系列手機(jī),Mate40系列手機(jī)的生產(chǎn)制造商是華為,品牌是華為,手機(jī)分類(lèi)也是華為,不過(guò)Mate40系列手機(jī)有多款,比如 Mate40 、Mate40 Pro 、 Mate40 Pro +,每款手機(jī)的架構(gòu)也不一樣,顏色也不一定一樣,那么這個(gè)例子中哪些是Spu哪些是Sku呢?

          Spu:

          手機(jī)系列:Mate40系列
          廠家:華為
          品牌:華為
          分類(lèi):手機(jī)

          Sku:

          價(jià)格
          顏色
          網(wǎng)絡(luò)格式

          2、表結(jié)構(gòu)設(shè)計(jì)

          2.1 Spu和Sku

          spu:

          CREATE TABLE `spu` (
            `id` varchar(60) NOT NULL COMMENT '主鍵',
            `name` varchar(100) DEFAULT NULL COMMENT 'SPU名',
            `intro` varchar(200) DEFAULT NULL COMMENT '簡(jiǎn)介',
            `brand_id` int(11) DEFAULT NULL COMMENT '品牌ID',
            `category_one_id` int(20) DEFAULT NULL COMMENT '一級(jí)分類(lèi)',
            `category_two_id` int(10) DEFAULT NULL COMMENT '二級(jí)分類(lèi)',
            `category_three_id` int(10) DEFAULT NULL COMMENT '三級(jí)分類(lèi)',
            `images` varchar(1000) DEFAULT NULL COMMENT '圖片列表',
            `after_sales_service` varchar(50) DEFAULT NULL COMMENT '售后服務(wù)',
            `content` longtext COMMENT '介紹',
            `attribute_list` varchar(3000) DEFAULT NULL COMMENT '規(guī)格列表',
            `is_marketable` int(1) DEFAULT '0' COMMENT '是否上架,0已下架,1已上架',
            `is_delete` int(1) DEFAULT '0' COMMENT '是否刪除,0:未刪除,1:已刪除',
            `status` int(1) DEFAULT '0' COMMENT '審核狀態(tài),0:未審核,1:已審核,2:審核不通過(guò)',
            PRIMARY KEY (`id`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

          sku:

          CREATE TABLE `sku` (
            `id` varchar(60) NOT NULL COMMENT '商品id',
            `name` varchar(200) NOT NULL COMMENT 'SKU名稱(chēng)',
            `price` int(20) NOT NULL DEFAULT '1' COMMENT '價(jià)格(分)',
            `num` int(10) DEFAULT '100' COMMENT '庫(kù)存數(shù)量',
            `image` varchar(200) DEFAULT NULL COMMENT '商品圖片',
            `images` varchar(2000) DEFAULT NULL COMMENT '商品圖片列表',
            `create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時(shí)間',
            `update_time` datetime DEFAULT NULL COMMENT '更新時(shí)間',
            `spu_id` varchar(60) DEFAULT NULL COMMENT 'SPUID',
            `category_id` int(10) DEFAULT NULL COMMENT '類(lèi)目ID',
            `category_name` varchar(200) DEFAULT NULL COMMENT '類(lèi)目名稱(chēng)',
            `brand_id` int(11) DEFAULT NULL COMMENT '品牌id',
            `brand_name` varchar(100) DEFAULT NULL COMMENT '品牌名稱(chēng)',
            `sku_attribute` varchar(200) DEFAULT NULL COMMENT '規(guī)格',
            `status` int(1) DEFAULT '1' COMMENT '商品狀態(tài) 1-正常,2-下架,3-刪除',
            PRIMARY KEY (`id`),
            KEY `cid` (`category_id`),
            KEY `status` (`status`),
            KEY `updated` (`update_time`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品表';

          2.2 商品發(fā)布流程分析

          商品發(fā)布流程如下:

          1)分類(lèi)選擇

          發(fā)布商品前,需要先選擇發(fā)布商品所屬分類(lèi),分類(lèi)嚴(yán)格定義為3級(jí)分類(lèi)。

          分類(lèi)表:

          CREATE TABLE `category` (
            `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '分類(lèi)ID',
            `name` varchar(50) DEFAULT NULL COMMENT '分類(lèi)名稱(chēng)',
            `sort` int(11) DEFAULT NULL COMMENT '排序',
            `parent_id` int(20) DEFAULT NULL COMMENT '上級(jí)ID',
            PRIMARY KEY (`id`),
            KEY `parent_id` (`parent_id`)
          ) ENGINE=InnoDB AUTO_INCREMENT=11182 DEFAULT CHARSET=utf8 COMMENT='商品類(lèi)目';

          2)選擇品牌

          分類(lèi)選擇完成后,需要加載品牌,品牌加載并非一次性加載完成,而是根據(jù)選擇的分類(lèi)進(jìn)行加載。

          分類(lèi)品牌關(guān)系表:

          CREATE TABLE `category_brand` (
            `category_id` int(11) NOT NULL COMMENT '分類(lèi)ID',
            `brand_id` int(11) NOT NULL COMMENT '品牌ID',
            PRIMARY KEY (`brand_id`,`category_id`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

          品牌表:

          CREATE TABLE `brand` (
            `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '品牌id',
            `name` varchar(100) NOT NULL COMMENT '品牌名稱(chēng)',
            `image` varchar(1000) DEFAULT '' COMMENT '品牌圖片地址',
            `initial` varchar(1) DEFAULT '' COMMENT '品牌的首字母',
            `sort` int(11) DEFAULT NULL COMMENT '排序',
            PRIMARY KEY (`id`)
          ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COMMENT='品牌表';

          3)屬性加載

          當(dāng)選擇分類(lèi)后,加載分類(lèi)對(duì)應(yīng)的屬性。

          分類(lèi)屬性表:

          CREATE TABLE `category_attr` (
            `category_id` int(11) NOT NULL,
            `attr_id` int(11) NOT NULL COMMENT '屬性分類(lèi)表',
            PRIMARY KEY (`category_id`,`attr_id`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

          屬性表:

          CREATE TABLE `sku_attribute` (
            `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
            `name` varchar(50) DEFAULT NULL COMMENT '屬性名稱(chēng)',
            `options` varchar(2000) DEFAULT NULL COMMENT '屬性選項(xiàng)',
            `sort` int(11) DEFAULT NULL COMMENT '排序',
            PRIMARY KEY (`id`)
          ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

          3、 商品發(fā)布加載功能

          對(duì)應(yīng)的Bean我們已經(jīng)提前寫(xiě)好,如下

          package com.bobo.vip.mall.goods.model;
          
          import com.baomidou.mybatisplus.annotation.IdType;
          import com.baomidou.mybatisplus.annotation.TableId;
          import com.baomidou.mybatisplus.annotation.TableName;
          import lombok.AllArgsConstructor;
          import lombok.Data;
          import lombok.NoArgsConstructor;
          
          import java.io.Serializable;
          
          /*****
           * @Author: 波波
           * @Description: 云商城
           ****/
          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          //MyBatisPlus表映射注解
          @TableName(value="category")
          public class Category implements Serializable {
          
              @TableId(type=IdType.AUTO)
              private Integer id;
              private String name;
              private Integer sort;
              private Integer parentId;
          }
          package com.bobo.vip.mall.goods.model;
          
          import com.baomidou.mybatisplus.annotation.TableField;
          import com.baomidou.mybatisplus.annotation.TableName;
          import lombok.AllArgsConstructor;
          import lombok.Data;
          import lombok.NoArgsConstructor;
          
          /*****
           * @Author: 波波
           * @Description: 云商城
           ****/
          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          //MyBatisPlus表映射注解
          @TableName(value="category_attr")
          public class CategoryAttr {
          
              @TableField
              private Integer categoryId;
          
              @TableField
              private Integer attrId;
          
          }
          /*****
           * @Author: 波波
           * @Description: 云商城
           ****/
          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          //MyBatisPlus表映射注解
          @TableName(value="category_brand")
          public class CategoryBrand {
          
              @TableField
              private Integer categoryId;
          
              @TableField
              private Integer brandId;
          }
          /*****
           * @Author: 波波
           * @Description: 云商城
           ****/
          @Data
          @NoArgsConstructor
          @AllArgsConstructor
          public class Product {
              // Spu
              private Spu spu;
              // Sku
              private List<Sku> skus;
          }
          
          1234567891011121314
          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          //MyBatisPlus表映射注解
          @TableName(value="sku")
          public class Sku {
          
              @TableId(type=IdType.ASSIGN_ID)
              private String id;
              private String name;
              private Integer price;
              private Integer num;
              private String image;
              private String images;
              private Date createTime;
              private Date updateTime;
              private String spuId;
              private Integer categoryId;
              private String categoryName;
              private Integer brandId;
              private String brandName;
              private String skuAttribute;
              private Integer status;
          }
          /*****
           * @Author: 波波
           * @Description: 云商城
           ****/
          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          //MyBatisPlus表映射注解
          @TableName(value="sku_attribute")
          public class SkuAttribute implements Serializable {
          
              @TableId(type=IdType.AUTO)
              private Integer id;
              private String name;
              private String options;
              private Integer sort;
          
              //對(duì)應(yīng)分類(lèi)
              @TableField(exist=false)
              private List<Category> categories;
          
          }
          12345678910111213141516171819202122
          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          //MyBatisPlus表映射注解
          @TableName(value="spu")
          public class Spu {
          
              @TableId(type=IdType.ASSIGN_ID)
              private String id;
              private String name;
              private String intro;
              private Integer brandId;
              private Integer categoryOneId;
              private Integer categoryTwoId;
              private Integer categoryThreeId;
              private String images;
              private String afterSalesService;
              private String content;
              private String attributeList;
              private Integer isMarketable;
              private Integer isDelete;
              private Integer status;
          }

          3.1 分類(lèi)加載

          分類(lèi)功能需要實(shí)現(xiàn)按照父ID查詢(xún),最開(kāi)始初始化加載的是頂級(jí)父類(lèi),parent_id=0,后面每次點(diǎn)擊的時(shí)候都根據(jù)傳入的id查詢(xún)子分類(lèi)。

          1)Mapper

          創(chuàng)建com.bobo.vip.mall.goods.mapper.CategoryMapper,代碼如下:

          public interface CategoryMapper extends BaseMapper<Category> {
          }
          12

          2)Service

          接口:com.bobo.vip.mall.goods.service.CategoryService代碼如下:

          public interface CategoryService extends IService<Category> {
          
              /**
               * 根據(jù)父ID查詢(xún)子分類(lèi)
               * @param pid
               * @return
               */
              List<Category> queryByParentId(Integer pid);
          }
          123456789

          實(shí)現(xiàn)類(lèi):com.bobo.vip.mall.goods.service.impl.CategoryServiceImpl代碼如下:

          @Service
          public class CategoryServiceImpl extends ServiceImpl<CategoryMapper,Category> implements CategoryService {
          
              @Autowired
              private CategoryMapper categoryMapper;
          
              /***
               * 根據(jù)父ID查詢(xún)子分類(lèi)
               * @param pid
               * @return
               */
              @Override
              public List<Category> queryByParentId(Integer pid) {
                  //條件封裝
                  QueryWrapper<Category> queryWrapper=new QueryWrapper<Category>();
                  queryWrapper.eq("parent_id",pid);
                  return categoryMapper.selectList(queryWrapper);
              }
          }
          12345678910111213141516171819

          3)Controller

          創(chuàng)建com.bobo.vip.mall.goods.controller.CategoryController代碼如下;

          @RestController
          @RequestMapping(value="/category")
          @CrossOrigin
          public class CategoryController {
          
              @Autowired
              private CategoryService categoryService;
          
              /****
               * 根據(jù)父ID查詢(xún)子分類(lèi)
               */
              @GetMapping(value="/parent/{pid}")
              public RespResult<List<Category>> list(@PathVariable(value="pid")Integer pid){
                  List<Category> categories=categoryService.queryByParentId(pid);
                  return RespResult.ok(categories);
              }
          }
          1234567891011121314151617

          3.2 品牌加載

          品牌需要根據(jù)分類(lèi)進(jìn)行加載,當(dāng)用戶(hù)選擇第3級(jí)分類(lèi)的時(shí)候,加載品牌,品牌數(shù)據(jù)需要經(jīng)過(guò)category_brand表關(guān)聯(lián)查詢(xún)。

          我們可以按照如下步驟實(shí)現(xiàn):

          1、查詢(xún)category_brand中指定分類(lèi)對(duì)應(yīng)的品牌ID集合
          2、從brand查出品牌集合

          1)Mapper

          修改com.bobo.vip.mall.goods.mapper.BrandMapper,添加根據(jù)分類(lèi)ID查詢(xún)品牌ID集合:

          //根據(jù)分類(lèi)ID查詢(xún)品牌集合
          @Select("select brand_id from category_brand where category_id=#{id}")
          List<Integer> queryBrandIds(Integer id);
          123

          2)Service

          接口:com.bobo.vip.mall.goods.service.BrandService中添加根據(jù)分類(lèi)ID查詢(xún)品牌集合方法

          //根據(jù)分類(lèi)ID查詢(xún)品牌
          List<Brand> queryByCategoryId(Integer id);
          12

          實(shí)現(xiàn)類(lèi):com.bobo.vip.mall.goods.service.impl.BrandServiceImpl

          /***
           * 根據(jù)分類(lèi)ID查詢(xún)品牌
           * @param id
           * @return
           */
          @Override
          public List<Brand> queryByCategoryId(Integer id) {
              //查詢(xún)分類(lèi)ID對(duì)應(yīng)的品牌集合
              List<Integer> brandIds=brandMapper.queryBrandIds(id);
              //根據(jù)品牌ID集合查詢(xún)品牌信息
              List<Brand> brands=brandMapper.selectBatchIds(brandIds);
              return brands;
          }
          12345678910111213

          3)Controller

          修改com.bobo.vip.mall.goods.controller.BrandController添加根據(jù)分類(lèi)ID查詢(xún)品牌集合

          /****
           * 根據(jù)分類(lèi)ID查詢(xún)品牌
           */
          @GetMapping(value="/category/{id}")
          public RespResult<List<Brand>> categoryBrands(@PathVariable(value="id")Integer id){
              List<Brand> brands=brandService.queryByCategoryId(id);
              return RespResult.ok(brands);
          }
          12345678

          3.3 屬性加載

          屬性也稱(chēng)為規(guī)格,屬性也需要根據(jù)分類(lèi)查詢(xún),我們可以按照如下思路實(shí)現(xiàn):

          1、先從category_attr根據(jù)分類(lèi)ID查詢(xún)出當(dāng)前分類(lèi)擁有的屬性ID集合
          2、從sku_attribute中查詢(xún)屬性集合

          1)Mapper

          創(chuàng)建com.bobo.vip.mall.goods.mapper.SkuAttributeMapper實(shí)現(xiàn)根據(jù)分類(lèi)ID查詢(xún)屬性信息。

          /***
           * 根據(jù)分類(lèi)ID查詢(xún)屬性集合
           * @param id
           * @return
           */
          @Select("SELECT * FROM sku_attribute WHERE id IN(SELECT attr_id FROM category_attr WHERE category_id=#{id})")
          List<SkuAttribute> queryByCategoryId(Integer id);
          1234567

          2)Service

          接口:com.bobo.vip.mall.goods.service.SkuAttributeService添加根據(jù)分類(lèi)ID查詢(xún)屬性集合方法

          //根據(jù)分類(lèi)ID查詢(xún)屬性集合
          List<SkuAttribute> queryList(Integer id);
          12

          實(shí)現(xiàn)類(lèi):com.bobo.vip.mall.goods.service.impl.SkuAttributeServiceImpl添加如下實(shí)現(xiàn)方法

          /***
           * 根據(jù)分類(lèi)ID查詢(xún)屬性集合
           * @param id
           * @return
           */
          @Override
          public List<SkuAttribute> queryList(Integer id) {
              return skuAttributeMapper.queryByCategoryId(id);
          }
          123456789

          3)Controller

          創(chuàng)建com.bobo.vip.mall.goods.controller.SkuAttributeController,添加如下方法

          /***
           * 根據(jù)分類(lèi)ID查詢(xún)
           */
          @GetMapping(value="/category/{id}")
          public RespResult<SkuAttribute> categoryAttributeList(@PathVariable(value="id")Integer id){
              //根據(jù)分類(lèi)ID查詢(xún)屬性參數(shù)
              List<SkuAttribute> skuAttributes=skuAttributeService.queryList(id);
              return RespResult.ok(skuAttributes);
          }
          123456789

          4、商品發(fā)布

          4.1 復(fù)合對(duì)象分析

          商品發(fā)布,如上圖,我們可以發(fā)現(xiàn)發(fā)布的商品信息包含Sku和Spu,因此我們應(yīng)該在后端能有一個(gè)對(duì)象同時(shí)能接到Spu和多個(gè)Sku,方法有很多種,我們可以直接在Spu中寫(xiě)一個(gè)List<Sku>,但這種方法不推薦,按照對(duì)象設(shè)計(jì)原則,對(duì)一個(gè)對(duì)象進(jìn)行擴(kuò)展時(shí),盡量避免對(duì)原始對(duì)象造成改變,因此我們可以使用復(fù)合類(lèi),可以創(chuàng)建一個(gè)Prodcut類(lèi),該類(lèi)中有Spu也有List<Sku>,代碼如下:

          @Data
          @NoArgsConstructor
          @AllArgsConstructor
          public class Product {
              // Spu
              private Spu spu;
              // Sku
              private List<Sku> skus;
          }
          123456789

          4.2 添加商品

          添加商品的時(shí)候,我們需要保存Spu,同時(shí)需要添加多個(gè)Sku。我們可以在華為商城中看看真實(shí)電商中Sku名字特征,每次點(diǎn)擊不同屬性的時(shí)候,前部分名字一樣,只是將名字中的規(guī)格替換了,也就是說(shuō)Sku的名字其實(shí)是組合成的,一部分是Spu的一部分是Sku的,可以進(jìn)行組合。

          1)名字分析

          添加商品的時(shí)候,會(huì)將商品的屬性傳入后臺(tái),格式如下,如果把規(guī)格名字添加到名字中,那就是華為商城中的效果了,我們可以這么做,把屬性解析成Map,然后每個(gè)屬性值添加到商品名字中即可。

          {"適合人群":"有一定java基礎(chǔ)的人","書(shū)籍分類(lèi)":"軟件編程"}

          2)實(shí)現(xiàn)代碼

          Mapper

          com.bobo.vip.mall.goods.mapper.SpuMapper代碼如下:

          public interface SpuMapper extends BaseMapper<Spu> {
          }
          12

          com.bobo.vip.mall.goods.mapper.SkuMapper代碼如下:

          public interface SkuMapper extends BaseMapper<Sku> {
          }
          12

          Service

          com.bobo.vip.mall.goods.service.SpuService中添加產(chǎn)品方法如下

          public interface SpuService extends IService<Spu> {
              //保存商品
              void saveProduct(Product product);
          }
          1234

          com.bobo.vip.mall.goods.service.impl.SpuServiceImpl中添加產(chǎn)品方法如下:

          @Service
          public class SpuServiceImpl extends ServiceImpl<SpuMapper,Spu> implements SpuService {
          
              @Autowired
              private SkuMapper skuMapper;
          
              @Autowired
              private SpuMapper spuMapper;
          
              @Autowired
              private CategoryMapper categoryMapper;
          
              @Autowired
              private BrandMapper brandMapper;
          
              // 保存商品
              @Override
              public void saveProduct(Product product) {
                  //Spu
                  Spu spu=product.getSpu();
                  //上架
                  spu.setIsMarketable(1);
                  //未刪除
                  spu.setIsDelete(0);
                  //狀態(tài)
                  spu.setStatus(1);
                  //添加
                  spuMapper.insert(spu);
          
          
                  //查詢(xún)?nèi)?jí)分類(lèi)
                  Category category=categoryMapper.selectById(spu.getCategoryThreeId());
                  //查詢(xún)品牌
                  Brand brand=brandMapper.selectById(spu.getBrandId());
                  //當(dāng)前時(shí)間
                  Date now=new Date();
          
                  //新增Sku集合
                  for (Sku sku : product.getSkus()) {
                      //設(shè)置名字
                      String skuName=spu.getName();
                      Map<String,String> attrMap=JSON.parseObject(sku.getSkuAttribute(), Map.class);
                      for (Map.Entry<String, String> entry : attrMap.entrySet()) {
                          skuName+="   "+entry.getValue();
                      }
                      sku.setName(skuName);
                      //設(shè)置圖片
                      sku.setImages(spu.getImages());
                      //設(shè)置狀態(tài)
                      sku.setStatus(1);
                      //設(shè)置類(lèi)目ID
                      sku.setCategoryId(spu.getCategoryThreeId());
                      //設(shè)置類(lèi)目名稱(chēng)
                      sku.setCategoryName(category.getName());
                      //設(shè)置品牌ID
                      sku.setBrandId(brand.getId());
                      //設(shè)置品牌名稱(chēng)
                      sku.setBrandName(brand.getName());
                      //設(shè)置Spuid
                      sku.setSpuId(spu.getId());
                      //時(shí)間
                      sku.setCreateTime(now);
                      sku.setUpdateTime(now);
                      //增加
                      skuMapper.insert(sku);
                  }
              }
          }
          1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

          Controller

          創(chuàng)建com.bobo.vip.mall.goods.controller.SpuController,添加產(chǎn)品代碼如下:

          @Autowired
          private SpuService spuService;
          
          /***
           * 保存
           */
          @PostMapping(value="/save")
          public RespResult save(@RequestBody Product product){
              //保存
              spuService.saveProduct(product);
              return RespResult.ok();
          }

          4.3 產(chǎn)品修改

          產(chǎn)品修改其實(shí)和產(chǎn)品添加幾乎一致,只需要做小改動(dòng)即可,實(shí)現(xiàn)步驟如下:

          1、如果Spu的id值不為空,說(shuō)明是修改操作
          2、如果是修改操作,先刪除之前對(duì)應(yīng)的Sku集合
          3、其他流程和添加商品一致

          修改com.bobo.vip.mall.goods.service.impl.SpuServiceImplsave方法,代碼如下:

          在這里插入圖片描述

          源碼如下:

          @Override
          public void saveProduct(Product product) {
              //Spu
              Spu spu=product.getSpu();
          
              //如果ID為空,則增加
              if(StringUtils.isEmpty(spu.getId())){
                  //上架
                  spu.setIsMarketable(1);
                  //未刪除
                  spu.setIsDelete(0);
                  //狀態(tài)
                  spu.setStatus(1);
                  //添加
                  spuMapper.insert(spu);
              }else{
                  //ID 不為空,則修改
                  spuMapper.updateById(spu);
                  //刪除之前的Sku記錄
                  skuMapper.delete(new QueryWrapper<Sku>().eq("spu_id",spu.getId()));
              }
          
              //查詢(xún)?nèi)?jí)分類(lèi)
              Category category=categoryMapper.selectById(spu.getCategoryThreeId());
              //查詢(xún)品牌
              Brand brand=brandMapper.selectById(spu.getBrandId());
              //當(dāng)前時(shí)間
              Date now=new Date();
          
              //新增Sku集合
              for (Sku sku : product.getSkus()) {
                  //設(shè)置名字
                  String skuName=spu.getName();
                  Map<String,String> attrMap=JSON.parseObject(sku.getSkuAttribute(), Map.class);
                  for (Map.Entry<String, String> entry : attrMap.entrySet()) {
                      skuName+="   "+entry.getValue();
                  }
                  sku.setName(skuName);
                  //設(shè)置圖片
                  sku.setImages(spu.getImages());
                  //設(shè)置狀態(tài)
                  sku.setStatus(1);
                  //設(shè)置類(lèi)目ID
                  sku.setCategoryId(spu.getCategoryThreeId());
                  //設(shè)置類(lèi)目名稱(chēng)
                  sku.setCategoryName(category.getName());
                  //設(shè)置品牌ID
                  sku.setBrandId(brand.getId());
                  //設(shè)置品牌名稱(chēng)
                  sku.setBrandName(brand.getName());
                  //設(shè)置Spuid
                  sku.setSpuId(spu.getId());
                  //時(shí)間
                  sku.setCreateTime(now);
                  sku.setUpdateTime(now);
                  //增加
                  skuMapper.insert(sku);
              }
          }
          1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859

          5 MyBatis Plus代碼生成

          我們可以發(fā)現(xiàn)個(gè)問(wèn)題,剛才寫(xiě)的很多增刪改查代碼都比較簡(jiǎn)單,比較枯燥,重復(fù)寫(xiě)一些類(lèi)的創(chuàng)建、單表增刪改查非常類(lèi),而創(chuàng)建對(duì)象和單標(biāo)操作的代碼,在開(kāi)發(fā)中幾乎占用了開(kāi)發(fā)時(shí)間的80%,如果能夠用工具生成就可以大大節(jié)省我們開(kāi)發(fā)成本了。

          5.1 MyBatis Plus介紹

          AutoGenerator 是 MyBatis-Plus 的代碼生成器,通過(guò) AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個(gè)模塊的代碼,極大的提升了開(kāi)發(fā)效率。

          學(xué)習(xí)網(wǎng)址 https://baomidou.com/guide/generator.html

          5.2 MyBatisPlus代碼生成配置

          1)引入依賴(lài)

          <dependency>
              <groupId>com.baomidou</groupId>
              <artifactId>mybatis-plus-generator</artifactId>
              <version>3.4.0</version>
          </dependency>
          
          <dependency>
              <groupId>org.apache.velocity</groupId>
              <artifactId>velocity-engine-core</artifactId>
              <version>2.2</version>
          </dependency>
          1234567891011

          2)代碼生成

          public static void main(String[] args) {
              // 代碼生成器
              AutoGenerator mpg=new AutoGenerator();
          
              // 全局配置
              GlobalConfig gc=new GlobalConfig();
              String projectPath=System.getProperty("user.dir");
              gc.setOutputDir(projectPath + "/src/main/java");    // 文件輸出路徑
              gc.setAuthor("bobo");   //作者
              gc.setOpen(false);   //生成之后是否打開(kāi)目錄
              gc.setIdType(IdType.NONE);  //主鍵策略
              gc.setServiceName("%sService"); //名字設(shè)置 %s是占位符,可以理解成類(lèi)的名字
              mpg.setGlobalConfig(gc);
          
              // 數(shù)據(jù)源配置
              DataSourceConfig dsc=new DataSourceConfig();
              dsc.setUrl("jdbc:mysql://192.168.100.140:3306/shop_goods?useUnicode=true&useSSL=false&characterEncoding=utf8");
              dsc.setDriverName("com.mysql.jdbc.Driver");
              dsc.setUsername("root");
              dsc.setPassword("123456");
              mpg.setDataSource(dsc);
          
              // 包配置
              PackageConfig pc=new PackageConfig();
              pc.setModuleName("mall-goods");
              pc.setParent("com.bobo.code");
              mpg.setPackageInfo(pc);
          
              // 策略配置
              StrategyConfig strategy=new StrategyConfig();
              strategy.setNaming(NamingStrategy.underline_to_camel);  //駝峰命名
              strategy.setColumnNaming(NamingStrategy.underline_to_camel);    //駝峰命名
              strategy.setEntityLombokModel(true);    //是否使用Lombok
              strategy.setRestControllerStyle(true);  //是否生成RestController
              // 寫(xiě)于父類(lèi)中的公共字段
              strategy.setSuperEntityColumns("id");   //公共字段定義
              strategy.setControllerMappingHyphenStyle(true); //駝峰轉(zhuǎn)連字符
              strategy.setTablePrefix(pc.getModuleName() + "_");  //表前綴
              mpg.setStrategy(strategy);
              mpg.execute();
          }

          效果

          有紅色的提示是因?yàn)闆](méi)有引入依賴(lài),我們可以把生成的相關(guān)內(nèi)容拷貝到合適的項(xiàng)目位置即可。

          Vue.js 3.x+Express全棧開(kāi)發(fā):從0到1打造商城項(xiàng)目》

          1

          本書(shū)內(nèi)容

          《Vue.js 3.x+Express全棧開(kāi)發(fā) : 從0到1打造商城項(xiàng)目》是一本詳盡的全棧開(kāi)發(fā)教程,旨在通過(guò)Vue.js和Express框架引導(dǎo)讀者從零開(kāi)始構(gòu)建一個(gè)完整的電商項(xiàng)目。內(nèi)容覆蓋電商項(xiàng)目的基本結(jié)構(gòu),以及Vue.js和Express的核心概念與架構(gòu);深入講解Vue.js開(kāi)發(fā)生態(tài)中的關(guān)鍵模塊,包括網(wǎng)絡(luò)請(qǐng)求、UI組件、路由管理和狀態(tài)管理等;探討Express框架的常用組件,如處理加密數(shù)據(jù)的中間件和與MySQL數(shù)據(jù)庫(kù)交互的插件;最后指導(dǎo)讀者打造一個(gè)完整的電商項(xiàng)目。在用戶(hù)端,實(shí)現(xiàn)注冊(cè)登錄、商品瀏覽、購(gòu)物車(chē)等功能;在服務(wù)端,完成用戶(hù)驗(yàn)證、商品維護(hù)、訂單處理等任務(wù);在后臺(tái)管理端,進(jìn)行商品信息、訂單數(shù)據(jù)等的管理與統(tǒng)計(jì)分析。通過(guò)閱讀《Vue.js 3.x+Express全棧開(kāi)發(fā) : 從0到1打造商城項(xiàng)目》,讀者能夠掌握Vue.js和Express全棧開(kāi)發(fā)技術(shù),并獨(dú)立完成電商項(xiàng)目的搭建與開(kāi)發(fā)。

          《Vue.js 3.x+Express全棧開(kāi)發(fā) : 從0到1打造商城項(xiàng)目》還提供了完整的項(xiàng)目源碼、代碼導(dǎo)讀手冊(cè)以及長(zhǎng)達(dá)30小時(shí)的教學(xué)視頻,可大幅提升學(xué)習(xí)效率。

          2

          本書(shū)作者

          張益琿,美國(guó)亞利桑那州立大學(xué)計(jì)算機(jī)工程技術(shù)碩士,架構(gòu)師,從業(yè)近10年,多年大前端開(kāi)發(fā)經(jīng)驗(yàn),曾就職于知名上市公司,主導(dǎo)開(kāi)發(fā)過(guò)多款商業(yè)級(jí)應(yīng)用程序,對(duì)移動(dòng)跨平臺(tái)開(kāi)發(fā)、前端開(kāi)發(fā),以及Vue.js 、React、Flutter、小程序與iOS開(kāi)發(fā)都擁有豐富經(jīng)驗(yàn)。開(kāi)源中國(guó)特邀技術(shù)專(zhuān)家,發(fā)表相關(guān)技術(shù)博文400余篇,訪問(wèn)量超過(guò)100萬(wàn)次。出版技術(shù)圖書(shū)《循序漸進(jìn)Vue.js 3.x前端開(kāi)發(fā)實(shí)戰(zhàn)》《微信小程序與云開(kāi)發(fā)從入門(mén)到實(shí)踐》《Swift 5從零到精通iOS開(kāi)發(fā)訓(xùn)練營(yíng)》等多部。

          3

          本書(shū)讀者

          《Vue.js 3.x+Express全棧開(kāi)發(fā) : 從0到1打造商城項(xiàng)目》采用實(shí)際商業(yè)項(xiàng)目作為教學(xué)案例,融入了多種前端框架和新技術(shù),非常適合缺乏項(xiàng)目經(jīng)驗(yàn)的學(xué)生和對(duì)全棧開(kāi)發(fā)感興趣的開(kāi)發(fā)者閱讀,也適合作為培訓(xùn)機(jī)構(gòu)和大中專(zhuān)院校相關(guān)專(zhuān)業(yè)的實(shí)踐課教學(xué)用書(shū)

          4

          本書(shū)目錄

          第1章 項(xiàng)目概覽與環(huán)境準(zhǔn)備 1

          1.1 項(xiàng)目概覽 1

          1.1.1 電商項(xiàng)目的功能構(gòu)成 2

          1.1.2 前端框架Vue.js及其周邊工具 3

          1.1.3 熟悉Node.js與Express 4

          1.1.4 從JavaScript到TypeScript 5

          1.2 腳手架工具的應(yīng)用 6

          1.2.1 安裝Node.js環(huán)境 6

          1.2.2 使用Vue.js腳手架工具Vite 7

          1.2.3 使用Express項(xiàng)目生成工具 9

          1.2.4 使用Visual Studio Code編程工具 11

          1.3 HelloWorld工程解析 13

          1.3.1 Vue.js工程解析 13

          1.3.2 Express工程解析 16

          1.4 小結(jié)與上機(jī)練習(xí) 22

          第2章 前端基礎(chǔ)模塊及應(yīng)用 24

          2.1 axios與vue-axios網(wǎng)絡(luò)請(qǐng)求模塊的應(yīng)用 25

          2.1.1 嘗試發(fā)起一個(gè)HTTP請(qǐng)求 25

          2.1.2 axios網(wǎng)絡(luò)模塊的更多用法 27

          2.2 Element Plus頁(yè)面UI組件模塊的應(yīng)用 30

          2.2.1 加載Element Plus模塊 30

          2.2.2 基礎(chǔ)UI組件 32

          2.2.3 典型的表單類(lèi)組件 34

          2.2.4 典型的數(shù)據(jù)展示類(lèi)組件 37

          2.2.5 常用的導(dǎo)航組件 40

          2.2.6 常用的用戶(hù)反饋類(lèi)組件 43

          2.3 Vue Router路由模塊的應(yīng)用 46

          2.3.1 Vue Router模塊的使用 46

          2.3.2 動(dòng)態(tài)路由與參數(shù)匹配 48

          2.3.3 路由的嵌套和命名 51

          2.3.4 路由中的導(dǎo)航守衛(wèi) 54

          2.4 Pinia狀態(tài)管理模塊的應(yīng)用 56

          2.4.1 嘗試使用Pinia 56

          2.4.2 Pinia中的幾個(gè)核心概念 59

          2.5 小結(jié)與上機(jī)練習(xí) 60

          第3章 后端服務(wù)基礎(chǔ)模塊及應(yīng)用 69

          3.1 文件上傳服務(wù) 70

          3.1.1 圖片上傳服務(wù)示例 70

          3.1.2 Multer中間件的更多用法 74

          3.2 在Express中使用MySQL數(shù)據(jù)庫(kù) 76

          3.2.1 MySQL數(shù)據(jù)庫(kù)的安裝和簡(jiǎn)單使用 76

          3.2.2 在Express中調(diào)用MySQL的相關(guān)功能 79

          3.3 使用JSON Web Token實(shí)現(xiàn)身份授權(quán)和驗(yàn)證 82

          3.3.1 JSON Web Token簡(jiǎn)介 82

          3.3.2 在Express中使用JWT 83

          3.4 使用bcrypt加密模塊實(shí)現(xiàn)商城安全 86

          3.5 小結(jié)與上機(jī)練習(xí) 89

          第4章 開(kāi)發(fā)用戶(hù)登錄和注冊(cè)模塊 96

          4.1 實(shí)現(xiàn)服務(wù)端的登錄和注冊(cè)模塊 96

          4.1.1 用戶(hù)數(shù)據(jù)表的定義 97

          4.1.2 封裝數(shù)據(jù)庫(kù)工具類(lèi)與實(shí)現(xiàn)登錄和注冊(cè)接口 98

          4.2 實(shí)現(xiàn)用戶(hù)端的登錄和注冊(cè)功能 107

          4.2.1 搭建用戶(hù)端工程 108

          4.2.2 開(kāi)發(fā)用戶(hù)端登錄和注冊(cè)頁(yè)面 110

          4.2.3 開(kāi)發(fā)用戶(hù)端賬戶(hù)數(shù)據(jù)邏輯 113

          4.2.4 開(kāi)發(fā)用戶(hù)端登錄和注冊(cè)接口邏輯 115

          4.3 實(shí)現(xiàn)后臺(tái)管理端的登錄和注冊(cè)功能 119

          4.4 小結(jié)與上機(jī)練習(xí) 121

          第5章 開(kāi)發(fā)營(yíng)銷(xiāo)推廣模塊 124

          5.1 實(shí)現(xiàn)服務(wù)端的運(yùn)營(yíng)推廣模塊 124

          5.1.1 定義運(yùn)營(yíng)位表結(jié)構(gòu)和接口文檔 125

          5.1.2 實(shí)現(xiàn)運(yùn)營(yíng)位圖片上傳接口 131

          5.1.3 實(shí)現(xiàn)用戶(hù)鑒權(quán)中間件 133

          5.1.4 實(shí)現(xiàn)運(yùn)營(yíng)位業(yè)務(wù)接口 136

          5.2 實(shí)現(xiàn)后臺(tái)管理端的運(yùn)營(yíng)位管理模塊 138

          5.2.1 搭建后臺(tái)管理系統(tǒng)首頁(yè) 138

          5.2.2 實(shí)現(xiàn)創(chuàng)建運(yùn)營(yíng)位組件 141

          5.2.3 實(shí)現(xiàn)運(yùn)營(yíng)位管理模塊 146

          5.3 實(shí)現(xiàn)用戶(hù)端的運(yùn)營(yíng)位模塊 149

          5.4 小結(jié)與上機(jī)練習(xí) 152

          第6章 開(kāi)發(fā)商品列表與詳情模塊 154

          6.1 開(kāi)發(fā)服務(wù)端的商品相關(guān)模塊 154

          6.1.1 商品類(lèi)別表的定義與接口實(shí)現(xiàn) 155

          6.1.2 商品表與相關(guān)接口的實(shí)現(xiàn) 158

          6.2 實(shí)現(xiàn)后臺(tái)管理端的商品管理模塊 167

          6.2.1 實(shí)現(xiàn)類(lèi)別管理功能 167

          6.2.2 實(shí)現(xiàn)商品編輯模塊 172

          6.2.3 實(shí)現(xiàn)商品管理模塊 180

          6.3 實(shí)現(xiàn)用戶(hù)端的商品模塊 183

          6.3.1 實(shí)現(xiàn)用戶(hù)端首頁(yè)商品推薦模塊 184

          6.3.2 實(shí)現(xiàn)用戶(hù)端的商品詳情頁(yè) 189

          6.4 小結(jié)與上機(jī)練習(xí) 193

          第7章 開(kāi)發(fā)購(gòu)物車(chē)與訂單模塊 194

          7.1 實(shí)現(xiàn)服務(wù)端的購(gòu)物車(chē)與訂單模塊 194

          7.1.1 購(gòu)物車(chē)表的定義與功能接口的實(shí)現(xiàn) 195

          7.1.2 訂單表的定義與接口分析 200

          7.1.3 實(shí)現(xiàn)訂單模塊后端接口 202

          7.2 實(shí)現(xiàn)用戶(hù)端的購(gòu)物車(chē)與訂單模塊 207

          7.2.1 實(shí)現(xiàn)購(gòu)物車(chē)功能 207

          7.2.2 實(shí)現(xiàn)訂單模塊 212

          7.3 實(shí)現(xiàn)后臺(tái)管理端的訂單管理模塊 217

          7.4 小結(jié)與上機(jī)練習(xí) 218

          第8章 開(kāi)發(fā)搜索與評(píng)價(jià)模塊 222

          8.1 實(shí)現(xiàn)服務(wù)端的搜索與評(píng)價(jià)模塊 222

          8.1.1 實(shí)現(xiàn)商品搜索接口 223

          8.1.2 評(píng)價(jià)數(shù)據(jù)結(jié)構(gòu)與接口定義 224

          8.1.3 實(shí)現(xiàn)評(píng)價(jià)相關(guān)接口 226

          8.2 實(shí)現(xiàn)用戶(hù)端的搜索與評(píng)價(jià)模塊 229

          8.2.1 實(shí)現(xiàn)搜索功能 230

          8.2.2 實(shí)現(xiàn)創(chuàng)建商品評(píng)價(jià)功能 233

          8.2.3 實(shí)現(xiàn)商品評(píng)價(jià)展示功能 237

          8.3 實(shí)現(xiàn)后臺(tái)管理端的評(píng)價(jià)模塊 239

          8.4 小結(jié)與上機(jī)練習(xí) 242

          第9章 數(shù)據(jù)統(tǒng)計(jì)模塊與項(xiàng)目總結(jié) 243

          9.1 實(shí)現(xiàn)電商后臺(tái)數(shù)據(jù)統(tǒng)計(jì)模塊 243

          9.1.1 數(shù)據(jù)統(tǒng)計(jì)功能的后端接口定義 244

          9.1.2 數(shù)據(jù)統(tǒng)計(jì)功能的后端服務(wù)接口實(shí)現(xiàn) 245

          9.1.3 后臺(tái)管理端的數(shù)據(jù)圖表繪制 250

          9.2 項(xiàng)目總結(jié) 254

          9.3 小結(jié)與上機(jī)練習(xí) 256


          5

          編輯推薦

          《Vue.js 3.x+Express全棧開(kāi)發(fā):從0到1打造商城項(xiàng)目》是一本實(shí)戰(zhàn)型教程,專(zhuān)注于使用最新的Vue.js 3.x和Express框架來(lái)構(gòu)建一個(gè)完整的電子商務(wù)平臺(tái)。以下是您可能需要這本書(shū)的原因:

          1全面而深入:《Vue.js 3.x+Express全棧開(kāi)發(fā):從0到1打造商城項(xiàng)目》首先介紹了Vue和Express的基本概念與框架結(jié)構(gòu),如Vue的組件化開(kāi)發(fā)、數(shù)據(jù)綁定以及Express的路由處理和中間件使用等,為您打下堅(jiān)實(shí)的基礎(chǔ)。

          2生態(tài)資源介紹:書(shū)中詳細(xì)講述了Vue和Express生態(tài)系統(tǒng)中的核心插件,讓您對(duì)UI搭建、網(wǎng)絡(luò)請(qǐng)求、路由管理、數(shù)據(jù)存儲(chǔ)與安全等方面有全面的了解。

          實(shí)戰(zhàn)項(xiàng)目經(jīng)驗(yàn):通過(guò)引導(dǎo)您搭建一個(gè)完整的電商項(xiàng)目,包括前端用戶(hù)功能和后端API服務(wù),幫助您獲得寶貴的實(shí)戰(zhàn)經(jīng)驗(yàn)。

          3功能完整:從用戶(hù)注冊(cè)登錄到商品展示、購(gòu)物車(chē)以及后臺(tái)的商品和訂單管理,這本書(shū)將指導(dǎo)您一步步實(shí)現(xiàn)一個(gè)功能完備的電商平臺(tái)。

          4學(xué)習(xí)資源豐富:《Vue.js 3.x+Express全棧開(kāi)發(fā):從0到1打造商城項(xiàng)目》提供了完整的項(xiàng)目源代碼、導(dǎo)讀手冊(cè)和配套視頻教程,極大地便利了您的學(xué)習(xí)和實(shí)踐,并加速理解過(guò)程。

          5適用讀者廣泛:無(wú)論是正在尋求項(xiàng)目經(jīng)驗(yàn)的開(kāi)發(fā)人員,還是希望通過(guò)實(shí)踐學(xué)習(xí)的在校學(xué)生,抑或是用作高校和培訓(xùn)機(jī)構(gòu)的實(shí)踐課教材,《Vue.js 3.x+Express全棧開(kāi)發(fā):從0到1打造商城項(xiàng)目》都是一個(gè)極佳的選擇。

          6這本書(shū)將幫助您掌握使用Vue和Express進(jìn)行全棧開(kāi)發(fā)的能力,更重要的是,在您完成閱讀和實(shí)踐后,能夠獨(dú)立負(fù)責(zé)電商項(xiàng)目的搭建和開(kāi)發(fā)。

          把握機(jī)遇,深化知識(shí),提升技能。相信《Vue.js 3.x+Express全棧開(kāi)發(fā):從0到1打造商城項(xiàng)目》將是您技術(shù)成長(zhǎng)道路上的一塊墊腳石。

          本文摘自《Vue.js 3.x+Express全棧開(kāi)發(fā):從0到1打造商城項(xiàng)目》,獲出版社和作者授權(quán)發(fā)布。


          主站蜘蛛池模板: 国产精品第一区第27页| 亚洲日韩国产一区二区三区 | 中文字幕无码不卡一区二区三区 | 消息称老熟妇乱视频一区二区| 人妻夜夜爽天天爽爽一区| 精品久久久久久无码中文字幕一区 | 视频一区视频二区制服丝袜| 成人国内精品久久久久一区| 国产人妖视频一区在线观看| 最新欧美精品一区二区三区 | 久久无码一区二区三区少妇 | 日韩人妻精品一区二区三区视频 | 暖暖免费高清日本一区二区三区| 国产成人无码一区二区在线观看| 国产一区二区三区手机在线观看| 亚洲丶国产丶欧美一区二区三区| 色国产精品一区在线观看| 日本不卡一区二区三区| 国产免费无码一区二区 | 欧洲精品码一区二区三区| 无码乱码av天堂一区二区| 精品午夜福利无人区乱码一区| 伊人精品视频一区二区三区| 国内国外日产一区二区| 国产午夜精品一区二区三区不卡| 国产观看精品一区二区三区| 一区二区三区中文字幕| 一区二区三区无码高清视频| 精品乱码一区内射人妻无码| 午夜无码视频一区二区三区| 亚洲国产一区二区三区| 国产伦精品一区二区三区视频金莲| 精品一区二区三区视频在线观看| av无码精品一区二区三区四区 | 国产麻豆精品一区二区三区v视界 国产美女精品一区二区三区 | 无码日韩AV一区二区三区| 国精产品999一区二区三区有限 | 无码人妻精品一区二区三区东京热 | 日本高清一区二区三区| 精品国产天堂综合一区在线| 亚洲第一区精品日韩在线播放|