专栏首页前端路桥Vue[0x03] - Vue基础实践

Vue[0x03] - Vue基础实践

阅读完本篇文章你可收获如下知识点

  • Vue的简要发展历史
  • 版本号的认识
  • MVVM做了件什么事
  • vue常用指令
  • vue生命周期钩子函数
  • 如何书写一个vue组件
  • bower的使用
  • vue cli 2.0 && 3.0的使用

一、Vue简史

1.1、 那些里程碑

抓重点讲吧,最开始可追溯的版本号是0.6.0这个,但是正式对外发布的版本是在2014年1月24日发布的0.8.0。后面就是两个打头的里程碑,一个是1.x.x,一个是2.x.x。注意到目前为止笔者写这篇文章(2020.03.23)的时候,是没有vue3.0正式版本的,目前是正在用Typescript开发中,2019年10月5号发布的是vue3.0的预览版源码(vue-next),到可以生产使用还有点路,而vue cli3.0这个说法是有的,他们不是一个概念这里先提及一下不要混淆,vue cli 是vue的脚手架工具。其中1.x.x中的1.0.0版本是在2015年10月27号笔者刚上大学的那年发布的,这个时候你写指令可以缩写了,有意思的是,那年发布的蛮多vue的插件的,比如管路由的vue-router、全局状态Vuex以及脚手架vue-cli等等。2.x.x中的2.0.0是在次年的国庆节发布的,它做的比较大的改动相对于1.x.x来讲的话就是,以前呢是把模板交给浏览器去解析渲染的,现在用的是Virtual DOM。

1.2、 版本号x.y.z

前面我们提到了一些关于Vue的版本号,那么我们这里来看下版本号代表的意思吧。

字母

版本号

说明

x

主版本号

一般是大改动,不保证兼容的,脱胎换骨那种

y

次版本号

有些新加的功能,能够保证兼容的

z

修订号

修复一些小的bug

注意事项:

  • 一般y为奇数表示是不稳定的开发版本,y为偶数表示你可以用到生产环境的稳定版本
  • 一些修饰词 名称含义alpha内部版本beta测试版demo演示版enhance增强版free自由版full version正式版lts长期维护版本release发行版rc即将作为正式版发布standard标准版ultimate旗舰版upgrade升级版

二、浅谈Vue

2.1、 前端网红

话不多说,直接上图

从上面的star、watch、fork以及使用数可以看到,前端届当之无愧的网红,学它至少能够找到一个前端的饭碗对吧,这里笔者单独拎出来这张图,其实还是想介绍下怎么去选择一个库。我们知道剩下两位React和Angular分别有FB和Google的支持,而Vue最开始是一个个人项目最后发展成为组织,原则上我们更倾向于有组织或者社区维护的库用于生产环境,这样子遇到问题解决的概率会大一点,还有个就是从可性度考虑,最直白的方式你看它用的人多不多,多的话你就放心用,对应这里的Userd by.

2.2 、一个MVVM框架

MVVM即Model-VIew-VIewModel。说得通俗点它做了一件事就是将数据和视图进行双向绑定,你操作数据视图改变了,你改变了视图数据也跟着改变了,你很少需要手动进行DOM操作。谈起如何实现,大致思路是第一个把一些指令啊表达式能够解析成浏览器能够听得懂的,第二个就是对数据对象的所有属性进行监听(Object.defineProperty()),第三个就是把他们关联起来。

2.3、一丢丢指令

指令的意义在于提供了更好地操作更新数据的方法,在没有这些指令之前,例如我们想更新p标签的内容,我们需要用js获取它的属性,然后通过innerText或者textContent去改变我们想要改变的内容,而有了v-text指令后,我们只需要在Vue实例中的data属性中操作我们需要更改的数据,同理可以类推出其他指令。

