一、Vue 实例的基本结构
script标签引入vue.js文件
<div id="app">
<p>{{msg}}<p>
</div>
// script标签内容:
var vm = new Vue({
el: '#app',
data: {
//页面响应的数据都放在这里,
msg: ' ',
},
props:{
//props 可以是数组或对象,接收任何值
},
methods: {
//页面或组件定义的方法的集合
},
computed: {
//计算属性(computed)与方法(methods) 类似,如果计算数据量比较大,建议放到这里
},
components:{
// 局部组件注册的地方
'component-a': ComponentA,
'component-b': ComponentB
},
directives: {
// 局部指令注册的地方
focus: {
// 指令的定义
inserted: function (el,binding) {
el.focus();
}
}
},
filters:{
// 局部过滤器注册的地方
},
二、Vue 事件处理、绑定属性
v-on:
1、绑定事件监听器。
如:click、keyup/down、mouseenter/over/move/down/out 等。
也可以监听自定义事件即 methods 里面的事件。
在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 event)"。
常用修饰符:
.stop - 调用 event.stopPropagation()。阻止冒泡
.prevent - 调用 event.preventDefault()。阻止默认事件
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
用法:
内联语句
<button v-on:click="doThat('hello', $event)"></button>
缩写
<button @click="doThis"></button>
停止冒泡
<button @click.stop="doThis"></button>
对象语法
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
v-on 还提供了按键修饰
键盘按钮的别名
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
2、v-bind: 动态地绑定一个或多个特性,或一个组件 prop 到表达式。
绑定一个属性
<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>
三、Vue 指令、自定义指令、
Vue指令:
v-text:
<span v-text="msg"></span>
<span>{{msg}}</span>
v-html://输出真正的 HTML
<div v-html="html"></div>
data{
html:'<strong>我是真正的html</strong>'
}
v-show://根据表达式之真假值,切换元素的 display CSS 属性。
<h1 v-show="ok">Hello!</h1>
v-if、v-if-else、v-else:
//v-if 是“真正”的条件渲染,如果条件为假,dom不会渲染在页面当中
//v-show 会一直渲染在dom当中
//当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。
<h1 v-if="ok">Yes</h1>
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
v-for://基于源数据多次渲染元素或模板块。
<div v-for="item in items">
{{ item.text }}
</div>
//另外也可以为数组索引指定别名 (或者用于对象的键):val->对象的键值 key->对象的键 index->对象的下标
<div v-for="(item, index) in items"></div>
<div v-for="(val, key) in object"></div>
<div v-for="(val, key, index) in object"></div>
v-model:作用于<input>、<select>、<textarea>,
当v-model作用于多个复选框、当选择按钮、选择框时,都是把这些标签的value值赋值给v-model的变量
修饰符:
.lazy - 取代 input
监听 change
事件
.number- 输入字符串转为数字
.trim- 输入首尾空格过滤
<input v-model="message" placeholder="edit me">
<textarea v-model="message" placeholder="add multiple lines"></textarea>
// 选择框
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
// 用 v-for 渲染的动态选项:
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
v-once:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
单个元素
<span v-once>This will never change: {{msg}}</span>
有子元素
<div v-once>
<h1>comment</h1>
<p>{{msg}}</p>
</div>
组件
<my-component v-once :comment="msg"></my-component>
v-for
指令
<ul>
<li v-for="i in list" v-once>{{i}}</li>
</ul>
Vue自定义指令:
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update
:1、所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。
2、指令的值可能发生了改变,也可能没有。
3、你可以通过比较更新前后的值来忽略不必要的模板更新
componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind
:只调用一次,指令与元素解绑时调用。
el
:指令所绑定的元素,可以用来直接操作 DOM 。
binding
:一个对象,包含以下属性:
name
:指令名,不包括 v-
前缀。
value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为 2
。
oldValue
:指令绑定的前一个值,仅在 update
和 componentUpdated
钩子中可用。无论值是否改变都可用。
expression
:字符串形式的指令表达式。例如 v-my-directive="1 + 1"
中,表达式为 "1 + 1"
。
arg
:传给指令的参数,可选。例如 v-my-directive:foo
中,参数为 "foo"
。
modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为 { foo: true, bar: true }
。
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el,binding) {
// 聚焦元素
el.focus();
console.log(binding.value) //=>666
}
})
//如果想注册局部指令,组件中也接受一个 directives 的选项:
directives: {
focus: {
// 指令的定义
inserted: function (el,binding) {
el.focus();
console.log(binding.value) //=>666
}
}
}
四、Vue 过滤器
Vue 过滤器的用法
过滤器可以用在两个地方:双花括号插值和 v-bind 表达式
与指令的用法类似,但过滤器一定要有返回值,也不支持链式调用
// 在双花括号中
{{ message | capitalize }}
// 在 v-bind
中
<div v-bind:id="rawId | formatId"></div>
// 局部注册过滤器
filters: {
// 首字母大写
capitalize: function (value) {
// value 就是 ‘|’ 符号前面的值
if (!value) return '';
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
// 注册全局过滤器
Vue.filter('capitalize', function (value) {
if (!value) return '';
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
// 过滤器传值
{{ number | dual(2) }}
Vue.filter('dual', function (value,type) {
// 回调函数里面默认有 value ,在页面上传过来的值会依次添加在后面
console.log(type) // => 2
if (!value) return '';
if (typeof value !== "number") return alert(value + ' 不是数字');
if( parseInt(type) === 2 ){
return value = value > 10 ? value : '0' + value
}
return value
})
// 过滤器的插件用法,与 directives.js 一致
// main.js
import directives from './filters.js'
Vue.use(filters);
// filters.js
export default {
install(Vue){
Vue.filter('dual', function (value,type) {
if (!value) return '';
if (typeof value !== "number") return alert(value + ' 不是数字');
if( parseInt(type) === 2 ){
return value = value > 10 ? value : '0' + value
}
return value
})
}
}
五、Vue 数据监听
Vue 数据监听 watch
// watch 基本用法与注意事项
data: {
a: 1,
e: {
f: {
g: 5
}
},
items: [
{ message: 'Foo' },
{ message: 'Bar' }
],
}
mounted: function(){
this.a = 2;
this.e.f.g = 10;
this.set 赋值
this.items[0] = { message: 'AAA' }; // 直接赋值
},
watch: {
// 最简单最直接的监听方式,能监听简单的数据变化,这种方法默认就是执行 handler: function(){}
// 注意:这种方式监听不到对象的变化
a: function(val, oldVal){
console.log(val); // => 变化之后的数据
console.log(oldVal); // => 变化之前的数据
},
// 深度监听,这里要注意一下,这样的方式打印出来两个值都是变化之后的值
// deep 的值默认为false,如果不写或者deep: false 都不能监听到对象值的变化
e: {
handler: function (val, oldVal) {
console.log(val); // => 变化之后的数据
console.log(oldVal); // => 变化之后的数据
},
deep: true,
},
// 如果要精准监听的对象值的变化,可以用这种方法
'e.f.g': function (val, oldVal) {
console.log(val); // => 变化之后的数据
console.log(oldVal); // => 变化之前的数据
},
// 监听数组
// 由于 JavaScript 的限制,Vue 不能检测 this.items[0] = { message: 'AAA' }; 这种方式赋值的变化
// 所以你要用 $set、或者数组变异的方法赋值
items: function(val, oldVal){
console.log(val); // => 变化之后的数据
console.log(oldVal); // => 变化之后的数据
},
}
六、Vue 组件
Vue 组件基础
组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods等。
Vue.component( 组件名 ,{ 选项 }) 全局注册
// 全局注册组件的时候必须写在Vue实例创建之前
// 下面这几种方式是等价的
import Vue from 'vue'
var MyComponent = Vue.extend({
template:"<h1>我是全局组件</h1>"
});
Vue.component("my-component",MyComponent);
// 注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({ /* ... / }))
// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', { / ... */ })
// 一个定义模板的方式是在一个 <script> 元素中,并为其带上 text/x-template 的类型,然后通过一个 id 将模板引用过去。
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
// 另一个定义模板的方式是在一个 <template> 元素中,通过一个 id 将模板引用过去;在单文件组件 .vue 当中,id可以省略;
<template id="hello-world-template">
<p>Hello hello hello</p>
</template>
Vue.component("my-component",{
template:"#hello-world-template"
});
局部注册组件
// 每个vue 实例都会有一个 components 的选项,而组件是可复用的 Vue 实例,所以每个组件都有components 选项
// 引入外部文件注册成局部组件
import home from './components/home/home'
new Vue({
el:"#app",
components: {
home, // 等价于home: home,ES6对象中属性的简洁表示,ES6(http://es6.ruanyifeng.com/#docs/object)
}
});
// 直接在components 选项中写,(不推荐这种用法)
new Vue({
el:"#app",
components: {
loading: {
data: function () {
return {
getting: 'welcome'
}
},
components:{
// 这里还可以嵌套局部组件...
}
}
}
});
Vue.component('my-component', {
props: {
// 基础的类型检查 (null
匹配任何类型)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组且一定会从一个工厂函数返回默认值
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})