2020-08-30 前端路上的新長征(Vuetify入門)

image.png

前端路上的新長征

  • 前言

從歷史的角度來說,盡管幾十年過去了,前端(即運行在瀏覽器里的程序)的基本結(jié)構(gòu)還是以HTML(CSS)+Javascript為主,變化不大,曾經(jīng)有一些腳本語言比如微軟的VBS試圖挑戰(zhàn)過這個架構(gòu),均以失敗告終(甚至連曇花一現(xiàn)都談不上)。后端(服務(wù)器)方面則是百花齊放,方案眾多,像是Java、PHP、GO、Python以及Javascript本身的一個分支Node.JS等等。

由于WEB技術(shù)的發(fā)展速度非??欤虼薍TML與Javascript也在高速迭代,于是產(chǎn)生了 “框架” 這個概念,所謂框架就是一堆前人已經(jīng)編寫好的成體系的代碼,其主要目的是不重復(fù)造輪子,加速開發(fā)效率。

前端框架大致上分為兩個大類,側(cè)重于HTML的CSS框架與側(cè)重于Javascript的JS框架。

主流的Javascript框架:React、Angular、Vue
主流的CSS框架:Bootstrap、Element、Vuetifylk

像React、Vue這一類框架關(guān)注點是Javascript本身,更多的是屬于處理邏輯層面的事務(wù)。而Bootstrap和Vuetify這一類CSS框架則著重關(guān)注HTML界面,頁面布局,排版等視覺方面的事情。

在沒有框架之前,所有前端開發(fā)者都采用原生HTML和原生Javascript,工作量極大。當(dāng)然,你如果問:我們一定需要框架嗎?答案卻是否定的,國外就確實有一股勢力是反對采用框架編程的,自詡為 "JS反框架聯(lián)盟",為了不引戰(zhàn),此話題咱們不做深入探討,見仁見智吧。

  • PS: 本文以Vue + Vuetify為基礎(chǔ)。

Vuetify 篇:

  • Vuetify 號稱是 Vue.js 的頭號組件庫,筆者使用過Bootstrap,因為年代久遠(yuǎn)已經(jīng)忘得差不多了,具體特點也不做評價。外賣雙雄之一的餓了嗎也搞了CSS庫,名字叫Element,感覺上手很容易,但限制比較多,UI的炫酷程度也比較一般。Vuetify 要比前兩者誕生的時間晚,但是它的可定制性很強,速度快,而且預(yù)設(shè)UI非常新潮,漂亮,值得嘗試!

由于Vuetify是專門提供給Vue使用的(從其名字也大概猜到了),所以在使用Vuetify之前我們還必須先安裝Vue。

  • 裝Vue之前還得先裝Node.JS

    Node.JS本質(zhì)上用于服務(wù)器后端,它將原本只能用在前端的Javascript變得可以運行在服務(wù)器后端,它對標(biāo)的是Java、PHP這一類東西。但此處安裝Node.js并不是要用到它的后端功能,主要是需要他的一個附屬工具:“npm” 包管理工具。

  • 回到Windows cmd命令行界面,開始準(zhǔn)備安裝vue-cli:

    • vue-cli是vue框架的“腳手架”,它的作用是快速為你搭建一個空的框架,然后立刻可以工作,省去了一大堆調(diào)試安裝的事情。當(dāng)然如果你不采用vue腳手架,用傳統(tǒng)的方式引用一個vue.js也是可以的。這樣做的優(yōu)點是更加簡潔高效,但是由于缺少npm包管理這個工具,調(diào)試和鏈接各種組件的難度將陡增,在此我還是建議從腳手架開始吧,等以后有閑了可以再去深入。

    • 輸入以下命令:

      npm install -g @vue/cli
      
    • vue-cli安裝好之后,vue命令就能使用了,用它創(chuàng)建一個項目,名稱隨意(此處為mini):

      vue create mini //創(chuàng)建mini項目
      cd mini
      vue add vuetify //添加vuetify組件
      
      
      • 項目將會自動創(chuàng)建完成,并且自動生成以下目錄結(jié)構(gòu):
image-20200830075007635.png
  • 問題是,如何運行一個vue程序? 很簡單,在cmd命令行輸入以下命令:

    npm run serve
    

一個最基礎(chǔ)的APP界面如下:

image-20200829024214407.png

如圖所示,這是一個最簡單的APP框架,包括

  • 兩個狀態(tài)欄:v-app-bar(頂部)、v-footer(底部)
  • 側(cè)邊功能導(dǎo)航欄:v-navigation-drawer
  • 主視圖區(qū):v-content

最基礎(chǔ)的主頁代碼,UI由<template>部分組成,JS代碼包裹在<script>里:

<template>
  <v-app id="inspire">
    <v-navigation-drawer
            v-model="drawer"
            app
            clipped>