罗列了下常用的指令如下:

  • v-text:同于textContext,innerText属性
  • v-html:同于innerHTML属性
  • v-show:如果值为false,会被渲染进DOM,display属性为none;
  • v-if、v-else、v-else-if: 如果值为false,元素直接销毁不渲染
  • v-for: 拿来遍历列表、对象
  • v-on:用于监听DOM事件
  • v-bind:用于动态绑定class、style、href等
  • v-model:用于表单数据的双向绑定(v0.8.0+)
  • v-once: 只渲染一次(v2.0.0+)
  • v-pre: 不做解析

楼上的备注(vx.x.x+)表示在某个版本及以上支持,这里笔者未全部测试,仅作了解。下面我们综合下楼上的指令做次实践。

2.3.1、v-html、v-text

我们做这样一件事,在Vue实例的data属性中放入如下数据,然后在页面上去展示:

data: {
    text: 'hello world!',
    html: "<span>我是一个span标签包裹的html</span>",
}
<p>v-text指令:</p>
<p v-text="text"></p>
<p v-text="html"></p>
<p>{{text}}</p>

<p>v-html 指令:</p>
<p v-html="text"></p>
<p v-html="html"></p>
<p>{{html}}</p>

在页面显示部分我们分别用v-text和v-html指令去解析楼上的数据,最后一条都用Moustache语法,得到的效果如图。

从中我们可以看到Moustache语法是直接解析成文本的,v-text它是不解析标签的,而v-html会去解析标签。

2.3.2 v-pre和v-once

偷懒一点,我们还是延用楼上的数据,只不过html部分改了下,这里我们故意<p v-html="html">试试</p>这么写

<p>v-once:</p>
<p v-once>{{html}}</p>

<p>v-pre:</p>
<p v-pre>{{html}}</p>

<p>v-html:</p>
<p v-html="html">试试</p>

之后我们打开网页进行操作一波

可以看到v-pre是不做解析的,v-once只按文本解析一次,而且默认写在标签的文字会被替换。

2.3.3 v-show、v-if、v-if-else、v-for

今天刚好是2020年3月22日嘛,那么我们创建一个数组arr: [2, 0, 2, 0, 0, 3, 2, 2]放在Vue实例的data里面,并且在methods里面写个判断偶数的函数

isEven(v) {
    return v % 2 === 0;
}

网页上做如下处理,这段话的意思就是先遍历数组,然后找是偶数的,这里我们分别用v-if和v-show:

<hr/>
<span v-for="(v,k) in arr" v-if="isEven(v)"> {{k}}:{{v}} </span>
<hr/>
<hr/>
<span v-for="(v,k) in arr" v-show="isEven(v)"> {{k}}:{{v}} </span>
<hr/>

具体的效果如图所示:

可以看到v-if如果条件为false的话是不解析的,而v-show如果条件为false,元素还是在的只不过display属性设置成了none。

我们把楼上的例子升级一下,就是如果不是偶数就爆红,然后再演示下遍历对象。在Vue实例的data属性中加入了一个obj对象

obj: {
        year: 2020,
        month: 03,
        day: 22
}

对应html的修改如下:

<p v-for="(v,k) in arr" v-if="isEven(v)"> {{k}}:{{v}} </p>
<p v-else style="color:red"> {{k}}:{{v}} </p>
<p v-for="(v,k) in obj"> {{k}}:{{v}} </p>

具体的展示效果如下:

2.3.4 v-on、v-bind、v-model

我们做这样一个例子点击按钮字符串反转,然后显示的颜色变红字体变大。

定义样式文件部分代码

.red {
    color: red;
}

.big {
    font-size: 20px;
}

定义html标签部分代码

<input type="text" v-model="text"/>
<p v-text="text" v-bind:class="{'red': isRed, 'big': isBig}"></p>
<button v-on:click="change">反转变红</button>

实例化Vue相关属性部分代码

data: {
    text: 'hello world!',
        isRed: false,
            isBig: false
},
methods: {
    change() {
        this.isRed = !this.isRed;
        this.isBig = !this.isBig;
        this.text = [...this.text].reverse().join('');
    }
  },

具体的效果如下:

2.4 、一丢丢生命周期钩子函数

