美文网首页
2020-08-30 前端路上的新长征(Vuetify入门)

2020-08-30 前端路上的新长征(Vuetify入门)

作者: Rockage | 来源:发表于2020-08-30 08:33 被阅读0次
image.png

前端路上的新长征

  • 前言

从历史的角度来说,尽管几十年过去了,前端(即运行在浏览器里的程序)的基本结构还是以HTML(CSS)+Javascript为主,变化不大,曾经有一些脚本语言比如微软的VBS试图挑战过这个架构,均以失败告终(甚至连昙花一现都谈不上)。后端(服务器)方面则是百花齐放,方案众多,像是Java、PHP、GO、Python以及Javascript本身的一个分支Node.JS等等。

由于WEB技术的发展速度非常快,因此HTML与Javascript也在高速迭代,于是产生了 “框架” 这个概念,所谓框架就是一堆前人已经编写好的成体系的代码,其主要目的是不重复造轮子,加速开发效率。

前端框架大致上分为两个大类,侧重于HTML的CSS框架与侧重于Javascript的JS框架。

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

像React、Vue这一类框架关注点是Javascript本身,更多的是属于处理逻辑层面的事务。而Bootstrap和Vuetify这一类CSS框架则着重关注HTML界面,页面布局,排版等视觉方面的事情。

在没有框架之前,所有前端开发者都采用原生HTML和原生Javascript,工作量极大。当然,你如果问:我们一定需要框架吗?答案却是否定的,国外就确实有一股势力是反对采用框架编程的,自诩为 "JS反框架联盟",为了不引战,此话题咱们不做深入探讨,见仁见智吧。

  • PS: 本文以Vue + Vuetify为基础。

Vuetify 篇:

  • Vuetify 号称是 Vue.js 的头号组件库,笔者使用过Bootstrap,因为年代久远已经忘得差不多了,具体特点也不做评价。外卖双雄之一的饿了吗也搞了CSS库,名字叫Element,感觉上手很容易,但限制比较多,UI的炫酷程度也比较一般。Vuetify 要比前两者诞生的时间晚,但是它的可定制性很强,速度快,而且预设UI非常新潮,漂亮,值得尝试!

由于Vuetify是专门提供给Vue使用的(从其名字也大概猜到了),所以在使用Vuetify之前我们还必须先安装Vue。

  • 装Vue之前还得先装Node.JS

    Node.JS本质上用于服务器后端,它将原本只能用在前端的Javascript变得可以运行在服务器后端,它对标的是Java、PHP这一类东西。但此处安装Node.js并不是要用到它的后端功能,主要是需要他的一个附属工具:“npm” 包管理工具。

  • 回到Windows cmd命令行界面,开始准备安装vue-cli:

    • vue-cli是vue框架的“脚手架”,它的作用是快速为你搭建一个空的框架,然后立刻可以工作,省去了一大堆调试安装的事情。当然如果你不采用vue脚手架,用传统的方式引用一个vue.js也是可以的。这样做的优点是更加简洁高效,但是由于缺少npm包管理这个工具,调试和链接各种组件的难度将陡增,在此我还是建议从脚手架开始吧,等以后有闲了可以再去深入。

    • 输入以下命令:

      npm install -g @vue/cli
      
    • vue-cli安装好之后,vue命令就能使用了,用它创建一个项目,名称随意(此处为mini):

      vue create mini //创建mini项目
      cd mini
      vue add vuetify //添加vuetify组件
      
      
      • 项目将会自动创建完成,并且自动生成以下目录结构:
image-20200830075007635.png
  • 问题是,如何运行一个vue程序? 很简单,在cmd命令行输入以下命令:

    npm run serve
    

一个最基础的APP界面如下:

image-20200829024214407.png

如图所示,这是一个最简单的APP框架,包括

  • 两个状态栏:v-app-bar(顶部)、v-footer(底部)
  • 侧边功能导航栏:v-navigation-drawer
  • 主视图区:v-content

最基础的主页代码,UI由<template>部分组成,JS代码包裹在<script>里:

<template>
  <v-app id="inspire">
    <v-navigation-drawer
            v-model="drawer"
            app
            clipped>
<!--  vmodel: 显示开关,设为null的时候屏蔽导航栏 
         app : 是app = 'true'的简化语法,表示这个导航栏属于app的一部分
         clipped: 等于clipped = 'true',表示导航栏采用压缩布局
-->
      <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>

