vue入门分享

2018. 03. 26    

一、背景介绍

名称: vuejs

地位: 前端三巨头(react, angular, vue)之一

作者: 尤雨溪

官方描述: Vue (读音 /vjuː/,类似于 view ) 是一套用于构建用户界面的 渐进式框架 。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与 现代化的工具链以及各种 支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

二、基本概念

1.起步

在HTML中引入vuejs文件

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:

<div id="app">
  { { message } }
</div>


var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
}) 

2.指令

  • v-bind : 动态绑定元素属性, 缩写 :
<!-- 绑定一个属性 -->;
<img v-bind:src="imageSrc">
<!-- 缩写 -->;
<img :src="imageSrc">
  • v-on : 绑定时间监听方法, 缩写 @
<!-- 方法处理器 -->;
<button v-on:click="doThis"></button>

<!—缩写 -->;
<button @click="doThis"></button>
  • v-text : 绑定元素的innerText

  • v-html : 绑定元素的innerHtml

  • v-show : 控制元素显示隐藏

  • v-if : 控制元素是否渲染( v-else, v-else-if)

  • v-for : 基于源数据多次渲染元素或模板块

<div v-for="item in items">
  { { item.text } }
</div>
  • v-model : 元素值与源数据双向绑定 <input v-model="value1" />

其他功能性指令:

v-pre , v-once , v-cloak

另vue支持自定义指令,此处不细说。

3.vue实例属性

  • $data : vue实例的数据对象,通过this.$data访问, Vue 实例也代理了 data 对象上所有的属性,因此访问 this.a 等价于访问 this.$data.a

  • $props : 当前组件接收到的props参数,相当于react组件的props, 通过this.$props访问,vue实例同样代理了props对象的属性

  • $refs : 注册引用信息,操作DOM相关,

  • $attrs :包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外),

  • $listeners : 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器

其他实例属性:

$el, $options, $parent, $root, $children, $slots, $scopedSlots

4.数据和方法

data, props上面已介绍

  • computed : 计算属性,根据vue其他属性(data或者props)计算而得,响应式变化
var vm = new Vue({
  data: { a: 1 },
  computed: {
    aDouble: function () {
      return this.a * 2
    },
})
  • watch : 观测一个值变化,执行任意操作
watch: {
    a: function (val, oldVal) {
      console.log(val, oldVal)
    },
}
  • methods : 所有自定义的方法都应该放在methods中,内部通过 this.someMethod(arg) 调用, 方法中的 this 自动绑定为 Vue 实例( react中需要通过bind(this)或者将方法写成赋值表达式的形式 )
methods: {
    plus: function () {
      this.a++
    }
}

5.生命周期

  • created : 在实例创建完成后被立即调用,此时挂载还未开始,真实DOM节点还未产生, 数据请求通常放在这个钩子执行

  • mounted : 节点挂载完成, 此时可访问到DOM 节点

  • updated : 数据更改DOM重新渲染时调用

不常用 : beforeCreate, beforeMount, beforeUpdate, activated, beforeDestroy, destroyed

6.组件

和react一样,vue也是秉承一切皆组件式的开发模式。所有的 Vue 组件同时也都是 Vue 的实例。一个最简单的组件实现:

components: {
    Haha: {
        template: '<p>哈哈: { {name}}</p>',
        props: ['name']
    }
}

Vue官方文档: https://cn.vuejs.org/v2/guide/index.html

三、构建完整单页应用

1.vue-cli工具

使用 Vue官方脚手架工具, 依次执行以下命令:

npm install -g @vue/cli

vue create my-project

cd my-project

npm run serve

2.引入vue-router

vue-router官方文档

npm install vue-router –-save

在/src目录下新建router.js

import Vue from 'vue';
import Router from 'vue-router';
import HelloWorld from './pages/HelloWorld';
import ErrorPage from './pages/Error';

Vue.use(Router)

export default new Router({
    mode: 'history';,
    routes: [
        {
            path: '/',
            component: HelloWorld
        },
    ]
})

修改main.js

import Vue from 'vue';
import App from './App.vue';
import router from './router';

Vue.config.productionTip = false

new Vue({
    render: h =>; h(App),
    router,
}).$mount('#app')

App.vue中加入 <router-view/>,标签以供显示路由页面

vue-router几个重要的钩子函数

beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },

  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },

  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }

3. vuex

npm install vuex –-save

在/src目录下新建store.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

 export default new  Vuex.Store({
    state: {
        count: 0,
    },
    getters: {
        countText(state){
            return '当前计数:' + state.count
        }
    },
    actions: {
        addCount({ commit }){
            commit('ADD_COUNT')
        }
    },
    mutations: {
        ADD_COUNT(state){
            return state.count ++
        }
    }
})

main.js 引入store

import store from './store';

并且放入实例化vue参数对象中

new Vue({
    render: h => h(App),
    router,
    store
}).$mount('#app')

实际用到state数据相关的页面示例: Error.vue

<template>
    <div>
        <h1>404</h1>;
        <p>{ {countText} }</p>;
        <button @click="addCount">点击增加</button>
    </div>
</template>
<script>
    import  { mapGetters, mapActions } from 'vuex';
    export default  {
        computed: {
            ...mapGetters(['countText'])
        },
        methods: {
            ...mapActions(['addCount'])
        }
    }
</script>

vuex单向数据流示意图

4.简单业务处理

按以上步骤流程新建的项目完整代码地址: https://github.com/iajinpeng/vue-share-demo

引入UI框架iview,通过vuex实现简单的数据增删改查。

5。其他示例

项目地址: https://github.com/iajinpeng/vue-app-music

描述: 根据一个开源的react QQ音乐, 用vue重写而成, 可以较为有代表地体现react与vue各层面的差异

git clone https://github.com/iajinpeng/vue-app-music.git

cd vue-app-music/

npm install

npm run dev

四、与react对比

React与Vue都是轻量级的组件库,专注于试图层,两者都可以应用在简单项目中,也可以使用工具及于周边生态扩展为复杂的应用程序。

1.相同之处

1)数据驱动

2)使用 Virtual DOM

3)响应式 (Reactive) 和组件化 (Composable)

4)都支持SSR

2.不同点

1) 语法差异:

  • Vue推荐的是使用 webpack + vue-loader 的单文件组件格式, 依然是熟悉的HTML、CSS、JS,但是可以放在一个文件里,结构清晰明了,易于上手

  • React 推荐的做法是 JSX + inline style,也就是HTML、CSS全部放进js里,虽然不易上手,但是逻辑处理能力远强过模版。 在渲染函数中,可以非常自由地使用js临时变量, 使用各种复杂语句,直接引用作用域中的值, 而在Vue的模板语法中,template中的指令内部的js代码只能是一个变量或者单纯的表达式, 不能写二行语句. 复杂一点的数据则只能通过computed, filter实现。

2) 数据流差异

  • Vue存在双向数据流,子组件可向父组件传值( this.$emit ), 子组件可改变父组件传入的prop , 在不引入vuex的情况下兄弟组件可传值( 通过共同引入的空vue实例作为事件总线 )

  • React父子组件之间则为单向数据流,没有双向绑定。

3)细节性差异

  • 访问数据的方式不一样,react组件就包含三种属性,即props, state和普通属性,分别通过this.props.someVal, this.state.someVal, this.someVal访问。而vue实例属性很多,均可通过this.$(属性名)访问,而常用的props, data, computed由于vue实例代理了其属性,可直接通过this.someVal访问。

  • 与视图相关的组件本身状态(react的state, vue的$data)需要更新已刷新视图的方式不一样。 react的state是不可变(immutable)的,需使用this.setState()分法来更改,vue则可直接赋值,如this.msg = someVal, (某些情况下,深层对象和数组内部更改不能被vue检测到,此时需使用$set()方法)。

  • vue实例的方法内部this直接指向该vue实例,而react则需要一定的写法来实现。

资料链接

Vue官方文档: https://cn.vuejs.org/v2/guide/index.html

Vue-router官方文档: https://router.vuejs.org/zh-cn/

Vuex 文档: https://vuex.vuejs.org/zh-cn/api.html

iView 官方文档 https://www.iviewui.com/

Vue前端开发规范: https://juejin.im/post/5ada9b586fb9a07aaf34c746