整理了下一个完整的Vue生命周期,

  • beforeCreate(创建前)
  • created(创建后)
  • beforeMount(挂载前)
  • mounted(挂载后)
  • beforeUpdate(更新前)
  • updated(更新后)
  • beforeDestroy(销毁前)
  • destroyed(销毁后)

目前笔者用的比较多的是created和mounted,它们长得很像,所以这里我们区分一下这两位选手。

created 是指完成了完成了数据、方法、属性、事件的初始化,你可以调用它们,但是$el属性并没有显示出来

mounted 是指el被新创建的的vm.$el替换了并且已经挂载到实例了,编译好的内容已经替换了el属性指向的DOM对象,所以在这个时候你去进行ajax交互是比较好的。

我们来看这样一个例子,我们实例化一个Vue对象,然后通过在data里面分别放了5个属性abcde,在created和mounted函数里面分别获取data的a的值,调用methods方法,以及获取网页的元素的值。

html部分代码如下:

<p>{{a}}</p>
<p>{{b}}</p>
<p>{{c}}</p>
<p>{{d}}</p>
<p>{{e}}</p>

Vue实例部分代码如下:

data: {
    a: 'aaaaa',
    b: 'bbbbb',
    c: 'ccccc',
    d: 'ddddd',
    e: 'eeeee'
},
created() {
    console.log('created start ....')
    console.log('get data a: ', this.a);
    console.log('call function hello: ', this.hello());
    let pArr = document.getElementsByTagName('p');
    for(let i = 0; i < pArr.length; i++) {
        console.log(`${i}: ${pArr[i].textContent}`)
    }
    console.log('created end ....')
},
mounted() {
    console.log('mounted start....')
    console.log('get data a: ', this.a);
    console.log('call function hello: ', this.hello());
    let pArr = document.getElementsByTagName('p');
    for(let i = 0; i < pArr.length; i++) {
        console.log(`${i}: ${pArr[i].textContent}`)
    }
    console.log('mounted end....');
},
methods: {
    hello() {
        return 'hello world';
    }
}

显示的效果如下:

可以看到,在created钩子中,确实初始化了相关事件方法属性,但是网页并未挂载到页面上,只有mounted之后,页面上显示了我们data里面的数据。

2.5、计算属性和侦听器

这里我觉得官网讲的很详细了,就提及一下吧。

2.5.1、计算属性

通常我们不期望在template里面暴露过多的判断逻辑,我们可以选择计算属性,实现一个方法但是暴露出去是一个值,我们只需要在合适的地方v-if="计算属性",这样就比较好维护了,计算属性有get和set方法,然后计算属性可以记录新旧值变化。

2.5.2、侦听器

顾名思义,就是监听数据变化然后触发相应操作,笔者目前用的比较多的是监听全局状态改变,然后各个分组件进行相关操作。

2.6、一丢丢组件

2.6.1、什么是组件?

简单地说,组件就是把网页肢解成一个个小模块去实现,特定场景可复用,直接上图吧。

从楼上这张图,我们不难发现,头部可以写个组件,底部可以写个组件,而且它们是通用组件,就是你换个页面也能用的,类似的还有弹框啊,按钮啊之类的。然后items也可以封装成一个个组件,一个专题一个。

2.6.2、那我们为什么要有组件

遥想上古时代网页编程,写个几十个页面,你写着写着发现a页面有个头部有个尾部还有若干链接按钮啥的,等你去写b页面又是它们,你去写c页面怎么还是它们,你的内心不崩溃吗?而当你写成组件的时候,下次你直接引用就好了,还比较好维护,放到以前那个做法就是CTRL+C&&CTRL+V,与此同时带来的一个问题就是组件间的通信了,例如父子组件传值,兄弟组件传值等等。

组件不是我们今天的重点,所以这里提及一下。

三、工具使用

3.1、Bower的使用