<!--  vmodel: 顯示開關(guān),設(shè)為null的時候屏蔽導(dǎo)航欄 
         app : 是app = 'true'的簡化語法,表示這個導(dǎo)航欄屬于app的一部分
         clipped: 等于clipped = 'true',表示導(dǎo)航欄采用壓縮布局
-->
      <v-list dense>
        <v-list-item link>
          <v-list-item-action>
            <v-icon>mdi-home</v-icon>
          </v-list-item-action>

          <v-list-item-content>
            <v-list-item-title>選項1</v-list-item-title>
          </v-list-item-content>
        </v-list-item>

        <v-list-item link>
          <v-list-item-action>
            <v-icon>mdi-email</v-icon>
          </v-list-item-action>

          <v-list-item-content>
            <v-list-item-title>選項2</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>

    <v-app-bar
            app
            clipped-left
            color="cyan"
            dense
    >
      <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
      <v-toolbar-title>Application</v-toolbar-title>

    </v-app-bar>

    <v-main>
      <v-container
              class="fill-height"
              fluid
      >
      <h1>Hello World!</h1>
      </v-container>
    </v-main>

    <v-footer
            color="cyan"
            app
    >
      <v-spacer></v-spacer>

      <span class="white--text">&copy; {{ new Date().getFullYear() }}</span>
    </v-footer>
  </v-app>
</template>

<script>
  export default {
    name: 'SimpleDemo',
    props: {
      source: String,
    },
    data: () => ({
      drawer: null,
    }),
  }
</script>

