v-text v-cloak
v-text 等价于 {{}} 用于显示内容,但区别在于{{}} 会造成闪烁问题, v-text 不会闪烁
如果还想用 {{}} 又不想有闪烁问题,则使用 v-cloak 来处理, 步骤如下:
在被 Vue 管理的模板入口节点上作用 v-cloak 指令
添加一个属性选择器 [v-cloak] 的CSS 隐藏样式: [v-cloak] {display: none;}
原理:默认一开始被 Vue 管理的模板是隐藏着的,当 Vue 解析处理完 DOM 模板之后,会自动把这个样式去
除,然后就显示出来。
<style>
/* 将带有 v-clock 属性的标签隐藏 */
[v-clock] {
display: none
}
</style>
</head>
<body>
<div id="app" v-clock>
<!-- v-pre
1. 用于显示双大括号{{}}
2. 跳过这个元素和它的子元素的编译过程,这样可以提高性能。 -->
<span v-pre>{{您好!}}</span>
<!-- 使用双大括号,会有双括号 {{}} 闪烁出来。
可以通过 v-text进行解决闪烁问题
如果我就需要使有双大括号,又不想让它有{{}} 闪烁出来
-->
<h3>{{message}}</h3>
<h3>{{message}}</h3>
<h3>{{message}}</h3>
<h3 v-text="message"></h3>
<h3 v-text="message"></h3>
<h3 v-text="message"></h3>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
message: 'hello word.....'
}
})
</script>
</body>
计算属性computed
computed 选项定义计算属性 计算属性 类似于 methods 选项中定义的函数
- 计算属性 会进行缓存,只在相关响应式依赖发生改变时它们才会重新求值。
- 函数 每次都会执行函数体进行计算。
需求:输入数学与英语分数,采用 methods 与 computed 分别计算出总得分
<body>
<div id="app">
数学:<input type="text" v-model="mathScore" >
英语:<input type="text" v-model="englishScore">
总分(方法-单向):<input type="text" v-model="sumScore()">
总分(计算属性-单向):<input type="text" v-model="sumScore1">
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
mathScore: 80,
englishScore: 90,
},
methods: { //不要少了s
sumScore: function () {
//在控制台输入 vm.sumScore() 每次都会被调用
console.info('sumScore被调用')
// `this` 指向当前 vm 实例, 减 0 是为了字符串转为数字运算
return (this.mathScore-0) + (this.englishScore-0)
}
},
computed: { //计算属性
sumScore1 : function () {
//在控制台输入vm.sumScore1 不会被重新调用,说明计算属性有缓存
console.info('sumScore1被调用')
return (this.mathScore - 0) + (this.englishScore -0)
}
}
})
</script>
</body>
computed 选项内的计算属性默认是 getter 函数,所以上面只支持单向绑定,当修改数学和英语的数据才会
更新总分,而修改总分不会更新数据和英语
计算属性双向绑定
计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter
<body>
<div id="app">
数学:<input type="text" v-model="mathScore" ><br>
英语:<input type="text" v-model="englishScore"><br>
总分(方法-单向):<input type="text" v-model="sumScore()"><br>
总分(计算属性-单向):<input type="text" v-model="sumScore1"><br>
总分(计算属性-双向):<input type="text" v-model="sumScore2"><br>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
mathScore: 80,
englishScore: 90,
},
methods: { //不要少了s
sumScore: function () {
//在控制台输入 vm.sumScore() 每次都会被调用
console.info('sumScore被调用')
// `this` 指向当前 vm 实例, 减 0 是为了字符串转为数字运算
return (this.mathScore-0) + (this.englishScore-0)
}
},
computed: {
//计算属性 默认 getter 只支持单向绑定
sumScore1: function(){
//在控制台输入vm.sumScore1 不会被重新调用,说明计算属性有缓存
console.info('sumScore1被调用')
return (this.mathScore - 0) + (this.englishScore -0)
},
//指定 getter/setter 双向绑定
sumScore2 : {
get: function() {
console.info('sumScore2被调用')
return (this.mathScore-0) + (this.englishScore-0)
},
set: function(newValue) {//value为更新后的值
// 被调用则更新了sumScore2,然后将数学和英语更新为平均分
var avgScore = newValue / 2
this.mathScore = avgScore
this.englishScore = avgScore
}
}
}
})
</script>
</body>
监听器watch
当属性数据发生变化时,对应属性的回调函数会自动调用, 在函数内部进行计算
通过 watch 选项 或者 vm 实例的 $watch() 来监听指定的属性
需求:
- 通过 watch 选项 监听数学分数, 当数学更新后回调函数中重新计算总分sumScore3
- 通过
vm.$watch()选项 监听英语分数, 当英语更新后回调函数中重新计算总分sumScore3
注意: 在data 选择中添加一个 sumScore3 属性
<body>
<div id="app">
数学:<input type="text" v-model="mathScore" ><br>
英语:<input type="text" v-model="englishScore"><br>
总分(方法-单向):<input type="text" v-model="sumScore()"><br>
总分(计算属性-单向):<input type="text" v-model="sumScore1"><br>
总分(计算属性-双向):<input type="text" v-model="sumScore2"><br>
总分(监听器):<input type="text" v-model="sumScore3"><br>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
mathScore: 80,
englishScore: 90,
sumScore3: 170
},
methods: { //不要少了s
sumScore: function () {
//在控制台输入 vm.sumScore() 每次都会被调用
console.log('sumScore被调用')
// `this` 指向当前 vm 实例, 减 0 是为了字符串转为数字运算
return (this.mathScore - 0) + (this.englishScore -0)
}
},
// 计算属性
computed: {
// 默认 getter 只支持单向绑定
sumScore1 : function () {
//在控制台输入 vm.sumScore1 不会被重新调用 ,说明计算属性有缓存
console.log('sumScore1被调用')
return (this.mathScore - 0) + (this.englishScore -0)
},
//指定 getter/setter 双向绑定
sumScore2 : {
get: function () {
console.log('sumScore2被调用')
return (this.mathScore-0) + (this.englishScore-0)
},
set: function (newValue) {//value为更新后的值
// 被调用则更新了sumScore2,然后将数学和英语更新为平均分
var avgScore = newValue / 2
this.mathScore = avgScore
this.englishScore = avgScore
}
}
},
//监听器方式1:watch选项
watch : {
//当数学修改后,更新总分sumScore3
mathScore : function (newValue, oldValue) {
//newValue 就是新输入的数学得分
this.sumScore3 = (newValue-0) + (this.englishScore-0)
}
}
})
//监听器方式2:通过vm对象调用
//第1个参数为监听的属性名,第2个回调函数
vm.$watch('englishScore', function (newValue) {
//newValue 就是新输入的英语得分
this.sumScore3 = (newValue-0) + (this.mathScore-0)
})
</script>
</body>
Class与Style绑定v-bind
通过 class 列表和 style 指定样式是数据绑定的一个常见需求。它们都是元素的属性,都用 v-bind 处理,其中表达 式结果的类型可以是:字符串、对象或数组。
语法格式
v-bind:class='表达式' 或 :class='表达式'
class 的表达式可以为:
- 字符串
:class="activeClass" - 对象
:class="{active: isActive, error: hasError}" - 数组
:class="['active', 'error']"注意要加上单引号,不然是获取data中的值
v-bind:style='表达式' 或 :style='表达式'
style 的表达式一般为对象
:style="{color: activeColor, fontSize: fontSize + 'px'}"
==注意:对象中的value值 activeColor 和 fontSize 是data中的属性==
<body>
<!-- 第2步:定义样式 -->
<style>
.active {
color: green; }
.delete {
background: red; }
.error {
font-size: 30px;
}
</style>
<div id="app">
<h2>Class绑定,v-bind:class 或 :class</h2>
<!--activeClass会从data中获取值为active,则对应样式为绿色-->
<p v-bind:class="activeClass">字符串达式</p>
<!-- isDelete为 true,渲染delete样式;当 hasError为false,不取 error 样式;-->
<p :class="{delete: isDelete, error: hasError}">对象表达式</p>
<!--- 渲染 'active', 'error' 样式,注意要加上单引号,不然是获取data中的值 -->
<p :class="['active', 'error']">数组表达式</p>
<h2>Style绑定, v-bind:style 或 :class</h2>
<p :style="{color: activeColor, fontSize: fontSize + 'px'}">Style绑定</p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
activeClass: 'active',
isDelete: true,
hasError: false,
//演示 Style绑定
activeColor: 'red',
fontSize: 20
}
})
</script>
</body>
条件渲染v-if
条件指令
v-if 是否渲染当前元素
v-else
v-else-if
v-show 与 v-if 类似,只是元素始终会被渲染并保留在 DOM 中,只是简单切换元素的 CSS 属性 display 来显示或隐藏
<body>
<style>
.box {
width: 200px;
height: 200px;
background: red;
}
</style>
<div id="app">
<h2>v-if 条件渲染</h2>
<input v-model="seen" type="checkbox" >勾选后显示红色小块
<!-- v-if 为 true则显示渲染当前元素, -->
<div v-if="seen" class="box" ></div>
<p v-else="seen">红块已隐藏</p>
<h2>v-show 条件渲染</h2>
<!-- v-show 的元素始终会被渲染并保留在 DOM 中,
只是简单切换元素的 CSS 属性 display 显示隐藏,而不是重新加载div-->
<div v-show="seen" class="box" ></div>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
seen: false
}
})
</script>
</body>
v-if 与 v-show 比较
什么时候元素被渲染 v-if 如果在初始条件为假,则什么也不做,每当条件为真时,都会重新渲染条件元素 v-show 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换
使用场景选择 v-if 有更高的切换开销, v-show 有更高的初始渲染开销。 因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行后条件很少改变,则使用 v-if 较好。
列表渲染 v-for
列表渲染指令
v-for 迭代数组
语法: v-for="(alias, index) in array"
说明: alias : 数组元素迭代的别名; index : 数组索引值从0开始(可选) 。
<div v-for="item in items" :key="item.id"></div>
<div v-for="(item, index) in items" :key="item.id"></div>
items 是源数据数组, item 是数组元素迭代的别名。
==注意:使用 key 特殊属性, 它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素==
v-for 迭代对象的属性
语法: v-for="(value, key, index) in Object"
说明: value : 每个对象的属性值; key : 属性名(可选); index : 索引值(可选) 。
<div v-for="value in object" ></div>
<div v-for="(value, key) in object"></div>
<div v-for="(value, key, index) in object"></div>
注意: 在遍历对象时,是按 Object.keys() 的结果遍历,但不能保证它的结果在不同的 JavaScript 引擎下是顺序一致的。
可用 of 替代 in 作为分隔符
<body>
<div id="app">
<h2>1. 迭代数组</h2>
<ul>
<!-- e 为当前对象别名,index 数组下标0开始-->
<li v-for="(e, index) in emps" :key="index">
编号:{{index+1}},姓名:{{e.name}},工资:{{e.salary}}
</li>
</ul>
<br>
<h2>2. 迭代对象</h2>
<ul>
<!-- value是属性值,key是属性名,index索引值-->
<li v-for="(value, key, index) in emps[0]">
第{{index+1}}个属性为:{{key}} = {{value}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
emps:[ //数组
{name: '马云', salary: '20000'},
{name: '马化腾', salary: '18000'},
{name: '刘强东', salary: '13000'}
]
}
})
</script>
</body>
事件处理 v-on
事件处理方法
完整格式: v-on:事件名="函数名" 或 v-on:事件名="函数名(参数……)"
缩写格式: @事件名="函数名" 或 @事件名="函数名(参数……)" ==注意: @ 后面没有冒号==
event :函数中的默认形参,代表原生 DOM 事件
当调用的函数,有多个参数传入时,需要使用原生DOM事件,则通过 $event 作为实参传入
作用:用于监听 DOM 事件
<body>
<div id="app">
<h2>1. 事件处理方法</h2>
<button @click="say">Say {{msg}}</button>
<button @click="warn('hello', $event)">Warn</button>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello, Vue.js'
},
methods: {
say: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert(this.msg)
// `event` 是原生 DOM 事件
alert(event.target.innerHTML)
},
//多个参数如果需要使用原生事件,将 $event 作为实参传入
warn: function (msg, event) {
alert(msg + "," + event.target.tagName)
}
}
})
</script>
</body>
事件修饰符
.stop 阻止单击事件继续传播 event.stopPropagation()
.prevent 阻止事件默认行为 event.preventDefault()
.once 点击事件将只会触发一次
<body>
<div id="app">
<h2>1. 事件处理方法</h2>
<button @click="say">Say {{msg}}</button>
<button @click="warn('hello', $event)">Warn</button>
<br>
<h2>2. 事件修饰符</h2>
<!--单击事件继续传播-->
<div @click="todo">
<!--点击后会调用doThis再调用todo-->
<button @click="doThis">单击事件会继续传播</button>
</div>
<br/>
<!-- 阻止单击事件继续传播,-->
<div @click="todo">
<!--点击后只调用doThis-->
<button @click.stop="doThis">阻止单击事件会继续传播</button>
</div>
<!-- 阻止事件默认行为 -->
<a href="http://www.baidu.com" @click.prevent="doStop">百度</a>
<!-- 点击事件将只会触发一次 -->
<button @click.once="doOnly">点击事件将只会触发一次: {{num}}</button>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello, Vue.js',
num: 1
},
methods: {
say: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert(this.msg)
// `event` 是原生 DOM 事件
alert(event.target.innerHTML)
},
//多个参数如果需要使用原生事件,将 $event 作为实参传入
warn: function (msg, event) {
alert(msg + "," + event.target.tagName)
},
todo: function () {
alert("todo....");
},
doThis: function () {
alert("doThis....");
},
doStop: function () {
alert("href默认跳转被阻止....")
},
doOnly: function() {
this.num++
}
}
})
</script>
</body>
按键修饰符
格式: v-on:keyup.按键名 或 @keyup.按键名
常用按键名:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
<body>
<div id="app">
<h3>1. 事件处理方法 v-on 或 @</h3>
<button v-on:click="say">Say {{msg}}</button>
<!-- $event代表的是原生 的Dom事件 -->
<button @click="warn('hello', $event)">Warn</button>
<h3>2. 事件修饰符</h3>
<!-- 2.1 防止单击事件继续传播 -->
<div @click="todo">
<button @click="doThis">单击事件会继续传播</button>
</div>
<br>
<div @click="todo">
<!-- .stop作用:是阻止事件的传播 -->
<!--点击后只调用doThis-->
<button @click.stop="doThis">阻止单击事件会继续传播</button>
</div>
<br>
<!-- 2.2 阻止事件的默认行为 -->
<a href="https://cn.vuejs.org/" @click.prevent="doStop">vue官方文档</a>
<!-- 2.3 点击事件只会触发一次 -->
<button @click.once="doOnly">点击事件只会触发一次:{{num}}</button>
<br>
<h3>3. 按键修饰符或按键码</h3>
<input type="text" @keyup.enter="keyEnter"><!--进入输入框按回车时调用keyEnter-->
<input type="text" @keyup.space="keySpace"><!--进入输入框按回车时调用keySpace-->
<input type="text" @keyup.13="keyCode">
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg: 'Hello word!!',
num: 0
},
methods: { //定义事件处理函数
say: function (event) {
// event代表的是Dom原生事件, Vue.js它会自动 的将它传入进来,
// `this` 在方法里指向当前 Vue 实例
alert(this.msg)
alert(event.target.innerHTML)
},
warn: function (name, event) {
//如果说函数有多个参数,而双需要使用原生事件,则需要使用 $event 作为 参数传入
alert(name + ',' + event.target.tagName)
},
doThis: function () {
alert('doThis....')
},
todo: function () {
alert('todo....')
},
doStop: function () {
alert('doStop...href默认行为已经被阻止')
},
doOnly: function () {
this.num ++
},
keyEnter: function () {
alert('当前按的是回车键')
},
keySpace: function() {
alert('当前按的是空格键')
},
keyCode: function () {
alert('按的是13')
}
},
})
</script>
</body>
表单数据双向绑定v-model
- 单向绑定:数据变,视图变;视图变(浏览器控制台上更新html),数据不变;上面的都是单向绑定
- 双向绑定:数据变,视图变;视图变(在输入框更新),数据变;
基础用法 v-model 指令用于表单数据双向绑定,针对以下类型: text 文本 textarea 多行文本 radio 单选按钮 checkbox 复选框 select 下拉框
<body>
<div id="demo">
<!-- @submit.prevent 阻止事件的默认行为,当前阻止的是action行为 -->
<form action="#" @submit.prevent="submitForm">
姓名(文本):<input type="text" v-model="name">
<br><br>
性别(单选按钮):
<input name="sex" type="radio" value="1" v-model="sex"/>男
<input name="sex" type="radio" value="0" v-model="sex"/>女
<br><br>
技能(多选框):
<input type="checkbox" name="skills" value="java" v-model="skills">Java开发
<input type="checkbox" name="skills" value="vue" v-model="skills">Vue.js开发
<input type="checkbox" name="skills" value="python" v-model="skills">Python开发
<br><br>
城市(下拉框):
<select name="citys" v-model="city">
<option v-for="c in citys" :value="c.code">
{{c.name}}
</option>
</select>
<br><br>
说明(多行文本):<textarea cols="30" rows="5" v-model="desc"></textarea>
<br><br>
<button type="submit" >提交</button>
</form>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#demo',
data: {
name: '',
sex: '1', //默认选中的是 男
skills: ['vue', 'python'], //默认选中 Vue.js开发 、Python开发
citys: [//初始化下拉框
{code: 'bj', name: '北京'},
{code: 'sh', name: '上海'},
{code: 'gz', name: '广州'}
],
city: 'sh', // 默认选中的城市:上海
desc: ''
},
methods: {
submitForm: function () { //处理提交表单
//发送ajax异步处理
alert(this.name + ', ' + this.sex + ', ' + this.skills + ', ' + this.city + ', ' + this.desc)
}
}
})
</script>
</body>
过渡&动画效果
什么是过渡&动画 元素在显示和隐藏时,实现过滤或者动画的效果。
常用的过渡和动画都是使用 CSS 来实现的
- 在 CSS 中操作 trasition (过滤 )或 animation (动画)达到不同效果
- 为目标元素添加一个父元素 , 让父元素通过自动应用 class 类名来达到效果
过渡与动画时,会为对应元素动态添加的相关 class 类名:
- xxx-enter :定义显示前的效果。
- xxx-enter-active :定义显示过程的效果。
- xxx-enter-to : 定义显示后的效果。
- xxx-leave : 定义隐藏前的效果。
- xxx-leave-active :定义隐藏过程的效果。
- xxx-leave-to :定义隐藏后的效果。
过滤效果案例
1.为目标元素添加父元素 <transition name="xxx">
2.定义 class 过渡样式
- 指定过渡样式: transition
- 指定隐藏时的样式: opacity(持续的时间)/其它
3.功能实现 点击按钮后, 显示隐藏文本 效果1:显示和隐藏有渐变效果 效果2:显示和隐藏的有平移效果,并持续时长不同
<style>
/* 显示或隐藏的过渡效果 */
.mxg-enter-active, .mxg-leave-active {
transition: opacity 1s; /*过渡:渐变效果持续时长1秒 */
}
/* 显示前或隐藏后的效果 */
.mxg-enter, .mxg-leave-to {
opacity: 0; /* 都是隐藏效果 */
}
/* 可以针对显示和隐藏指定不同的效果 */
/* 显示过渡效果 1秒 */
.meng-enter-active {
transition: all 1s; /*all 所有效果,持续1秒*/
}
/* 隐藏过渡效果 5秒 */
.meng-leave-active {
transition: all 5s; /*all 所有效果,持续5秒*/
}
/* 显示前或隐藏后的效果 */
.meng-enter, .meng-leave-to {
opacity: 0; /* 都是隐藏效果 */
transform: translateX(10px); /*水平方向 移动 10px*/
}
</style>
</head>
<body>
<div id="app1">
<button @click="show = !show">渐变过渡</button>
<transition name="mxg">
<p v-show="show" >mengxuegu</p>
</transition>
</div>
<div id="app2">
<button @click="show = !show">渐变平滑过渡</button>
<transition name="meng">
<p v-show="show" >vue</p>
</transition>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app1',
data: {
show: true
}
})
new Vue({
el: '#app2',
data: {
show: true
}
})
</script>
</body>
动画效果案例
CSS 动画用法同 CSS 过渡,只不过采用 animation 为指定动画效果 功能实现: 点击按钮后, 文本内容有放大缩小效果
==注意:官网上面源码有问题,要在 <p> 元素上增加样式 style="display: inline-block"==
<style>
/* 显示过程中的动画效果 */
.bounce-enter-active {
animation: bounce-in 1s;
}
/* 隐藏过程中的动画效果 */
.bounce-leave-active {
animation: bounce-in 1s reverse;
}
@keyframes bounce-in {
0% { /*持续时长百分比,比如针对1s: 0%代表0秒,50%代表0.5*/
transform: scale(0); /*缩小为0*/
}
50% {
transform: scale(1.5); /*放大1.5倍*/
}
100% {
transform: scale(1); /*原始大小*/
}
}
</style>
</head>
<body>
<div id="demo">
<button @click="show = !show">放大缩小动画</button>
<transition name="bounce">
<p v-show="show" >vuejs</p>
</transition>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#demo',
data: {
show: true
}
})
</script>
</body>
自定义指令
自定义指令的作用 除了内置指令外,Vue 也允许注册自定义指令。有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候使用自定义指令更为方便。 自定义指令文档: cn.vuejs.org/v2/guide/cu…
注册与使用自定义指令方式 1.注册全局指令
// 指令名不要带 v-
Vue.directive('指令名', {
// el 代表使用了此指令的那个 DOM 元素
// binding 可获取使用了此指令的绑定值 等
inserted: function (el, binding) {
// 逻辑代码
}
})
2.注册局部指令
directives : {
'指令名' : { // 指令名不要带 v-
inserted (el, binding) {
// 逻辑代码
}
}
}
注意:注册时,指令名不要带 v-
3.使用指令:
引用指令时,指令名前面加上 v-
直接在元素上在使用即可 : v-指令名='表达式'
案例演示 需求: 1.实现输出文本内容全部自动转为大写,字体为红色 ( 功能类型于 v-text , 但显示内容为大写) 2. 当页面加载时,该元素将获得焦点 (注意: autofocus 在移动版 Safari 上不工作)
<body>
<div id="app">
<p v-upper-text="message">xxxxx</p>
自动获取焦点:<input type="text" v-focus>
</div>
<div id="app2">
<p v-upper-text="msg">xxxxx</p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 注册全局自定义指令,可以在多个Vue管理的入口下使用该指令
// 第一个参数为指令名,但是不要有v-开头
// 注册一个全局 v-upper-text 指令
Vue.directive('upper-text',{
//一般对样式 的操作在bind中,bind函数只调用一次
//因为是样式,所以不需要元素插入到DOM中,就好像link引入CSS文件时并不关心元素是否加载
bind: function (el) {
el.style.color = 'red'
},
//一般对js操作在inserted中,inserted也是只调用一次
// el 代表使用了此指令的那个 DOM 元素
// binding用于获取使用了当前指令的绑定值(value)、表达式(expression)、指令名(name)等
inserted: function (el, binding) {
// 将在 v-upper-text 指令中获取到的值,变成大写输出到标签体中
el.innerHTML = binding.value.toUpperCase()
}
})
new Vue({
el: '#app',
data: {
message: '渐进式JavaScript 框架 '
},
//注册局部自定义指令:只能在当前Vue实例管理的入口 下引用这个指令
directives: {//注册一个局部指令 v-focus
'focus': { // 指令名,
bind: function () {
},
//和js行为有关的操作,最好在inserted中执行,和样式相关的操作都可在bind中执行
// 刷新页面自动获取焦点
inserted: function (el, binding) {
//被 v-focus 作用的那个元素在刷新页面后会自动 获取焦点
el.focus()
}
}
}
})
</script>
</body>
Vue 组件化开发
template:定义组件的视图模板
data :在组件中必须是一个函数
Vue.component('组件名',{
template: '定义组件模板',
data: function(){ //data 选项在组件中必须是一个函数
return {}
}
//其他选项:methods
})
<body>
<div id="app">
<!-- 通过组件名直接使用, 不能使用驼峰形式 -->
<component-a></component-a>
</div>
<script src="node_modules/vue/dist/vue.js" type="text/javascript"></script>
<script type="text/javascript">
Vue.component('component-a', {
// template 选项指定此组件的模板代码
template: '<div><h1>头部组件 - {{ name }}</h1></div>',
// data 必须是函数
data: function () {
return {
name: '全局组件'
}
}
})
new Vue({
el: '#app'
})
</script>
</body>
1. JS 对象来定义组件:
var ComponentA = { data: function(){},
template: '组件模板A'}
var ComponentA = { data: function(){},
template: '组件模板A'}
2. 在Vue实例中的 components 选项中引用组件:
new Vue({
el: '#app',
data: {},
components: { // 组件选项
'component-a': ComponentA // key:组件名,value: 引用的组件对象
'component-b': ComponentB
}
})
组件是可复用的 Vue 实例,不需要手动实例化
与 new Vue 接收相同的选项,例如 data 、 computed 、 watch 、 methods 等
组件的 data 选项必须是一个函数
<body>
<div id="app">
<!-- 通过组件名直接使用, 不能使用驼峰形式 -->
<component-b ></component-b>
</div>
<script src="node_modules/vue/dist/vue.js" type="text/javascript"></script>
<script type="text/javascript">
// 定义局部组件对象
var ComponentB = {
template: '<div> 这是:
{{ name }}</div>',
data: function () {
return {
name: '局部组件'
}
}
}
new Vue({
el: '#app',
components: { // 局部组件
'component-b': ComponentB
}
})
</script>
</body>
页面引入组件 js 文件后, 进行使用
Header.js 文件内容
Vue.component('app-header',{
// template 选项指定此组件的模板代码
template: '<div class="header"><h1>头部组件</h1></div>'
})
Main.js 文件内容
Vue.component('app-main',{
// template 选项指定此组件的模板代码
template: '<div class="main"><ul><li>客户管理</li><li>帐单管理</li><li>供应商管理</li></ul><h3></h3>
</div>'
})
Footer.js 文件内容
Vue.component('app-footer',{
// template 选项指定此组件的模板代码
template: '<div class="footer"><h1>底部组件</h1></div>'
})
<body>
<div id="app">
<!-- 通过组件名直接使用 -->
<app-header></app-header>
<app-main></app-main>
<app-footer></app-footer>