Vue.js项目开发技术解析

Vue.js项目开发技术解析

一、Vue.js实例

在一个Vue.js工程中,用于显示内容最基层的实例称之为根实例。通过该实例可以进行页面或组件的更新和显示。对于项目本身而言,无论是什么样的页面,都要基于该根实例进行显示。

1.1、何为构造器

对于Vue.js项目来说,每个应用的起步都需要使用Vue.js的构造函数创建一个根实例,如下:

// 逻辑部分代码,建立Vue实例
var vm = new Vue({
  //选项
})

这里的vm其实是ViewModel的简称。虽然Vue.js并不是完全遵循MVVM模型,但是Vue.js的设计无疑受到了它的启发。

在实例化Vue.js时,需要传入一个选项对象,它包括数据、模板、挂载元素、方法和生命周期钩子等选项,全部的选项可以在API文档中查看。
对于已经创建的相关构造器,可以扩展为其他构造器,相当于对某一构造器的继承,从而达到可复用组件构造器的目的。
演示代码如下:

var MyComponent = Vue.extend({
  // 扩展选项
})
// 所有的 MyComponent  实例都将以预定义的扩展选项被创建
var myComponentInstance = new MyComponent()

1.2、实例的属性和方法

当一个 Vue 实例被创建时,它将 data 对象中的所有的属性加入到 Vue 的响应式系统中。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。

// 我们的数据对象
var data = { a: 1 }

// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
  data: data
})

// 获得这个实例上的属性
// 返回源数据中对应的字段
vm.a == data.a // => true

// 设置属性也会影响到原始数据
vm.a = 2
data.a // => 2

// ……反之亦然
data.a = 3
vm.a // => 3

当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时就已经存在于 data 中的属性才是响应式的。也就是说如果你添加一个新的属性,
比如:

vm.b = 'hi'

那么对 b 的改动将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值。
这里唯一的例外是使用 Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。

var obj = {
  foo: 'bar'
}

Object.freeze(obj)

new Vue({
  el: '#app',
  data: obj
})
<div id="app">
  <p>{{ foo }}</p>
  <!-- 这里的 `foo` 不会更新! -->
  <button v-on:click="foo = 'baz'">Change it</button>
</div>

除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来。例如:

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})

vm.$data === data // => true
vm.$el === document.getElementById('example') // => true

// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
  // 这个回调将在 `vm.a` 改变后调用
})

以后你可以在 API 参考[API 参考]中查阅到完整的实例属性和方法的列表。

1.3、生命周期

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如 created 钩子可以用来在一个实例被创建之后执行代码:

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  }
})
// => "a is: 1"

也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mountedupdateddestroyed。生命周期钩子的 this上下文指向调用它的 Vue 实例。

注意:不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch(‘a’, newValue => this.myMethod())。因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。
image.png

二、Vue.js路由

Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,让构建单页应用变得易如反掌。
包含的功能有:

  • 嵌入的路由/视图表
  • 正极的,基于组件的路由配置
  • 路由参数,查询,通配符
  • 基于Vue.js过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的CSS类的链接
  • HTML5历史模式或hash模式,在IE9中自动降级
  • 自定义的滚动条行为

两种方式:

1、直接引入
2、npm安装方式

使用Vue.js + Vue Router创建单页应用,是非常简单的。使用Vue.js,我们已经可以通过组合组件来组成应用程序,当你要把Vue Router添加进来,我们需要做的是,将组件(组件)映射到路由(路由),然后告诉Vue Router在哪里渲染它们。下面是一个基本示例:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="https://unpkg.com/vue/dist/vue.js"></script>
		<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
		<title></title>
	</head>
	<body>

	
	<div id="app">
	  <h1>Hello App!</h1>
	  <p>
	    <!-- 使用 router-link 组件来导航. -->
	    <!-- 通过传入 `to` 属性指定链接. -->
	    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
	    <router-link to="/foo">Go to Foo</router-link>
	    <router-link to="/bar">Go to Bar</router-link>
	  </p>
	  <!-- 路由出口 -->
	  <!-- 路由匹配到的组件将渲染在这里 -->
	  <router-view></router-view>
	</div>	
	<script type="text/javascript">
		// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
		
		// 1. 定义 (路由) 组件。
		// 可以从其他文件 import 进来
		const Foo = { template: '<div>foo</div>' }
		const Bar = { template: '<div>bar</div>' }
		
		// 2. 定义路由
		// 每个路由应该映射一个组件。 其中"component" 可以是
		// 通过 Vue.extend() 创建的组件构造器,
		// 或者,只是一个组件配置对象。
		// 我们晚点再讨论嵌套路由。
		const routes = [
		  { path: '/foo', component: Foo },
		  { path: '/bar', component: Bar }
		]
		
		// 3. 创建 router 实例,然后传 `routes` 配置
		// 你还可以传别的配置参数, 不过先这么简单着吧。
		const router = new VueRouter({
		  routes // (缩写) 相当于 routes: routes
		})
		
		// 4. 创建和挂载根实例。
		// 记得要通过 router 配置参数注入路由,
		// 从而让整个应用都有路由功能
		const app = new Vue({
		  router
		}).$mount('#app')
		
		// 现在,应用已经启动了!
	</script>
		
	</body>
</html>

通过注入路由器,我们可以在任何组件内部通过this.$router访问路由器,也可以通过this.$route访问当前路由:

// Home.vue
export default {
  computed: {
    username() {
      // 我们很快就会看到 `params` 是什么
      return this.$route.params.username
    }
  },
  methods: {
    goBack() {
      window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
    }
  }
}

上面的示例都常使用router实例。留意一下this.$router和router使用起来完全一样。我们使用this.$router的原因是我们并不想在每个独立需要封装路由的组件中都引入路由。

三、Vue.js路由配置vue-router

3.1、动态路由匹配

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:

const User = {
  template: '<div>User</div>'
}

const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
})

现在呢,像 /user/foo 和 /user/bar 都将映射到相同的路由。

一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。于是,我们可以更新 User 的模板,输出当前用户的 ID:

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

3.2、嵌套路由

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如:

3.3、编程式导航

3.4、命名路由

有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

要链接到一个命名路由,可以给 router-link 的 to 属性传一个对象:

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

这跟代码调用 router.push() 是一回事:

router.push({ name: 'user', params: { userId: 123 }})

这两种方式都会把路由导航到 /user/123 路径。

3.5、命名视图

3.6、重定向和别名

3.7、路由组件传递参数

3.8、HTML5 History模式

四、数据获取

4.1、导航守卫

4.1.1、全局守卫

4.1.2、全局解析守卫

4.1.3、全局后置钩子

4.1.4、路由独享的守卫

4.1.5、组件内的守卫

4.2、数据获取

4.2.1、导航完成后获取数据

4.2.2、在导航完成前获取数据

…详细的在官网上都有相应的描述。

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?