基于dreamweaver軟件設計和開發一網站_基于 abp vNext 和 .NET Core 開發博客項目 Blazor 實戰系列(一)...

系列文章

  1. 使用 abp cli 搭建項目
  2. 給項目瘦身,讓它跑起來
  3. 完善與美化,Swagger登場
  4. 數據訪問和代碼優先
  5. 自定義倉儲之增刪改查
  6. 統一規范API,包裝返回模型
  7. 再說Swagger,分組、描述、小綠鎖
  8. 接入GitHub,用JWT保護你的API
  9. 異常處理和日志記錄
  10. 使用Redis緩存數據
  11. 集成Hangfire實現定時任務處理
  12. 用AutoMapper搞定對象映射
  13. 定時任務最佳實戰(一)
  14. 定時任務最佳實戰(二)
  15. 定時任務最佳實戰(三)
  16. 博客接口實戰篇(一)

  17. 博客接口實戰篇(二)

  18. 博客接口實戰篇(三)

  19. 博客接口實戰篇(四)

  20. 博客接口實戰篇(五)


前言

從今天開始將使用 Blazor 完成博客的前端開發,如果你不了解?Blazor?,建議你還是去微軟官網學習學習基礎知識。本篇不做普及,因為這是實戰系列,重點是完成項目開發。

還有,在開始 Blazor 實戰之前,建議動手完成之前的系列文章,這樣更有連貫性,不至于懵圈。

因為我也是第一次使用 Blazor 開發項目,所以無法保證代碼的最優性,如果有不對的地方,或者有更好的做法,歡迎大家指正,謝謝。

接下來,我將現學現做帶來一個完整的博客項目,來吧,Just do it 。

我這里選擇的是 Blazor WebAssembly,需要你有 .NET Core 3.1 的開發環境,并且你還要有 Visual Studio 2019 IDE。

給大家看看我的開發環境,終端工具是:Window Terminal ,配置一下用起來太爽了,五星強烈推薦。

eae5da14e0bb53f3f8f4b64bc86ec433.png

搭建

Blazor WebAssembly 是一個單頁應用框架,可用它通過 .NET 生成交互式客戶端 Web 應用。Blazor WebAssembly 使用開放的 Web 標準(沒有插件或代碼轉換),適用于移動瀏覽器等各種新式 Web 瀏覽器。...

不啰嗦了,直接開干吧,在項目中新建 Blazor Web 應用。

1adb9972780d942881c1dce72b027397.png

然后將項目設置為啟動項目,Ctrl+F5 運行一下看看,官網默認示例我這里也懶得說了,直接進入主題吧。

改造

我這里使用的UI還是我目前博客的樣式,你可以選擇任意你喜歡的UI界面,這部分就隨意了,不是本實戰系列的重點,所以有關樣式這些東西我就直接 Ctrl CV 了。

替換下面css代碼到 wwwroot/css/app.css 中。