上面是最简单的基础用法,接下来我们稍微复杂一点:
  1. 用数组的方法为导航栏(v-navigation-drawer) 添加连接
  2. 结合vue-router动态渲染主视图区

  • 首先回到cmd命令行状态,输入以下命令安装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平级的目录中创建一个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},
        ]
    }) 
    /*以上代码创建了两个路由,“/” 根路由和“/msg”
       大白话解释根路由就是当我们在浏览器地址栏什么参数都不带,直接输入网址比如qq.com,页面应该跳到哪,
       第二个路由/msg,就是说当我们在网址后面加一个/msg,比如qq.com/msg,页面应该跳到哪,所谓路由就是这个意思。*/
    
  • 在 src/components 目录中创建一个hello.vue文件:

    <template>
        <h1>Hello {{ $route.params.msg}}</h1>
      <!-- 此处的$route.params.msg表示从路由/msg传递过来的参数 -->
    </template>
    
    <script>
        export default {
            name: 'hello',
    
            data: () => ({
    
            }),
        }
    /* 以上就是一个最简单的vue组件,它由template和script两部分组成,template部分表示HTML代码,
    很简单,就是显示一个H1级别的文字:Hello + 路由传过来的参数,
    JS部分其实并没有任何实质性内容,是一个空框架。 */
    </script>
    
    
  • 修改app.vue文件,清空旧的内容,将以下内容全部复制粘贴进去:

    <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 是组的标题 -->
                    <v-list-item
                            v-for="item in items"
                            :key="item.text"
                            @click="test(item.path)"
                            link>
                        <!-- v-for 是 vue的标准语法,item in items的 items 是一个数组,: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 是选项图标
                             v-list-item-content 是选项的内容区
                             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 是一个随机产生用户头像的趣味网站,此处从该网站获取头像图片 -->
                                <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>
    
                  <!-- 以下两个选项并没有用到数组,一般用于一些非动态的固定栏目 -->
                  <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变量来决定导航栏是否隐藏,PS:当宽度被压缩的时候导航栏自动隐藏(比如手机) -->
                <v-toolbar-title>我的第一个APP</v-toolbar-title>
            </v-app-bar>
    
            <v-main> <!-- v-main是主试图,一般指与用户交互信息最频繁的区域,尺寸也最大 -->
                <v-container
                        class="fill-height"
                        fluid>
                    <router-view></router-view>
                    <!-- router-view 是路由视图,APP的所有点击变化都在此反映,一般来说路由视图约等于主视图-->
                </v-container>
            </v-main>
    
            <v-footer color="cyan" app> <!-- v-footer是最底部的页脚栏,一般用于放置版权信息之类杂项 -->
                <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


运行结果如下,点击导航栏不同的菜单选项,触发vue-router产生不同的参数,主视图也会跟着一起改变:

image-20200830054159768.png

相关文章

  • 2020-08-30 前端路上的新长征(Vuetify入门)

    前端路上的新长征 前言 从历史的角度来说,尽管几十年过去了,前端(即运行在浏览器里的程序)的基本结构还是以HTML...

  • Vue Express 注册登录实现--1

    项目使用 vue、vuetify、express、JWT、passport、mysql 建立项目 建立文件夹 前端...

  • 优质的 Vue 开源项目

    Vuetify - Vue.js 2.0 组建库 Material Design 的前端组建库,基于 Vue.js...

  • Unexpected end of JSON input whi

    前端项目使用 npm install vuetify --save 命令时出现如下错误 解决方案 使用 npm ...

  • 前端新人

    新入门web前端,想把在学习前端道路上的心得分享一下,嘻嘻

  • 新长征仍然在路上

    作者:李红刚 新长征仍然在路上, 民族复兴离不开伟大的党。 中华号巨轮平稳前进, 习书记的思想是胜利方向。 新长征...

  • 新长征路上

    新长征路上也要走出二万五千里 旁边树荫小憩,安逸 待久了,有点慌 再次启程,胳膊腿脚已经废退 有办法吗?没办法 跑...

  • 人民日报时评金句摘抄

    新长征路上,有风有雨是常态,风雨无阻是心态,风雨兼程是状态。——《人民日报》 适用主题:新长征路 日日行不怕千万里...

  • 人民日报时评金句

    新长征路上,有风有雨是常态,风雨无阻是心态兼程是状态。(适用:新长征路) 日日行不怕千万里,天天讲不吝千万言,时时...

  • 人民日报时评金句摘录

    新长征路上,有风有雨是常态,风雨无阻是心态,风雨兼程是状态。——《人民日报》 适用主题:新长征路 自力更生是中华民...

网友评论

      本文标题:2020-08-30 前端路上的新长征(Vuetify入门)

      本文链接:https://www.haomeiwen.com/subject/bmbssktx.html