最开始我们写页面,本地的时候可能会创建一个文件夹叫assets,然后再新建一个js文件夹引入一堆jQuery之类的库。线上的话我们可能会用cdn去引入。放到上古时代,我们每次都要打开浏览器去下载它,然后去解压,然后贴到我们的项目目录对吧。有了bower以后,你就可以不用关心这些了,直接命令行一把梭,但话说回来,bower现在在前端工程化项目用的并不多,笔者是很喜欢在演示项目的时候用它,因为比较方便,好的下面我们一起来看下吧。

3.1.1 bower相关命令
$ npm install -g bower  #全局安装bower
$ bower init  #会创建一个bower.json配置文件
$ bower install pkg #安装pkg, 例如 bower install jquery, 默认安装在bower_components下
$ bower search pkg  #搜索pkg
$ bower info pkg # 查看pkg信息,这个命令也会去下载的
$ bower list # 列出已安装的包
3.1.2 自定义目录

默认bower安装都是放在bower_components下面的,我们有的时候想自己定义,那么新建一个文件叫.bowerrc

{
    "directory": "assets/libs",
    "timeout": 120000,
    "registry": "https://registry.bower.io"
}

那么它下次就会安装在assets下面的libs目录下

3.1.3 安装指定版本

这里以vue0.6.0为例命令是bower install vue#0.6.0

bower vue#0.6.0             not-cached https://github.com/vuejs/vue.git#0.6.0
bower vue#0.6.0                resolve https://github.com/vuejs/vue.git#0.6.0
bower vue#0.6.0               download https://github.com/vuejs/vue/archive/0.6.0.tar.gz
bower vue#0.6.0               progress received 0.1MB
bower vue#0.6.0               progress received 0.1MB
bower vue#0.6.0               progress received 0.1MB
bower vue#0.6.0                extract archive.tar.gz
bower vue#0.6.0               resolved https://github.com/vuejs/vue.git#0.6.0
bower vue#0.6.0                install vue#0.6.0

vue#0.6.0 assets\libs\vue

很有意思,同学们发现了吗,首先他会去看下本地有没有缓存,没用的话就去远程下载,然后下载完解压到指定目录。

3.2、vue cli的使用

3.2.1 vue cli 2.0 && 3.0
安装方式创建项目不同

vue cli 2.0的安装方式

npm i vue-cli -g

vue cli 2.0 创建项目

vue init vue project

vue cli 3.0的安装方式

npm i @vue/cli -g

vue cli 3.0 创建项目

vue create project

配置不同

vue cli 2.0创建的项目有一大堆配置文件,所以学习成本就上去了,vue cli 3.0相比之下少了很多,集成了webpack和webpack-dev-server

文件结构不同

2.0时代有config、build、static文件夹,其中config和build里面又有dev、prod等配置文件,而3.0取而代之的是vue.config.js,并且砍掉了这些目录,改为public。

vue cli 3.0好在哪里

配置简单了,新增 .browserslistrc 文件可做浏览器兼容,新增 babel.config.js 替代原先的.babelrc,但作用是一样的,不仅有命令行还有ui界面了,输入vue ui可以进行项目创建可视化配置。

.vue文件组成
<template>
  //这里面写你的html标签元素
</template>
<script>
  //写js逻辑
</script>
<style>
  //写css样式
</style>

四、设计一个低配版弹框组件

结合楼上的部分,我们实现一个低配版的弹框。

我们做这样一件事情,就是打开网页点击按钮,内容显示,再次点击按钮内容消失。

MsgBox.vue

这里MsgBox相当于Home的子组件,他们之间用props进行通信。

<template>
  <div class="msgBox">
    {{msg}}
  </div>
</template>