*,*:after,*:before {  -webkit-box-sizing: border-box;  -moz-box-sizing: border-box;  box-sizing: border-box;}html {  line-height: 1.15;  -webkit-text-size-adjust: 100%;}body {  margin: 0;}h1 {  font-size: 2em;  margin: 0.67em 0;}hr {  box-sizing: content-box;  height: 0;  overflow: visible;}pre {  font-family: monospace, monospace;  font-size: 1em;}a {  background-color: transparent;}abbr[title] {  border-bottom: none;  text-decoration: underline;  text-decoration: underline dotted;}b,strong {  font-weight: bolder;}code,kbd,samp {  font-family: monospace, monospace;  font-size: 1em;}small {  font-size: 80%;}sub,sup {  font-size: 75%;  line-height: 0;  position: relative;  vertical-align: baseline;}sub {  bottom: -0.25em;}sup {  top: -0.5em;}img {  border-style: none;}button,input,optgroup,select,textarea {  font-family: inherit;  font-size: 100%;  line-height: 1.15;  margin: 0;}button,input {  overflow: visible;}button,select {  text-transform: none;}button,[type="button"],[type="reset"],[type="submit"] {  -webkit-appearance: button;}button::-moz-focus-inner,    [type="button"]::-moz-focus-inner,    [type="reset"]::-moz-focus-inner,    [type="submit"]::-moz-focus-inner {  border-style: none;  padding: 0;}button:-moz-focusring,    [type="button"]-moz-focusring,    [type="reset"]-moz-focusring,    [type="submit"]-moz-focusring {  outline: 1px dotted ButtonText;}fieldset {  padding: 0.35em 0.75em 0.625em;}legend {  box-sizing: border-box;  color: inherit;  display: table;  max-width: 100%;  padding: 0;  white-space: normal;}progress {  vertical-align: baseline;}textarea {  overflow: auto;}[type="checkbox"],[type="radio"] {  box-sizing: border-box;  padding: 0;}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button {  height: auto;}[type="search"] {  -webkit-appearance: textfield;  outline-offset: -2px;}    [type="search"]::-webkit-search-decoration {  -webkit-appearance: none;}::-webkit-file-upload-button {  -webkit-appearance: button;  font: inherit;}details {  display: block;}summary {  display: list-item;}template {  display: none;}[hidden] {  display: none;}@font-face {  font-family: 'Fira Code Medium';    src: url('https://static.meowv.com/fonts/FiraCode-Medium.woff2') format('woff2'), url("https://static.meowv.com/fonts/FiraCode-Medium.woff") format("woff");    font-weight: 500;    font-style: normal;}html {  font-family: 'Fira Code Medium', Microsoft Yahei, monospace;  overflow-x: hidden;}html::-webkit-scrollbar {  width: 5px;  height: 5px;}html::-webkit-scrollbar-thumb {  height: 20px;  background-color: #5A9600;}html::-webkit-scrollbar-thumb:hover {  background-color: #5A9600;}body {  font-size: 11pt;  font-weight: normal;  line-height: 2em;  background-color: #fff;  color: #161209;  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, opacity 0.2s ease;}body:before {  content: "";  background-repeat: no-repeat;  background-position: center;  opacity: 0.05;  position: fixed;  top: 0;  left: 0;  width: 100%;  height: 100%;  z-index: -1;}body.dark-theme {  background-color: #292a2d;  color: #a9a9b3;  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, opacity 0.2s ease;}a {  color: #161209;  text-decoration: none;  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, opacity 0.2s ease;  cursor: pointer;}a:hover {  color: #5A9600;  text-decoration: none;  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, opacity 0.2s ease;}.dark-theme a {  color: #a9a9b3;  text-decoration: none;  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, opacity 0.2s ease;}.dark-theme a:hover {  color: #fff;  text-decoration: none;  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, opacity 0.2s ease;}.wrapper {  display: flex;  flex-direction: column;  min-height: 100vh;  width: 100%;}.navbar {  height: 4rem;  line-height: 4rem;  width: 100%;}.navbar .container {  width: auto;  max-width: 1200px;  text-align: center;  margin: 0 auto;  display: flex;  justify-content: space-between;}.main {  flex-grow: 1;  flex-shrink: 0;  flex-basis: auto;}.container {  padding-left: 1em;  padding-right: 1em;}.footer {  width: 100%;  text-align: center;}/*input css begin*/* {  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);}input[type="checkbox"],input[type="radio"] {  display: none;  width: 0;  height: 0;  visibility: hidden;}input[type="checkbox"]:checked + label:after {  transition: all 0.3s ease-in;}input[type="checkbox"]:not(:checked) + label:after {  transition: all 0.3s ease-out;}input[type="checkbox"]:checked + label,    input[type="checkbox"]:not(:checked) + label {  transition: all 0.3s ease-in-out;}input[type="checkbox"]:checked + label:before,        input[type="checkbox"]:checked + label i:before,        input[type="checkbox"]:not(:checked) + label i:before,        input[type="checkbox"]:checked + label i:after,        input[type="checkbox"]:not(:checked) + label i:after,        input[type="checkbox"]:not(:checked) + label:before {  transition: all 0.3s ease-in-out;}input[type="radio"]:checked + label:after,    input[type="radio"]:not(:checked) + label:after {  transition: all 0.3s ease-in-out;}.switch_default + label {  background-color: #e6e6e6;  border-radius: 7px;  cursor: pointer;  display: inline-block;  height: 14px;  position: relative;  box-shadow: 0.2px 0.2px 1px 0.5px rgb(180, 180, 180);  width: 30px;}.switch_default + label:after {  background-color: #fff;  border-radius: 50%;  content: "";  height: 12px;  left: 1px;  position: absolute;  top: .5px;  width: 12px;  box-shadow: 0.2px 0.2px 1px 0.5px rgb(180, 180, 180);}.switch_default:checked + label {  background-color: #1ABC9C;  box-shadow: none;}.switch_default:checked + label:after {  left: 17px;}@font-face {  font-family: "iconfont";    src: url('//at.alicdn.com/t/font_1313145_r9szngeugmj.eot?t=1566619028667'); /* IE9 */    src: url('//at.alicdn.com/t/font_1313145_r9szngeugmj.eot?t=1566619028667#iefix') format('embedded-opentype'), /* IE6-IE8 */    url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), url('//at.alicdn.com/t/font_1313145_r9szngeugmj.woff?t=1566619028667') format('woff'), url('//at.alicdn.com/t/font_1313145_r9szngeugmj.ttf?t=1566619028667') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */    url('//at.alicdn.com/t/font_1313145_r9szngeugmj.svg?t=1566619028667#iconfont') format('svg'); /* iOS 4.1- */}.iconfont {  font-family: "iconfont" !important;  font-size: 16px;  font-style: normal;  -webkit-font-smoothing: antialiased;  -moz-osx-font-smoothing: grayscale;}.iconread:before {  content: "\e742";}.iconweixin:before {  content: "\e632";}.iconmanage:before {  content: "\e610";}.iconapi:before {  content: "\e668";}.iconcode:before {  content: "\e654";}.icongithub:before {  content: "\ea0a";}.iconnotes:before {  content: "\e687";}.header-logo a {  padding: 0;}.navbar .menu a {  padding: 0 8px;}.navbar .menu .active {  font-weight: 900;  color: #161209;}.dark-theme .navbar .menu .active {  color: #fff;}.navbar-header a:hover,.navbar .menu a:hover {  background-color: transparent;}header label {  margin-left: 15px;  position: relative;  -webkit-transform: translateY(0.1em) translateX(0.5em);}.copyright {  font-size: 14px;}.pagination {  display: flex;  flex-direction: row;  justify-content: center;  list-style: none;  white-space: nowrap;  width: 100%;  padding-top: 2em;}.pagination a,    .pagination span {  -webkit-font-smoothing: antialiased;  font-size: 12px;  color: #bfbfbf;  letter-spacing: 0.1em;  font-weight: 700;  padding: 5px 5px;  text-decoration: none;  transition: 0.3s;}.pagination .page-number {  padding-bottom: 3px;  margin: 0 20px;  box-sizing: border-box;  position: relative;  display: inline;}.pagination .page-number.disabled {  display: none;}.pagination .page-number:hover a {  color: #000;}.dark-theme .pagination .page-number:hover a {  color: #fff;}.pagination .page-number:before,.pagination .page-number:after {  position: absolute;  content: "";  width: 0;  height: 1px;  background: #000;  transition: 0.3s;  bottom: 0px;}.dark-theme .pagination .page-number:before,.dark-theme .pagination .page-number:after {  background: #fff;}.pagination .page-number:before .current,.pagination .page-number:after .current {  width: 100%;}.pagination .page-number:before {  left: 50%;}.pagination .page-number:after {  right: 50%;}.pagination .page-number:hover:before,.pagination .page-number:hover:after {  width: 50%;}.pagination .page-number.current {  color: #000;}.dark-theme .pagination .page-number.current {  color: #fff;}.pagination .page-number.current:before,.pagination .page-number.current:after {  width: 60%;}.intro {  transform: translateY(20vh);  text-align: center;}.intro .avatar {  padding: 10px;}.intro .avatar img {  width: 128px;  height: auto;  display: inline-block;  -webkit-border-radius: 100%;  border-radius: 100%;  -webkit-box-shadow: 0 0 0 0.3618em rgba(0, 0, 0, 0.05);  box-shadow: 0 0 0 0.3618em rgba(0, 0, 0, 0.05);  margin: 0 auto;  -webkit-transition: all ease 0.4s;  -moz-transition: all ease 0.4s;  -o-transition: all ease 0.4s;  transition: all ease 0.4s;  cursor: pointer;}.intro .avatar img:hover {  position: relative;  -webkit-transform: translateY(-0.75em);  -moz-transform: translateY(-0.75em);  -ms-transform: translateY(-0.75em);  -o-transform: translateY(-0.75em);  transform: translateY(-0.75em);  cursor: pointer;}.nickname {  font-size: 2em;  font-weight: normal;}.links a {  padding: 0 5px;}.links a:hover {  background-color: transparent;}.links .iconfont {  font-size: 2em;}.post-wrap {  position: relative;  width: 100%;  max-width: 1024px;  margin: 0 auto;  padding-top: 2rem;}.archive-item-date {  float: right;  text-align: right;  color: #a9a9b3;}.dark-theme .archive-item-date {  color: #87878d;}.post-wrap .categories-card {  margin: 0 auto;  margin-top: 1em;  display: flex;  align-items: center;  justify-content: space-between;  flex-direction: row;  flex-wrap: wrap;  padding: 0 2.5em;  line-height: 1.6em;}.post-wrap .categories-card .card-item {  font-size: 14px;  text-align: left;  width: 50%;  display: flex;  align-items: flex-start;  position: relative;}.post-wrap .categories-card .card-item .categories {  overflow: hidden;}.categories h3 {  display: inline-block;}.categories span {  float: right;  padding-right: 1em;}.categories .more-post-link {  float: right;}.tag-cloud-tags {  margin: 10px 0;  padding-top: 2em;}.tag-cloud-tags a {  display: inline-block;  position: relative;  margin: 5px 10px;  word-wrap: break-word;  transition-duration: 0.3s;  transition-property: transform;  transition-timing-function: ease-out;}.tag-cloud-tags a:active,        .tag-cloud-tags a:focus,        .tag-cloud-tags a:hover {  color: #5A9600;  transform: scale(1.1);}.dark-theme .tag-cloud-tags a:active,.dark-theme .tag-cloud-tags a:focus,.dark-theme .tag-cloud-tags a:hover {  color: #fff;}.tag-cloud-tags a small {  margin: 0 0.3em;  color: #a9a9b3;}.dark-theme .tag-cloud-tags a small {  color: #fff;}.page {  padding-top: 0;}.page .post-content {  margin: 0;  padding-top: 0;}.post-wrap p {  font-size: 1em;  margin: 0.5em 0 0.5em 0;}.post-wrap .post-header h1 {  margin: 0 !important;}.post-wrap .post-title {  font-size: 2em;  line-height: 1.5em;}.post-wrap .eror-tip {  text-align: center;  line-height: 1.5em;  margin-top: 250px;}.post-wrap .post-meta {  color: rgba(85, 85, 85, 0.529) !important;}.dark-theme .post-wrap .post-meta {  color: #87878d !important;}.post-wrap .post-meta a {  color: #000;}.dark-theme .post-wrap .post-meta a {  color: #eee;}.post-wrap .post-meta a:hover {  color: #5A9600;}.dark-theme .post-wrap .post-meta a:hover {  color: #fff;}.post-content {  padding-top: 2rem;  text-align: justify;}.post-copyright {  margin-top: 5rem;  border-top: 1px solid #e8e8e8;  border-bottom: 1px solid #e8e8e8;}.post-copyright a {  color: #000;}.dark-theme .post-copyright a {  color: #eee;}.post-copyright a:hover {  color: #5A9600;}.dark-theme .post-copyright a:hover {  color: #fff;}.post-copyright .copyright-item {  margin: 5px 0;}.post-copyright .lincese {  font-weight: bold;}.dark-theme .post-copyright {  border-top: 1px solid #909196;  border-bottom: 1px solid #909196;}.post-tags {  padding: 1rem 0 1rem;  display: flex;  justify-content: space-between;}.post-nav:before,.post-nav:after {  content: " ";  display: table;}.post-nav a.prev,.post-nav a.next {  font-weight: 600;  font-size: 16px;  transition-property: transform;  transition-timing-function: ease-out;  transition-duration: 0.3s;}.post-nav a.prev {  float: left;}.post-nav a.prev::before {  content: ";  margin-right: 0.5em;}.post-nav a.prev:hover {  transform: translateX(-4px);}.post-nav a.next {  float: right;}.post-nav a.next::after {  content: ">";  margin-left: 0.5em;}.post-nav a.next:hover {  transform: translateX(4px);}.post-nav a.prev::before,    .post-nav a.next::after {  font-weight: bold;}.tag:not(:last-child) a::after {  content: " / ";}@media only screen and (min-device-width: 320px) and (max-device-width: 1024px) {  .main {    padding-top: 40pt;  }  .navbar {    display: none;  }  .navbar-mobile {    display: block !important;    position: fixed;    width: 100%;    z-index: 100;    transition: all 0.6s ease 0s;  }  .navbar-mobile .container {    padding: 0;    margin: 0;    line-height: 5.5em;    background: #fff;  }  .navbar-mobile .container .navbar-header {    display: flex;    justify-content: space-between;    align-items: center;    width: 100%;    padding-right: 1em;    padding-left: 1em;    box-sizing: border-box;    position: relative;  }  .navbar-mobile .container .navbar-header .menu-toggle {    cursor: pointer;    line-height: 5.5em;    padding: auto 2em;  }  .navbar-mobile .container .navbar-header .menu-toggle span {    display: block;    background: #000;    width: 36px;    height: 2px;    -webkit-border-radius: 3px;    -moz-border-radius: 3px;    border-radius: 3px;    -webkit-transition: 0.25s margin 0.25s, 0.25s transform;    -moz-transition: 0.25s margin 0.25s, 0.25s transform;    transition: 0.25s margin 0.25s, 0.25s transform;  }  .dark-theme .navbar-mobile .container .navbar-header .menu-toggle span {    background: #a9a9b3;  }  .navbar-mobile .container .navbar-header .menu-toggle span:nth-child(1) {    margin-bottom: 8px;  }  .navbar-mobile .container .navbar-header .menu-toggle span:nth-child(3) {    margin-top: 8px;  }  .navbar-mobile .container .navbar-header .menu-toggle.active span {    -webkit-transition: 0.25s margin, 0.25s transform 0.25s;    -moz-transition: 0.25s margin, 0.25s transform 0.25s;    transition: 0.25s margin, 0.25s transform 0.25s;  }  .navbar-mobile .container .navbar-header .menu-toggle.active span:nth-child(1) {    -moz-transform: rotate(45deg) translate(4px, 6px);    -ms-transform: rotate(45deg) translate(4px, 6px);    -webkit-transform: rotate(45deg) translate(4px, 6px);    transform: rotate(45deg) translate(4px, 6px);  }  .navbar-mobile .container .navbar-header .menu-toggle.active span:nth-child(2) {    opacity: 0;  }  .navbar-mobile .container .navbar-header .menu-toggle.active span:nth-child(3) {    -moz-transform: rotate(-45deg) translate(8px, -10px);    -ms-transform: rotate(-45deg) translate(8px, -10px);    -webkit-transform: rotate(-45deg) translate(8px, -10px);    transform: rotate(-45deg) translate(8px, -10px);  }  .navbar-mobile .container .menu {    text-align: center;    background: #fff;        /*border-top: 1px solid #000;*/    padding-top: 1em;    padding-bottom: 1em;    display: none;    box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1), 0px 4px 8px rgba(0, 0, 0, 0.1);  }  .navbar-mobile .container .menu a {    display: inline-block;    margin: 0 1em;    line-height: 2.5em;  }  .navbar-mobile .container .menu.active {    display: block;    white-space: nowrap;    box-sizing: border-box;    overflow-x: auto;  }  .dark-theme .navbar-mobile .container .menu {    background: #292a2d;        /*border-top: 1px solid #87878d;*/  }  .dark-theme .navbar-mobile .container {    background: #292a2d !important;  }  .archive {    width: 90%;  }  .archive .archive-item .archive-item-date {    display: none;  }  #dynamic-to-top {    display: none !important;  }  .footer {    height: 3rem;    width: 100%;    text-align: center;    line-height: 1.5rem;    padding-top: 2em;  }  .post-warp {    padding-top: 6em;  }  .post-warp .archive-item-date {    display: none;  }  .categories .categories-card .card-item {    width: 100%;    display: flex;    min-height: 0;  }  .categories .categories-card .card-item .categories {    overflow: hidden;  }  .signature-img {    width: 100%;  }  .signature-box img {    height: 100px !important;  }  .signature-img img {    height: 100px;  }  .signature-action, .vip-action {    width: 100%;  }  .signature-action select, .vip-action select {    width: 100%;  }  .signature-action input, .vip-action input {    width: 200px;    float: left;    margin-top: 5px;  }  .signature-action button, .vip-action button {    width: 200px;    margin-top: 5px;  }  .mta-box {    width: 100% !important;  }  .mta-a ul li {    width: 100% !important;  }  .navbar-mobile {    display: none;  }}@media only screen and (min-device-width: 768px) {  .navbar-mobile {    display: none;  }}@media only screen and (min-width: 1024px) {  .navbar-mobile {    display: none;  }}.loader {  box-sizing: content-box;  display: block;  position: absolute;  top: 50%;  left: 50%;  margin: 0;  text-align: center;  z-index: 1000;  -webkit-transform: translateX(-50%) translateY(-50%);  transform: translateX(-50%) translateY(-50%);}.loader:before {  position: absolute;  content: '';  top: 0;  left: 50%;  width: 50px;  height: 50px;  margin: 0 0 0 -25px;  border-radius: 50px;  border: 4px solid rgba(0, 0, 0, .1);}.loader:after {  position: absolute;  content: '';  top: 0;  left: 50%;  width: 50px;  height: 50px;  margin: 0 0 0 -25px;  animation: loader .6s linear;  animation-iteration-count: infinite;  border-radius: 50px;  border: 4px solid transparent;  border-top-color: #767676;  box-shadow: 0 0 0 1px transparent;}@keyframes loader {  from {    -webkit-transform: rotate(0deg);    transform: rotate(0deg);  }  to {    -webkit-transform: rotate(360deg);    transform: rotate(360deg);  }}.dark-theme .post-content {  background: #292a2d !important;  color: #eee !important;}.dark-theme .post-content p code, .dark-theme .post-content ul li code {  background: #292a2d !important;}.apps {  color: red;  font-weight: bold;}.signature-box {  margin-top: 100px;  text-align: center;}.signature-box img {  border: none;  height: 145px;  margin-bottom: 50px;}.signature-action select, .vip-action select {  height: 30px;}.signature-action input, .vip-action input {  height: 25px;  padding-left: 5px;}.signature-action input:focus, .vip-action input:focus {  outline: none;}.signature-action button, .vip-action button {  width: 135px;  height: 30px;}.tag-cloud-tags-extend {  padding-top: 0;}.hidden {  display: none;}.vip-action {  text-align: center;}.imgbox {  width: 70%;  text-align: center;  margin: 80px auto 0;}.imgbox img {  max-width: 100%;  max-height: 100%;}.girl-qrcode {  text-align: center;}.girl-img {  width: 20%;}.btnbox {  text-align: center;  margin-top: 20px;}.tab-box {  margin: 0 auto;  margin-top: 50px;  width: 1150px;}.top-tab {  font-weight: bold;  float: left;  margin-top: 5px;}.top-tab ul li {  list-style: none;}.top-tab ul li a.archive {  color: #5A9600;}.top-content {  float: left;}.top-content ul li {  list-style: none;  height: 35px;  line-height: 35px;  width: 888px;  overflow: hidden;  text-overflow: ellipsis;  white-space: nowrap;}.mta-box {  width: 75%;  margin: 100px auto 0;}.mta-a {  margin: 20px 68px 50px 20px;}.mta-a ul {  width: auto;  display: none;}.mta-a ul li {  float: left;  width: 25%;  list-style: none;}.mta-a-item {  margin: 0 10px;  border: 1px solid #e1e1e1;  background: #fff;  min-height: 60px;}.mta-a-title {  padding: 16px 16px 0;  height: 20px;  line-height: 20px;}.mta-a-value {  height: 100%;  font-size: 30px;  height: 24px;  margin: 20px 0 20px 30px;}.mta-date {  text-align: right;  padding-right: 5px;}.dark-theme .mta-a-item {  border: 1px solid #a9a9b3;  background: transparent;}.qrcode {  width: 120px;  z-index: 99999;  opacity: 0.8;  margin: 20px auto 0;}.qrcode img {  width: 100%;}.soul {  text-align: center;  margin-top: 200px;}.soul-btn {  background-color: #5a9600;  border: 5px;  color: white;  padding: 15px 32px;  text-align: center;  text-decoration: none;  display: inline-block;  font-size: 16px;  margin: 4px 2px;  cursor: pointer;  -webkit-transition-duration: 0.4s;  transition-duration: 0.4s;}.soul-btn:hover {  box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);}

在css中用到了開源的 FiraCode 字體,可以自己去下載,不過在css中我已經改為遠程地址了。

刪掉 wwwroot/sample-data、wwwroot/css/bootstrap、wwwroot/css/open-iconic 三個文件夾。

在wwwroot文件夾下,有一個index.html,這個是我們網站的入口,注意里面有一對標簽:Loading...,這個標簽里面的內容會在 wasm 加載完畢后自動清除掉,所以,一般可以用來做加載提示。

現在改造一下index.html,代碼如下:

<html><head>    <meta charset="utf-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />    <meta name="keywords" content="Meowv,qix,阿星Plus,個人博客">    <meta name="description" content="阿星Plus的個人博客,用于發表原創文章,關注微信公眾號:『阿星Plus』了解更多。">    <title>?阿星Plus???title>    <base href="/" />    <link href="css/app.css" rel="stylesheet" />head><body>    <app>        <div class="loader">div>    app>    <script src="_framework/blazor.webassembly.js">script>body>html>

千萬注意,blazor.webassembly.js?這個js不可以刪除,會在項目打包后自動生成這個js文件。

然后我們一點一點完善,Program.cs默認就行暫時不需要做任何改動。

Pages文件夾內的Razor組件就是我們的具體頁面了,干掉默認的Counter.razorFetchData.razor,留下Index.razor,當作我們的首頁。

Shared文件夾內可以放一些共享的組件,比如我們的模板MainLayout.razor就在里面,它需要繼承LayoutComponentBase

所以現在可以來修改一下我們的模板內容。

以我博客的UI架構而言,博客分為了三個部分,頭部、尾部、內容。

@inherits LayoutComponentBase
class="wrapper"> <Header /> @Body <Footer />div>

@Body為固定語法,表示這里是內容部分,其他的不變,只在這里填充內容。

在Shared文件夾中添加兩個組件,頭部:Header.razor、尾部:Footer.razor

Header.razor的內容如下:

<header>    <nav class="navbar">        <div class="container">            <div class="navbar-header header-logo">                <NavLink class="menu-item" href="/" Match="NavLinkMatch.All">                    ?阿星Plus                NavLink>            div>            <div class="menu navbar-right">                <NavLink class="menu-item" href="posts">PostsNavLink>                <NavLink class="menu-item" href="categories">CategoriesNavLink>                <NavLink class="menu-item" href="tags">TagsNavLink>                <NavLink class="menu-item apps" href="apps">AppsNavLink>                <input id="switch_default" type="checkbox" class="switch_default" />                <label for="switch_default" class="toggleBtn">label>            div>        div>    nav>    <nav class="navbar-mobile">        <div class="container">            <div class="navbar-header">                <div>                    <NavLink class="menu-item" href="" Match="NavLinkMatch.All">?阿星PlusNavLink>                    <NavLink > · LightNavLink>                div>                <div class="menu-toggle">? Menudiv>            div>            <div class="menu">                <NavLink class="menu-item" href="posts">PostsNavLink>                <NavLink class="menu-item" href="categories">CategoriesNavLink>                <NavLink class="menu-item" href="tags">TagsNavLink>                <NavLink class="menu-item apps" href="apps">AppsNavLink>            div>        div>    nav>header>

可以看到有很多的NavLink組件,這是我將a標簽轉換后的內容,其實最終生成的也是我們熟悉的a標簽,不過他自然有獨特用處,看介紹:

創建導航鏈接時,請使用 NavLink 組件代替 HTML 超鏈接元素?()。NavLink 組件的行為方式類似于??元素,但它根據其 href 是否與當前 URL 匹配來切換 active CSS 類。active 類可幫助用戶了解所顯示導航鏈接中的哪個頁面是活動頁面。...

Footer.razor的內容如下:

<footer id="footer" class="footer">    <div class="copyright">        <span>            Powered by <a target="_blank" href="http://dot.net">.NET Core 3.1a> and <a href="http://blazor.net/">Blazora> on Linux        span>    div>footer>

然后刪掉默認的多余的組件:NavMenu.razorSurveyPrompt.razor

還有一個_Imports.razor,這個就是用來導入命名空間的,放在這里面就相當于全局引用了。

現在去編輯我們的首頁Index.razor

@page "/"<div class="main">    <div class="container">        <div class="intro">            <div class="avatar">                <a href="javascript:;"><img src="https://static.meowv.com/images/avatar.jpg">a>            div>            <div class="nickname">阿星Plusdiv>            <div class="description">                <p>                    生命不息,奮斗不止                    <br>Cease to struggle and you cease to live                p>            div>            <div class="links">                <NavLink class="link-item" title="Posts" href="posts">                    <i class="iconfont iconread">i>                NavLink>                <NavLink target="_blank" class="link-item" title="Notes" href="https://notes.meowv.com/">                    <i class="iconfont iconnotes">i>                NavLink>                <NavLink target="_blank" class="link-item" title="API" href="https://api.meowv.com/">                    <i class="iconfont iconapi">i>                NavLink>                <NavLink class="link-item" title="Manage" href="/account/auth">                    <i class="iconfont iconcode">i>                NavLink>                <NavLink target="_blank" class="link-item" title="Github" href="https://github.com/Meowv/">                    <i class="iconfont icongithub">i>                NavLink>                <NavLink class="link-item weixin" title="掃碼關注微信公眾號:『阿星Plus』查看更多。">                    <i class="iconfont iconweixin">i>                NavLink>                <div class="qrcode">                    <img src="https://static.meowv.com/images/wx_qrcode.jpg" />                div>            div>        div>    div>div>

@page指令用于設置頁面路由地址,因為是首頁,所以直接給一個"/"就可以了。

至此項目算是搭建完成并且將其改造了一番,現在可以去運行一下看看效果了。

6576f9109242b881cd48e0a884323ab9.png

第一次打開或者強制刷新頁面會出現加載中的界面,我這里就是一個小圈圈在那里轉,當加載完畢后就會自動消失,什么都不需要干,太方便了。

現在已經成功將首頁的顯示搞定了,隨便點擊幾個按鈕試試,會輸出一個錯誤提示:Sorry, there's nothing at this address,因為沒有找到這些路由,所以就...

默認的有點丑,并且這句提示當然也可以自定義的,現在來看最后的一個組件App.razor

<Router AppAssembly="@typeof(Program).Assembly">    <Found Context="routeData">        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />    Found>    <NotFound>        <LayoutView Layout="@typeof(MainLayout)">            <p>Sorry, there's nothing at this address.p>        LayoutView>    NotFound>Router>

通過語義化的代碼不難理解,Found就是找到與之匹配的路由,然后調用模板MainLayoutNotFound就是沒有找到的情況下,使用MainLayout并且在@body輸出一句提示。

將這句錯誤提示做成一個公共的組件并且美化一下,在Shared文件夾下新建組件:ErrorTip.razor,內容如下:

class="main"> <div class="post-wrap"> <h2 class="eror-tip">Sorry, there's nothing at this address.???h2> div></div>

使用組件也很簡單,在App.razor中刪掉默認的p標簽然后調用ErrorTip

...    <NotFound>        <LayoutView Layout="@typeof(MainLayout)">            <ErrorTip />        LayoutView>    NotFound>...

再看一下打開了不存在路由的頁面的錯誤提示吧。

6068c7186f74438fbe7c002d1fbfb4b5.png

哈哈哈,是不是好看許多,接下來會完成主題切換,菜單展開關閉等等功能,其實這些可以用JavaScript很方便的實現,但是既然用了 Blazor 開發,所以還是用 .NET 代碼實現吧。

本篇就先到這里,未完待續...

開源地址:https://github.com/Meowv/Blog/tree/blog_tutorial

b01a3e05f083505585c0c652aa9e966f.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455861.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455861.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455861.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS邊框,背景,邊距,溢出

CSS邊框,背景,邊距,溢出 css邊框屬性 border:寬度 樣式 顏色; border-color; border-style; 邊框樣式&#xff1a;solid實現&#xff0c;dotted點狀線&#xff0c;dashed虛線CSS3的樣式 border-radius&#xff1a;圓角處理 box-shadow: x軸偏移 y軸偏移 模糊度 擴散成都 顏色…

LINUX 內存使用情況

# free 顯示結果如下&#xff1a; Mem&#xff1a;表示物理內存統計 total 內存總數 8057964KBused 已使用的內存 7852484KBfree 空閑的內存數 205480KBshared 當前已經廢棄不用&#xff0c;總是0buffers Buffer 緩存內存數: 290432KBcached Page 緩存內存數:5735024KB(存在關…

vagrant系列教程(四):vagrant搭建redis與redis的監控程序redis-stat(轉)

閱讀目錄 下載redis解壓redis編譯安裝redis配置redisredis開機自啟動系統參數的調整上一篇php7環境的搭建 真是火爆&#xff0c;僅僅兩天時間&#xff0c;就破了我之前swagger系列的一片文章&#xff0c;看來&#xff0c;大家對搭建環境真是情有獨鐘。 為了訪問量&#xff0c;我…

sps及pps在解碼器內傳遞過程

首先解碼器中有一個全局變量seq_parameter_set_rbsp_t SeqParSet[MAXSPS];// MAXSPS32&#xff0c;它是一個指向序列參數集的數組。還有一個全局變量seq_parameter_set_rbsp_t *active_sps;主要為后續解碼所用。解碼器先將碼流中的數據讀入臨時指針sps&#xff0c;之后存入全局…

【技術分享】Ubuntu下使用微信教程

做后端開發的同學用的Linux&#xff08;ubuntu&#xff09;,肯定會因為沒有適配微信版本會感覺不太舒服&#xff0c;很多時候因為缺少一些辦公通訊軟件而感到不便。現在已經有很方便的Wine WeChat方案&#xff0c;但是微信在Wine上配置還有許多bug&#xff0c;今天在github上看…

python join函數_Python join()函數

原博文 2016-08-12 10:16 ? 今天寫python 100例時&#xff0c;有個題目是大致是這樣的&#xff1a;已知輸入形式是1321&#xff0c;要求輸出形式為1123 一開始思路是將輸入的字符串用split()函數劃分成數組&#xff0c;在對數組進行排序&#xff0c;再用for循環輸出 代碼附上&…

CSS中的盒子

盒子 盒子模型解釋元素在頁面中顯示成一個方塊&#xff0c;類似一個盒子&#xff0c;CSS盒子模型就是使用現實中盒子來做比喻&#xff0c;幫助我們設置元素對應的樣式。盒子模型示意圖如下&#xff1a; 把元素叫做盒子&#xff0c;設置對應的樣式分別為&#xff1a;盒子的邊框…

分享Kali Linux 2017年第17周鏡像文件

分享Kali Linux 2017年第17周鏡像文件 Kali Linux官方于4月23日發布2017年的第17周鏡像。這次維持了11個鏡像文件的規模。默認的Gnome桌面的4個鏡像&#xff0c;E17、KDE、LXDE、MATE、XFCE桌面的各一個&#xff0c;手機版的包括ARMEL和ARMHF。有最近要安裝Kali Linux系統的&am…

Djang重新整理migrations,解決:Django Table xxx already exist

在開發過程中&#xff0c;由于需求變更或者自我重構&#xff0c;需要清理migrations&#xff0c;以保持代碼整潔和后續的可維護性。 場景一 不考慮數據庫數據表&#xff0c;可以完全清空數據庫里面的表的數據。 步驟&#xff1a; 刪除所有migrations find . -path "/migr…

安全隨筆2:對稱加密應用場景

MD5或者說HASH值是一種不可逆的算法。如果需要從密文還原成明文&#xff0c;那么就需要對稱和非對稱這兩類可逆算法。 首先&#xff0c;簡單介紹下這兩類算法。圖9-1是對稱算法的示意圖&#xff1a; 圖9-1 對稱算法 在對稱算法中&#xff0c;首先需要發送方和接收方協定一個密鑰…

python安裝多久_python安裝與使用

1、進入官網下載python軟件 python-3.4.4.amd64.msi http://www.python.org/download/ 這個軟件包含三個環境&#xff0c;如下圖&#xff1a;2、雙擊安裝軟件 3、設置環境變量path";C:\Python34"; 4、驗證是否安裝成功 進入cmd中&#xff0c;輸入python,如果出現如下…

HADAMARD變換

for (j0;j<16;j) { for (i0;i<16;i) { M1[ i ][j]imgY_org[img->opix_yj][img->opix_xi]-img->mprr_2[k][j][ i ]; 計算當前宏塊殘差塊 M0[i%4][i/4][j%4][j/4]M1[ i ][j]; } } current_intra_sad_20; //…

CSS中的塊元素,內聯元素,內聯塊元素

塊元素,內聯元素,內聯塊元素 元素就是標簽&#xff0c;布局中常用的有三種標簽&#xff0c;塊元素、內聯元素、內聯塊元素&#xff0c;了解這三種元素的特性&#xff0c;才能熟練的進行頁面布局。 塊元素塊元素&#xff0c;也可以稱為行元素&#xff0c;布局中常用的標簽如&…

django 與 vue 的完美結合

最近接到一個任務&#xff0c;就是用django后端&#xff0c;前段用vue&#xff0c;做一個普通的簡單系統&#xff0c;我就是一搞后端的&#xff0c;聽到vue也是比較震驚&#xff0c;之前壓根沒接觸過vue。看了vue的一些文檔&#xff0c;還有一些項目&#xff0c;先說一下django…

東芝確定半導體重組計劃:保留閃存其他全賣

會計丑聞給日本東芝公司的業績帶來嚴重影響&#xff0c;為了提高盈利&#xff0c;東芝正在對旗下的半導體、個人電腦、白色家電等業務進行一次重大重組。據日經新聞1月23日報道&#xff0c;東芝已經正式制定了芯片業務重組的詳細計劃&#xff0c;除了占據優勢的閃存芯片之外&am…

python畫兩條曲線圖_python繪制多個曲線的折線圖

這篇文章利用的是matplotlib.pyplot.plot的工具來繪制折線圖&#xff0c;這里先給出一個段代碼和結果圖&#xff1a; # -*- coding: UTF-8 -*- import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt #這里導入你自己的數據 #...... #...... #x_axix&a…

5.19匯總

int block_x 8*(b8 & 0x01)4*(b4 & 0x01);int block_y 8*(b8 >> 1)4*(b4 >> 1);請問下老大 這兩句定義是什么意思啊&#xff1f; 帶些值進去算一下就知道了 b8 0 1 2 3b4 0 1 2 3 A&#xff1a;0 ........Er…

oracle 截取字指定的字符串

過濾指定的字符串,一字符串有重復的數據內容,所以需要去掉重復的內容,subst()截取 起止下標;instr()獲取終止下標位置 例如:substr(p.address, 0, instr(p.address, -, 1, 1)-1) ); case when length(substr(p.address, 0, instr(p.address, -, 1, 1)-1) ) 13 then substr(sub…

[django]django模型中auto_now和auto_now_add

示例: update_time models.DateTimeField(更新時間, defaulttimezone.now) create_time models.DateTimeField(創建時間, auto_now_addTrue) auto_now無論是你添加還是修改對象&#xff0c;時間為你添加或者修改的時間。 auto_now_add為添加時的時間&#xff0c;更新對象時不…

2014-7-29-阿里電面-第一輪

等了好久&#xff0c;以為簡歷要掛了&#xff0c;今天最終打來了。面試過程中手抖嘴抖有木有&#xff01; 1、經經常使用的集合類。我回到ArrayList、LinkedList、HashMap&#xff0c;接著問ArrayList、LinkedList的差別&#xff0c;以及分別的適用范圍。看了Java集合類基本上是…