Vue学习笔记 在html文件中创建Vue实例,并使用http-vue-loader注册单文件组件
Posted 梆子井欢喜坨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue学习笔记 在html文件中创建Vue实例,并使用http-vue-loader注册单文件组件相关的知识,希望对你有一定的参考价值。
本篇博客基于Vue2.x
官方文档:https://cn.vuejs.org/v2/guide/instance.html
最近和同学合作一个设备信息管理的小项目,而同学找的模板不是前后端分离的
因此只能学习一下在 html文件中如何使用Vue,并学习一些之前没有理清的概念。
1. Vue实例
在Vue的官方教程中,也是从在html中使用Vue起步的, 下面是一个简单的Hello World 例子。
<!DOCTYPE html>
<html>
<head>
<title>My first Vue app</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<!-- 用简洁的模板语法来声明式地将数据渲染进 DOM 的系统 -->
{{ message }}
</div>
<script>
// 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。
当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。
当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
// 我们的数据对象
var data = { a: 1 }
// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
data: data
})
// 获得这个实例上的 property
// 返回源数据中对应的字段
vm.a == data.a // => true
// 设置 property 也会影响到原始数据
vm.a = 2
data.a // => 2
// ……反之亦然
data.a = 3
vm.a // => 3
当这些数据改变时,视图会进行重渲染。
只有当实例被创建时就已经存在于 data 中的 property 才是响应式的。
除了数据 property,Vue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 $,以便与用户定义的 property 区分开来。
var data = { a: 1 }
var vm = new Vue({
el: '#example', // 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
console.log(app.$data);
===========================
out: {message: "Hello Vue!"}
实例生命周期钩子
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
如mounted钩子
实例被挂载后调用,这时 el
被新创建的 vm.$el
替换了。如果根实例挂载到了一个文档内的元素上,当 mounted
被调用时 vm.$el
也在文档内。
mounted
不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在mounted
内部使用vm.$nextTick
:
mounted: function () {
this.$nextTick(function () { // 生命周期钩子的 this 上下文指向调用它的 Vue 实例。
// Code that will run only after the
// entire view has been rendered
})
}
生命周期图示:
2. 注册组件
组件是可复用的 Vue 实例
每个组件必须只有一个根元素
一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
count: 0
}
}
有两种组件的注册类型:全局注册和局部注册。
2.1 通过 Vue.component 全局注册:
组件名就是 Vue.component 的第一个参数。
自定义组件名的规范为kebab-case (短横线分隔命名),字母全小写且必须包含一个连字符
Vue.component('my-component-name', {
// ... options ...
})
使用 PascalCase(首字母大写命名) 定义一个组件时,用两种命名法都可以引用组件
Vue.component('MyComponentName', { /* ... */ })
但是直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。
全局注册的组件可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。
2.2 局部注册
全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 javascript 的无谓的增加。
可以通过一个普通的 JavaScript 对象来定义组件:
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
然后在 components 选项中定义你想要使用的组件:
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
局部注册的组件在其子组件中不可用
2.3 在模块系统中局部注册单文件组件
如果使用了诸如 Babel 和 webpack 的模块系统。
创建一个 components 目录,并将每个组件放置在其各自的文件中。
在局部注册之前导入每个你想使用的组件。
例如,在一个假设的 ComponentB.js 或 ComponentB.vue 文件中:
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
现在 ComponentA 和 ComponentC 都可以在 ComponentB 的模板中使用了。
在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:
- 用在模板中的自定义元素的名称
- 包含了这个组件选项的变量名
2.4 在html中注册单文件组件
如果是一个页面中的组件复用,使用基本的局部注册就可以满足需求。
但是在这个项目中,需要在多个html文件中复用诸如侧边栏,顶边栏之类的组件。
因此还是考虑用单文件组件的方式进行注册。
为了在html文件中注册单文件组件,需要使用一个npm包http-vue-loader
github地址:https://github.com/FranckFreiburger/http-vue-loader
Load .vue files directly from your html/js. No node.js environment, no build step.
例如有个单文件组件my-component.vue
<template>
<div class="hello">Hello {{who}}</div>
</template>
<script>
module.exports = {
data: function() {
return {
who: 'world'
}
}
}
</script>
在html文件中进行组件注册
<!doctype html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
</head>
<body>
<div id="my-app">
<my-component></my-component>
</div>
<script type="text/javascript">
new Vue({
el: '#my-app',
components: {
'my-component': httpVueLoader('my-component.vue')
}
});
</script>
</body>
</html>
其它使用示例参见github。
2.5 个人学习总结
可以发现http-vue-loader的示例中,单文件子组件中写的是module.exports = {}
,而不是export default {}
以上一篇博客Vue学习笔记(1) 根据MDN教程,创建一个To-Do List为例
在APP.vue中是这样写的
export default {
name: 'app',
components: {
ToDoItem,
ToDoForm
},
// ...
}
之前没有系统学习JavaScript,没有思考过export default
的作用,加上平时都是直接用Vue脚手架,导致忽略了一些问题,在写组件的时候直接copy export default {}
不起效,浪费了很多时间。
回忆一下使用vue/cli前进行了什么操作
- 安装npm(Node Package Manager),它是基于Node.js的包管理器
- 安装vue/cli
事实上,用Vue脚手架前安装Node的主要目的是使用npm这个前端开发的软件包管理器和使用WebPack进行模块化管理。
不使用npm,在页面引入 vue.min.js 也能使用Vue进行前端开发。
下面来解释下module.exports = {}
和export default {}
的区别:
学习参考:
https://segmentfault.com/a/1190000010426778
首先要明白一个前提,CommonJS模块规范和ES6模块规范完全是两种不同的概念。
require
: node 和 es6 都支持的引入
export / import
: 只有es6 支持的导出引入
module.exports / exports
: 只有 node 支持的导出
nodeJS采用commonJs规范,
CommonJS定义的模块分为: 模块标识(module)、模块定义(exports) 、模块引用(require)
为了让对象暴露于模块之外,只需把它们设置为 exports 对象的附加属性即可
在一个既定的模块内,可以把 exports 想象成 module.exports 的 快捷方式。
exports 本质上就是在模块初始化前为 module.exports 的值进行初始化的一个变量。
这个值是对一个对象(这里是空对象)的引用。
这意味着 exports 与 module.exports 引用了同一个对象,也意味着如果为 exports 赋其它值不会影响到 module.exports。
Node 模块是通过 module.exports 导出的,如果直接将exports变量指向一个值,就切断了exports与module.exports的联系
不同于CommonJS,ES6使用 export 和 import 来导出、导入模块。
ES6中的模块功能主要由两个命令构成:export和import。
- export命令用于规定模块的对外接口
- import命令用于输入其他模块提供的功能。
export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。
导出的不是一个具体的数值,而是一个对象
export default命令,为模块指定默认输出。
命名的导出 | 默认的导出 |
---|---|
export class User {…} | export default class User {…} |
import {User} from … | import User from … |
学完Js语法,还是很疑惑为什么在脚手架创建的工程中,单文件组件的导出使用export default
template和style部分好像没有导出。
这时候查到了一个叫Vue Loader的东西,消除了我的疑惑。
文档:https://vue-loader.vuejs.org/zh/
Vue Loader
- 允许为 Vue 组件的每个部分使用其它的 webpack loader,例如在
<style>
的部分使用 Sass 和在<template>
的部分使用 Pug; - 允许在一个 .vue 文件中使用自定义块,并对其运用自定义的 loader 链;
- 使用 webpack loader 将
<style>
和<template>
中引用的资源当作模块依赖来处理; - 为每个组件模拟出 scoped CSS;
- 在开发过程中使用热重载来保持状态。
vue 文件的script 会被解析成es6 的模块。export default 定义封装vue的属性,export 以外的部分也是整个模块的一部分。
这个问题还是没有完全搞明白,前端开发的知识还是太欠缺了。
以上是关于Vue学习笔记 在html文件中创建Vue实例,并使用http-vue-loader注册单文件组件的主要内容,如果未能解决你的问题,请参考以下文章