<script>
export default {
  name: 'MsgBox',
  props: {
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.msgBox {
  width: 500px;
  height: 300px;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0px 0px 15px rgba(4,0,0,.4);
  align-items: center;
  justify-content: center;
  display: flex;
  font-size: 24px;
}
</style>

Home.vue

给按钮加个点击事件,点击的时候调用toShow方法,然后通过判断相关参数去决定显示与否

<template>
  <div class="home">
    <div class="header">
    <button class="button" @click="toShow">{{message}}</button>
    </div>
    <div v-if="isShow" class="show">
    <MsgBox msg="Hello World"/>
    </div>
  </div>
</template>

<script>
// @ is an alias to /src
import MsgBox from '@/components/MsgBox.vue'

export default {
  name: 'Home',
  data () {
    return {
      show: false,
      message: '显示'
    }
  },
  components: {
    MsgBox
  },
  methods: {
    toShow () {
      this.show = !this.show
      this.message = this.show ? '隐藏' : '显示'
    }
  },
  computed: {
    isShow () {
      return this.show
    }
  }
}
</script>

<style>
.home {
  display: flex;
  flex-direction: column;
}
.header {
  flex-basis: 100%;
  display:flex;
}
.button {
    background-color: #4CAF50; /* Green */
    border: none;
    color: white;
    padding: 10px 20px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
}

.button:hover {
  box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
}

.show {
  flex-basis: 100%;
  display:flex;
  justify-content: center;
}
</style>>

这里笔者是比较粗暴地实现了,其实深究下去还是有很多问题,比如组件的健壮性,尽量可配置化程度高一点,然后点击的时候有个过渡效果可能会好一点,后续我们再继续完善吧,以上就是今天的全部内容。

五、参考文献

bower文件配置:https://bower.io/docs/config/

bower包库搜索:https://bower.io/search/

vue cli: https://cli.vuejs.org/guide/

本文分享自微信公众号 - 前端路桥(ataola),作者:丰臣正一

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • vue[0x01] -- Hello World

    如果你看过一千部以上的电影,你就会发现,这世间根本没有什么离奇的事。为什么从后端或者说网页三剑客过来的哥们,会有觉得vue上手快,容易学的错觉?很大程度上,在早...

    丰臣正一
  • vue[0x02] -- 基础特性

    你会发现这样一个现象,我本来时挂载到id为app的div上的,但是它并没有这么做。

    丰臣正一
  • Javascript[0x03] -- 队列

    生活中队列的例子有很多,例如吃饭排队、小学生出勤做广播体操、打印机打印文件、去地铁坐车也要排队,去海底捞吃饭也要叫号排队,这些都是队列的一种;还有一种就是优先...

    丰臣正一
  • MacOS中安装vue

    初学者都知,要搭建vue要安装node的环境,所以,我们先下载node mac os版 node下载地址

    奕仁
  • 量化未知 ——谈电影票房预测【海量服务之道2.0】

    我们说,数据是不会说谎的。 我们又说,数据是会说谎的。 我们发现,数据有时候说谎,有时候不说谎。 后来我们找到了一个可以自圆其说的说法: 数据不说谎,说谎的是不...

    腾讯大讲堂
  • 剑指Offer面试题:18.二叉树的镜像

    Step1.先序遍历原二叉树的每个节点,如果遍历到的结点有子结点,就交换它的两个子结点。

    Edison Zhou
  • 如何使用Node.js编写命令工具——以vue-cli为例

    vue-cli全局安装之后,提供了vue命令和vue init、vue list、vue build三个子命令,通过命令可以搭建基于vue.js的脚手架项目。本...

    用户1217459
  • 对代码的领悟之-高质量代码有三要素:可读性、可维护性、可变更性

      我们评价高质量代码有三要素:可读性、可维护性、可变更性。我们的代码要一个都不能少地达到了这三要素的要求才能算高质量的代码。

    Java编程指南
  • 十年来最难的一届CVPR:接收率22%,百度入选19篇,旷视17篇

    本届CVPR共有198位区域主席、3664位审稿人参与,共收到6656篇投稿,有1470篇论文被接收,接收率约22%。

    量子位
  • 国内2大Git代码托管网站

    可以说GitHub的出现完全颠覆了以往大家对代码托管网站的认识。GitHub不但是一个代码托管网站,更是一个程序员的SNS社区。GitHub真正迷人的是它的创新...

    张善友

扫码关注云+社区

领取腾讯云代金券