上面是最簡單的基礎(chǔ)用法,接下來我們稍微復(fù)雜一點:
  1. 用數(shù)組的方法為導(dǎo)航欄(v-navigation-drawer) 添加連接
  2. 結(jié)合vue-router動態(tài)渲染主視圖區(qū)

  • 首先回到cmd命令行狀態(tài),輸入以下命令安裝vue-router:

    npm install vue-router
    
  • 然后在main.js里添加:

    import VueRouter from 'vue-router'
    Vue.use(VueRouter) //啟用vue-router插件
    import router from './router' //引入我們自己的路由定義表
    
    new Vue({
      vuetify:vuetify,
      router:router, //這行也可以簡寫為: router,
      render: function (h) { return h(App) }
    }).$mount('#app')
    
  • 在與main.js平級的目錄中創(chuàng)建一個router.js文件:

    import VueRouter from "vue-router";
    import hello from './components/hello'
    
    const originalPush = VueRouter.prototype.push;
    VueRouter.prototype.push = function push(location) {
        return originalPush.call(this, location).catch(err => err)
    } //以上三行是為了解決相同路由報錯的問題,不用深究,照原樣放在此就行了
    
    export default new VueRouter({
        mode: 'history',
        routes: [
            {path: '/', component: hello},
            {path: '/msg/:msg', name: 'sayhi', component: hello},
        ]
    }) 
    /*以上代碼創(chuàng)建了兩個路由,“/” 根路由和“/msg”
       大白話解釋根路由就是當(dāng)我們在瀏覽器地址欄什么參數(shù)都不帶,直接輸入網(wǎng)址比如qq.com,頁面應(yīng)該跳到哪,
       第二個路由/msg,就是說當(dāng)我們在網(wǎng)址后面加一個/msg,比如qq.com/msg,頁面應(yīng)該跳到哪,所謂路由就是這個意思。*/
    
  • 在 src/components 目錄中創(chuàng)建一個hello.vue文件:

    <template>
        <h1>Hello {{ $route.params.msg}}</h1>
      <!-- 此處的$route.params.msg表示從路由/msg傳遞過來的參數(shù) -->
    </template>
    
    <script>
        export default {
            name: 'hello',
    
            data: () => ({
    
            }),
        }
    /* 以上就是一個最簡單的vue組件,它由template和script兩部分組成,template部分表示HTML代碼,
    很簡單,就是顯示一個H1級別的文字:Hello + 路由傳過來的參數(shù),
    JS部分其實并沒有任何實質(zhì)性內(nèi)容,是一個空框架。 */
    </script>
    
    
  • 修改app.vue文件,清空舊的內(nèi)容,將以下內(nèi)容全部復(fù)制粘貼進(jìn)去:

    <template>
        <v-app id="inspire">
            <v-navigation-drawer
                    v-model="drawer"
                    app
                    clipped>
                <v-list dense>
                    <v-subheader class="mt-4 grey--text text--darken-1">操作選項</v-subheader>
                    <!-- v-subheader 是組的標(biāo)題 -->
                    <v-list-item
                            v-for="item in items"
                            :key="item.text"
                            @click="test(item.path)"
                            link>
                        <!-- v-for 是 vue的標(biāo)準(zhǔn)語法,item in items的 items 是一個數(shù)組,:key 表示唯一值 -->
                        <v-list-item-action>
                            <v-icon>{{ item.icon }}</v-icon>
                        </v-list-item-action>
                        <v-list-item-content>
                            <v-list-item-title>
                                {{ item.text }}
                            </v-list-item-title>
                        </v-list-item-content>
                        <!-- v-list-item-action 是選項圖標(biāo)
                             v-list-item-content 是選項的內(nèi)容區(qū)
                             v-list-item-title 是選項的文字
                        -->
                    </v-list-item>
                    <v-subheader class="mt-4 grey--text text--darken-1">用戶選項</v-subheader>
                    <v-list>
                        <v-list-item
                                v-for="item in items2"
                                :key="item.text"
                                @click="test(item.path)"
                                link>
                            <v-list-item-avatar>
                                <!-- https://randomuser.me 是一個隨機產(chǎn)生用戶頭像的趣味網(wǎng)站,此處從該網(wǎng)站獲取頭像圖片 -->
                                <img
                                        :src="`https://randomuser.me/api/portraits/men/${item.picture}.jpg`"
                                        alt="">
                            </v-list-item-avatar>
                            <v-list-item-title v-text="item.text"></v-list-item-title>
                        </v-list-item>
                    </v-list>
    
                  <!-- 以下兩個選項并沒有用到數(shù)組,一般用于一些非動態(tài)的固定欄目 -->
                  <v-list-item class="mt-4" link>
                      <v-list-item-action>
                          <v-icon color="grey darken-1">mdi-plus-circle-outline</v-icon>
                      </v-list-item-action>
                      <v-list-item-title class="grey--text text--darken-1">附加選項1</v-list-item-title>
                  </v-list-item>
    
                  <v-list-item link>
                      <v-list-item-action>
                          <v-icon color="grey darken-1">mdi-cog</v-icon>
                      </v-list-item-action>
                      <v-list-item-title class="grey--text text--darken-1">附加選項2</v-list-item-title>
                  </v-list-item>
    
    
              </v-list>
          </v-navigation-drawer>
    
          <!-- v-app-bar 是頂部欄,一般放一些操作類的按鈕、搜索功能等 -->
            <v-app-bar
                    app
                    clipped-left
                    color="cyan"
                    dense>
                <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
                <!-- 此處通過修改drawer變量來決定導(dǎo)航欄是否隱藏,PS:當(dāng)寬度被壓縮的時候?qū)Ш綑谧詣与[藏(比如手機) -->
                <v-toolbar-title>我的第一個APP</v-toolbar-title>
            </v-app-bar>
    
            <v-main> <!-- v-main是主試圖,一般指與用戶交互信息最頻繁的區(qū)域,尺寸也最大 -->
                <v-container
                        class="fill-height"
                        fluid>
                    <router-view></router-view>
                    <!-- router-view 是路由視圖,APP的所有點擊變化都在此反映,一般來說路由視圖約等于主視圖-->
                </v-container>
            </v-main>
    
            <v-footer color="cyan" app> <!-- v-footer是最底部的頁腳欄,一般用于放置版權(quán)信息之類雜項 -->
                <v-spacer></v-spacer>
                <span class="white--text">&copy; {{ new Date().getFullYear() }}</span>
            </v-footer>
        </v-app>
    </template>
    
    <script>
        export default {
            name: 'sayhi',
            props: {
                source: String,
            },
            data: () => ({
                drawer: null,
                items: [
                    {icon: 'mdi-trending-up', text: '世界', path: 'Wolrd'},
                    {icon: 'mdi-youtube-subscription', text: '太陽', path: 'Sun'},
                    {icon: 'mdi-history', text: '月亮', path: 'Moon'},
                    {icon: 'mdi-playlist-play', text: '星星', path: 'Star'},
                    {icon: 'mdi-clock', text: '地球', path: 'Earth'},
                ],
                items2: [
                    {picture: 28, text: 'Joseph',path:"約瑟夫"},
                    {picture: 38, text: 'Apple',path:"蘋果"},
                    {picture: 48, text: 'Xbox',path:"叉博克斯"},
                    {picture: 58, text: 'Nokia',path:"諾基亞"},
                    {picture: 78, text: 'MKBHD',path:"愛慕凱碧愛趣帝"},
                ],
            }),
            methods: {
                test: function (path) {
                    this.$router.push({name: "sayhi", params: {msg: path}})
                }
            }
        }
    </script>
    
  • 在命令行輸入: npm run serve


運行結(jié)果如下,點擊導(dǎo)航欄不同的菜單選項,觸發(fā)vue-router產(chǎn)生不同的參數(shù),主視圖也會跟著一起改變:

image-20200830054159768.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容