1.Vue.js 是什么?
网址:https://vuejs.org/
Vue.js(读音 /vjuː/,类似于 view 的读音)是一套构建用户界面(user interface)的渐进式框架。与其他重量级框架不同的是,Vue 从根本上采用最小成本、渐进增量(incrementally adoptable)的设计。Vue 的核心库只专注于视图层,并且很容易与其他第三方库或现有项目集成。另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供有力驱动。
声明式渲染
Vue.js 的核心是,可以采用简洁的模板语法来声明式的将数据渲染为 DOM:
<div id="app">
|
var app = new Vue({
|
el:template render
data:view ->property
mehtods: views-> events
template: string template
render: createElement
computed:
watch:function(new,old){} hook newold-oldnew
el
-
类型:
string | HTMLElement
-
限制:只在由
new
创建的实例中遵守。 -
详细:
提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。
在实例挂载之后, 元素可以用
vm.$el
访问。如果这个选项在实例化时有作用,实例将立即进入编译过程,否则,需要显式调用
vm.$mount()
手动开启编译。提供的元素只能作为挂载点。不同于 Vue 1.x,所有的挂载元素会被 Vue 生成的 DOM 替换。因此不推荐挂载root实例到
<html>
或者<body>
上。如果
render
函数和template
属性都不存在,挂载 DOM 元素的 HTML 会被提取出来用作模板,此时,必须使用 Runtime + Compiler 构建的 Vue 库。
data
-
类型:
Object | Function
-
限制:组件的定义只接受
function
。 -
详细:
Vue 实例的数据对象。Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。对象必须是纯粹的对象(含有零个或多个的key/value对):浏览器 API 创建的原生对象,原型上的属性会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。
一旦观察过,不需要再次在数据对象上添加响应式属性。因此推荐在创建实例之前,就声明所有的根级响应式属性。
实例创建之后,可以通过
vm.$data
访问原始数据对象。Vue 实例也代理了 data 对象上所有的属性,因此访问vm.a
等价于访问vm.$data.a
。以
_
或$
开头的属性 不会 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、 API 方法冲突。你可以使用例如vm.$data._property
的方式访问这些属性。在定义一个组件时,
data
必须声明为一个返回初始数据对象的函数,因为可能会使用此函数创建多个实例。如果data
是一个普通对象,则所有创建出来的实例将共享引用同一个数据对象!通过提供data
函数,每次创建一个新实例后,我们能够调用data
函数,从而返回初始数据的一个全新的 data 对象副本。如果需要,可以通过将
vm.$data
传入JSON.parse(JSON.stringify(...))
得到深拷贝的原始数据对象。 -
示例:
var data = { a: 1 }
// 直接创建一个实例
var vm = new Vue({
data: data
})
vm.a // => 1
vm.$data === data // => true
// Vue.extend() 中 data 必须是函数
var Component = Vue.extend({
data: function () {
return { a: 1 }
}
})注意,如果你对
data
属性使用箭头函数,this
将不会指向组件实例,但是你仍然可以通过函数返回的第一个参数,来访问组件实例:data: vm => ({ a: vm.myProp })
template
-
类型:
string
-
详细:
一个字符串模板作为 Vue 实例的标识使用。模板将会 替换 挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发 slot。
如果值以
#
开始,则它用作选项符,将使用匹配元素的 innerHTML 作为模板。常用的技巧是用<script type="x-template">
包含模板。出于安全考虑,你应该只使用你信任的 Vue 模板。避免使用其他人生成的内容作为你的模板。
如果 Vue 选项中包含 render 函数,template 选项将被忽略。
-
参考:
render
-
类型:
(createElement: () => VNode) => VNode
-
详细:
字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。render 函数接收一个
createElement
方法作为第一个参数用来创建VNode
。如果组件是一个函数组件,render 函数还会接收一个额外的
context
参数,为没有实例的函数组件提供上下文信息。Vue 选项中的
render
函数若存在,则 Vue 构造函数不会从template
选项或通过el
选项指定的挂载元素中提取出的 HTML 模板编译 render 函数。 -
computed
-
类型:
{ [key: string]: Function | { get: Function, set: Function } }
-
详细:
计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。
注意,如果你对
data
属性使用箭头函数,this
将不会指向组件实例,但是你仍然可以通过函数返回的第一个参数,来访问组件实例:computed: {
aDouble: vm => vm.a * 2
}计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果实例范畴之外的依赖 (比如非响应式的 not reactive) 是不会触发计算属性更新的。
-
示例:
var vm = new Vue({
data: { a: 1 },
computed: {
// 只获取
aDouble: function () {
return this.a * 2
},
// 获取和设置
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
vm.aPlus // => 2
vm.aPlus = 3
vm.a // => 2
vm.aDouble // => 4 -
参考:计算属性
methods
-
类型:
{ [key: string]: Function }
-
详细:
methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的
this
自动绑定为 Vue 实例。注意,不应该使用箭头函数来定义 method 函数 (例如
plus: () => this.a++
)。理由是箭头函数绑定了父级作用域的上下文,所以this
将不会按照期望指向 Vue 实例,this.a
将是 undefined。 -
示例:
var vm = new Vue({
data: { a: 1 },
methods: {
plus: function () {
this.a++
}
}
})
vm.plus()
vm.a // 2 -
参考:事件处理
watch
-
类型:
{ [key: string]: string | Function | Object | Array}
-
详细:
一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用
$watch()
,遍历 watch 对象的每一个属性。 -
示例:
var vm = new Vue({
data: {
a: 1,
b: 2,
c: 3,
d: 4,
e: {
f: {
g: 5
}
}
},
watch: {
a: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
},
// 字符串方法名
b: 'someMethod',
// 深度 watcher
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},
// 回调函数会将在观察(data observer)开始后立即被调用
d: {
handler: function (val, oldVal) { /* ... */ },
immediate: true
},
e: [
function handle1 (val, oldVal) { /* ... */ },
function handle2 (val, oldVal) { /* ... */ }
],
// watch vm.e.f's value: {g: 5}
'e.f': function (val, oldVal) { /* ... */ }
}
})
vm.a = 2 // => new: 2, old: 1注意,不应该使用箭头函数来定义 watcher 函数 (例如
searchQuery: newValue => this.updateAutocomplete(newValue)
)。理由是箭头函数绑定了父级作用域的上下文,所以this
将不会按照期望指向 Vue 实例,this.updateAutocomplete
将是 undefined。
-
2.2、钩子函数的执行
<!DOCTYPE html> <html> <head> <title></title> <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script> </head> <body> <div id="app"> <p>{{ message }}</p> </div> <script type="text/javascript"> var app = new Vue({ el: '#app', data: { message : "xuxiao is boy" }, beforeCreate: function () { console.group('beforeCreate 创建前状态===============》'); console.log("%c%s", "color:red" , "el : " + this.$el); //undefined console.log("%c%s", "color:red","data : " + this.$data); //undefined console.log("%c%s", "color:red","message: " + this.message) }, created: function () { console.group('created 创建完毕状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); //undefined console.log("%c%s", "color:red","data : " + this.$data); //已被初始化 console.log("%c%s", "color:red","message: " + this.message); //已被初始化 }, beforeMount: function () { console.group('beforeMount 挂载前状态===============》'); console.log("%c%s", "color:red","el : " + (this.$el)); //已被初始化 console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); //已被初始化 console.log("%c%s", "color:red","message: " + this.message); //已被初始化 }, mounted: function () { console.group('mounted 挂载结束状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); //已被初始化 console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); //已被初始化 console.log("%c%s", "color:red","message: " + this.message); //已被初始化 }, beforeUpdate: function () { console.group('beforeUpdate 更新前状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, updated: function () { console.group('updated 更新完成状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, beforeDestroy: function () { console.group('beforeDestroy 销毁前状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, destroyed: function () { console.group('destroyed 销毁完成状态===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message) } }) </script> </body> </html>
3.指令
v-for
列表渲染
使用 v-for
遍历数组生成元素
我们可以使用 v-for
指令,将一个数组渲染为列表项。v-for
指令需要限定格式为 item in items
的特殊语法,其中,items
是原始数据数组(source data array),而 item
是数组中每个迭代元素的指代别名(alias):
<ul id="example-1">
|
var example1 = new Vue({
|
结果:
- Foo
- Bar
在 v-for
代码块中,我们可以完全地访问父级作用域下的属性。v-for
还支持可选的第二个参数,作为当前项的索引。
<ul id="example-2">
|
var example2 = new Vue({
|
结果:
- Parent - 0 - Foo
- Parent - 1 - Bar
你还可以不使用 in
,而是使用 of
作为分隔符,因为它更加接近 JavaScript 迭代器语法:
<div v-for="item of items"></div>
|
使用 v-for
遍历对象
也可以使用 v-for
来遍历对象的属性。
<ul id="v-for-object" class="demo">
|
new Vue({
|
结果:
- John
- Doe
- 30
还可以提供第二个参数,作为对象的键名(key):
<div v-for="(value, key) in object">
|
然后第三个参数作为索引(index):
<div v-for="(value, key, index) in object">
|
v-text
-
期望类型:
string
-
详细:
更新元素的
textContent
。如果要更新部分的textContent
,需要使用{{ Mustache }}
插值。 -
示例:
<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>
v-model
-
期望类型:随表单控件类型不同而不同。
-
限制:
<input>
<select>
<textarea>
- components
-
修饰符:
-
用法:
在表单控件或者组件上创建双向绑定。细节请看下面链接的教程。
v-html
-
期望类型:
string
-
详细:
更新元素的
innerHTML
。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译 。如果试图使用v-html
组合模板,可以重新考虑是否通过使用组件来替代。在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用
v-html
,永不用在用户提交的内容上。在 单文件组件 中,
scoped
样式不会应用在v-html
内部,因为这些 HTML 没有被 Vue 模板编译器处理过。如果你希望针对v-html
中的内容设置带作用域的 CSS,作为替代你可以使用 CSS 模块,或者使用一个额外的全局<style>
元素,手动设置类似 BEM 的作用域策略。 -
示例:
<div v-html="html"></div>
v-on
-
缩写:
@
-
期望类型:
Function | Inline Statement | Object
-
参数:
event
-
修饰符:
.stop
- 调用event.stopPropagation()
。.prevent
- 调用event.preventDefault()
。.capture
- 添加事件侦听器时使用 capture 模式。.self
- 只当事件是从侦听器绑定的元素本身触发时才触发回调。.{keyCode | keyAlias}
- 只当事件是从特定键触发时才触发回调。.native
- 监听组件根元素的原生事件。.once
- 只触发一次回调。.left
- (2.2.0) 只当点击鼠标左键时触发。.right
- (2.2.0) 只当点击鼠标右键时触发。.middle
- (2.2.0) 只当点击鼠标中键时触发。.passive
- (2.3.0) 以{ passive: true }
模式添加侦听器
-
用法:
绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
用在普通元素上时,只能监听 原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个
$event
属性:v-on:click="handle('ok', $event)"
。从 2.4.0+ 开始,
v-on
同样支持不带参数绑定一个事件/监听器键值对的对象。注意,当使用对象语法时,不支持任何修饰符。 -
示例:
<!-- 方法处理器 -->
<button v-on:click="doThis"></button>
<!-- 内联语句 -->
<button v-on:click="doThat('hello', $event)"></button>
<!-- 缩写 -->
<button @click="doThis"></button>
<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>
<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>
<!-- 阻止默认行为,没有表达式 -->
<form @submit.prevent></form>
<!-- 串联修饰符 -->
<button @click.stop.prevent="doThis"></button>
<!-- 键修饰符,键别名 -->
<input @keyup.enter="onEnter">
<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">
<!-- 点击回调只会触发一次 -->
<button v-on:click.once="doThis"></button>
<!-- 对象语法(2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>在子组件上监听自定义事件(当子组件触发 “my-event” 时将调用事件处理器):
<my-component @my-event="handleThis"></my-component>
<!-- 内联语句 -->
<my-component @my-event="handleThis(123, $event)"></my-component>
<!-- 组件中的原生事件 -->
<my-component @click.native="onClick"></my-component>
v-bind
-
缩写:
:
-
期望类型:
any (with argument) | Object (without argument)
-
参数:
attrOrProp (optional)
-
修饰符:
.prop
- 被用于绑定 DOM 属性(有什么不同?)。如果标签是一个组件,那么.prop
将在组件的$el
上设置属性。.camel
- (2.1.0+) transform the kebab-case attribute name into camelCase..sync
- (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的v-on
侦听器。
-
用法:
动态地绑定一个或多个特性,或一个组件 prop 到表达式。
在绑定
class
或style
特性时,支持其它类型的值,如数组或对象。可以通过下面的教程链接查看详情。在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。
没有参数时,可以绑定到一个包含键值对的对象。注意此时
class
和style
绑定不支持数组和对象。 -
示例:
<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">
<!-- 缩写 -->
<img :src="imageSrc">
<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">
<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">
<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- 通过 prop 修饰符绑定 DOM 属性 -->
<div v-bind:text-content.prop="text"></div>
<!-- prop 绑定. “prop” 必须在 my-component 中声明。 -->
<my-component :prop="someThing"></my-component>
<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>
<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>.camel
修饰符允许在使用 DOM 模板时将v-bind
属性名称驼峰化,例如 SVG 的viewBox
属性:<svg :view-box.camel="viewBox"></svg>
在使用字符串模板或通过
vue-loader
/vueify
编译时,无需使用.camel
。
v-cloak
-
不需要表达式
-
用法:
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如
[v-cloak] { display: none }
一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。 -
示例:
[v-cloak] {
display: none;
}<div v-cloak>
{{ message }}
</div>不会显示,直到编译结束。
组件化
项目目录
最开始是MVC模式,这里
vue学习之路之MVC,MVP,MVVM之间的区别和联系
M代表的是model负责提供数据,V是视图view,C 代表控制器,他们之间是单向通信,V和M之间的通信是通过C来作为桥梁的,也就是说V和M并不是直接通信;
而且比angular清凉的多。
vue总结
https://www.cnblogs.com/caojiayan/p/6282974.html
https://www.cnblogs.com/whocare/p/6528618.html
vue脚手架的使用
https://www.cnblogs.com/libin-1/p/6833373.html
https://blog.csdn.net/hhzzcc_/article/details/79251027
全栈工程师的参考文档
http://www.100phone.cn/category/vue2/