内部指令
项目搭建
//安装
npm install live-server -g
//打开
live-server
v-if v-else v-show
v-if : 用来判断是否加载html的DOM
v-show : 则是通过css来控制
<body>
<h1>v-if&v-else&v-show</h1>
<hr>
<div id="app">
<div v-if="isLogin">已登录</div>
<div v-else>未登录</div>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
isLogin : false
}
})
</script>
</body>
v-for
v-for指令是循环渲染一组data中的数组,v-for 指令需要以 item in items 形式的特殊语法,items 是源数据数组并且item是数组元素迭代的别名
数组和对象的循环
<body>
<h1>v-for</h1>
<hr>
<div id="app">
<ul>
<li v-for="item in sortItems">
{{item}}
</li>
</ul>
<ul>
<li v-for="(student,index) in sortStudents">
{{index}} : {{student.name}}--{{student.age}}
</li>
</ul>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
//数组排序
items : [2,31,52,4,456,34,18,5],
//对象排序
students : [
{name:'greentea',age:24},
{name:'wang',age:1},
{name:'klaus',age:22}
]
},
computed : {
sortItems : function(){
return this.items.sort(sortNumber); //从小到大排列
},
sortStudents : function(){
return sortByKey(this.students,'age');
}
}
});
function sortNumber(a,b){
return a-b;
}
//数组对象方法排序:
function sortByKey(array,key){
return array.sort(function(a,b){
var x=a[key];
var y=b[key];
return ((x<y)?-1:((x>y)?1:0));
});
}
</script>
</body>
v-text & v-html
v-text和{{}}的效果相同,{{}}的弊端就是当我们网速很慢或者javascript出错时,会暴露我们的{{xxx}}
v-html 可以输出带html标签的内容,也就是当内容有html标签的时候,是可以识别的
<span>{{ message }}</span>=<span v-text="message"></span><br/>
<span v-html="theHtml"></span>
v-on
v-on 就是监听事件,可以用v-on指令监听DOM事件来触发一些javascript代码。
<body>
<h1>v-on</h1>
<hr>
<div id="app">
number:{{score}}
<p>
<button v-on:click="add">add</button>
<button @click="minus">minus</button>
<input type="text" @keyup.enter="onEnter" v-model="score2">
<!--<input type="text" @keyup.13="onEnter" v-model="score2">-->
</p>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
score : 0,
score2 : 1
},
methods : {
add : function(){
this.score++;
},
minus : function () {
this.score--;
},
onEnter : function () {
this.score = this.score + parseInt(this.score2);
}
}
})
</script>
</body>
v-model
就是把数据绑定在特定的表单元素上,可以很容易的实现双向数据绑定。
<body>
<h1>v-model</h1>
<hr>
<div id="app">
<h4>文本框</h4>
<p>{{message}}</p>
<br>
<p><input type="text" v-model="message"></p>
<p><input type="text" v-model.lazy="message"><span>失去焦点后改变</span></p>
<p><input type="text" v-model.number="message"><span>必须是数字,最先输入的是字符串就失效了</span></p>
<p><input type="text" v-model.trim="message"><span>去空格</span></p>
<hr>
<h4>文本域</h4>
<textarea name="" id="" cols="30" rows="10" v-model="message"></textarea>
<h4>多选框绑定一个值</h4>
<input type="checkbox" id="isYes" v-model="isTrue">
<label for="isYes">{{isTrue}}</label>
<hr>
<h4>多选框绑定数组</h4>
<p>
<input type="checkbox" id="greentea" value="greentea" v-model="names">
<label for="greentea">greentea</label>
<input type="checkbox" id="wang" value="wang" v-model="names">
<label for="wang">wang</label>
<input type="checkbox" id="klaus" value="klaus" v-model="names">
<label for="klaus">klaus</label>
</p>
<p>{{names}}</p>
<hr>
<h4>单选框绑定</h4>
<p>
<input type="radio" id="one" value="male" v-model="sex">
<label for="one">male</label>
<input type="radio" id="two" value="female" v-model="sex">
<label for="two">female</label>
<p>已选择:{{sex}}</p>
</p>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
message : 'hello world',
isTrue : true,
names : [],
sex : 'male'
}
})
</script>
</body>
v-bind
v-bind是处理HTML中的标签属性的
<body>
<h1>v-bind</h1>
<hr>
<div id="app">
<p>![](imgSrc)</p>
<p><a :href="myBlog" target="_blank">me</a></p>
<hr>
<div :class="className">1.绑定class</div>
<div :class="{classA:isTrue}">2.绑定class中的判断</div>
<div :class="[classA,classB]">3.绑定class中的数组</div>
<div :class="isTrue?classA:classB">4.绑定class中的三元运算符</div>
<hr>
<div>
<input type="checkbox" id="theInput" v-model="isTrue">
<label for="theInput">istrue={{isTrue}}</label>
</div>
<hr>
<div :style="{color:red,fontSize:font}">5.绑定style</div>
<div :style="styleObject">6.对象绑定style</div>
</div>
<style>
.classA{
color : red;
}
.classB{
font-size: 200%;
}
</style>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
imgSrc : 'https://cn.vuejs.org/images/logo.png',
myBlog : 'http://www.guoqianchen.com',
className : 'classA',
isTrue : true,
classA : 'classA',
classB : 'classB',
red:'red',
font:'20px',
styleObject : {
color : 'green',
fontSize : '24px'
}
}
})
</script>
</body>
其他内部指令
v-pre 在模板中跳过vue的编译,直接输出原始值
v-cloak 在vue渲染完指定的整个DOM后才进行显示,它必须和CSS样式一起使用
v-once 在第一次DOM时进行渲染,渲染完成后视为静态内容
<body>
<h1>v-pre&v-cloak&v-once</h1>
<hr>
<div id="app">
<div v-pre>{{message}}</div>
<div v-cloak>渲染完成后显示</div>
<div v-once>{{message}}</div>
<div><input type="text" v-model="message"></div>
<div>{{message}}</div>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
message : 'hello world'
}
})
</script>
</body>
全局API
什么是全局API
全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API.说的简单些就是,在构造器外部用Vue提供给我们的API函数来定义新的功能.
1. Vue.directive自定义指令
Vue.directive('jspang',function(el,binding,vnode){
el.style='color:'+binding.value;
});
自定义指令中的三个参数
el: 指令所绑定的元素,可以用来直接操作DOM。
binding: 一个对象,包含指令的很多信息。
vnode: Vue编译生成的虚拟节点。
自定义指令的生命周期
自定义指令有五个生命周期(也叫钩子函数),分别是 bind,inserted,update,componentUpdated,unbind
bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。
inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。
update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
unbind:只调用一次,指令与元素解绑时调用。
<body>
<h1>Vue.directive 自定义指令</h1>
<hr>
<div id="app">
<div v-greentea="color">{{num}}</div>
<p><button @click="add">ADD</button></p>
<p><button onclick="unbind()">解绑</button></p>
</div>
<script src="../assets/js/vue.js"></script>
<script>
function unbind(){
app.$destroy();
}
Vue.directive("greentea",{
bind:function(el,binding){//被绑定
console.log('1 - bind');
el.style = "color:"+binding.value;
},
inserted:function(){//绑定到节点
console.log('2 - inserted');
},
update:function(){//组件更新
console.log('3 - update');
},
componentUpdated:function(){//组件更新完成
console.log('4 - componentUpdated');
},
unbind:function(){//解绑
console.log('5 - unbind');
}
})
var app = new Vue({
el : '#app',
data : {
num : 10,
color : 'red'
},
methods : {
add : function () {
this.num++
}
}
})
</script>
</body>
2. Vue.extend构造器的延伸
Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的Vue实例构造器。经常服务于Vue.component用来生成组件,可以简单理解为当在模板中遇到该组件名称作为标签的自定义元素时,会自动调用“扩展实例构造器”来生产组件实例,并挂载到自定义元素上。
<body>
<h1>Vue.extend</h1>
<hr>
<div id="author"></div>
<author></author>
<script src="../assets/js/vue.js"></script>
<script>
var authorExtend = Vue.extend({
template : "<p><a :href='authorURL'>{{authorName}}</a></p>",
data : function(){
return {
authorName : 'greentea',
authorURL : 'http://www.guoqianchen.com'
}
}
});
new authorExtend().$mount('#author');
new authorExtend().$mount('author');
</script>
</body>
3. Vue.set全局操作
Vue.set 的作用就是在构造器外部操作构造器内部的数据、属性或者方法。比如在vue构造器内部定义了一个count为1的数据,我们在构造器外部定义了一个方法,要每次点击按钮给值加1.就需要用到Vue.set。
引用构造器外部数据
//在构造器外部声明数据
var outData={
count:1,
goodName:'car'
};
var app=new Vue({
el:'#app',
//引用外部数据
data:outData
})
在外部改变数据的三种方法
<body>
<h1>helloworld</h1>
<hr>
<div id="app">
{{count}}
</div>
<p><button onclick="add()">ADD</button></p>
<script src="../assets/js/vue.js"></script>
<script>
function add(){
//Vue.set(outdata,'count',3); //使用Vue.set改变
//app.count++; //用Vue对象的方法添加
outdata.count++; //直接操作外部数据
}
var outdata = {
count : 1,
goods : 'book'
}
var app = new Vue({
el : '#app',
data : outdata
})
</script>
</body>
为什么要有Vue.set的存在
由于Javascript的限制,Vue不能自动检测以下变动的数组。
当你利用索引直接设置一个项时,vue不会为我们自动更新。
当你修改数组的长度时,vue不会为我们自动更新。
<body>
<h1>helloworld</h1>
<hr>
<div id="app">
{{count}}
<ul>
<li v-for="item in arr">{{item}}</li>
</ul>
</div>
<p><button onclick="add()">ADD</button></p>
<script src="../assets/js/vue.js"></script>
<script>
function add(){
//Vue.set(outdata,'count',3); //使用Vue.set改变
//app.count++; //用Vue对象的方法添加
//outdata.count++; //直接操作外部数据
// app.arr[1] = 'ddd'; //无法改变数组的值
Vue.set(app.arr,1,'ddd');
}
var outdata = {
count : 1,
// goods : 'book'
arr : ['aaa','bbb','ccc']
}
var app = new Vue({
el : '#app',
data : outdata
})
</script>
</body>
这时我们的界面是不会自动跟新数组的,我们需要用Vue.set(app.arr,1,’ddd’)来设置改变,vue才会给我们自动更新,这就是Vue.set存在的意义。
4. Vue的生命周期(钩子函数)
Vue一共有10个生命周期函数,利用这些函数在vue的每个阶段都进行操作数据或者改变内容。
<body>
<h1>life cycle</h1>
<hr>
<div id="app">
{{count}}
<p><button @click="add">ADD</button></p>
</div>
<button onclick="app.$destroy()">destroy</button>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
count : 1
},
methods : {
add : function(){
this.count++
}
},
beforeCreate:function(){
console.log('1-beforeCreate 初始化之前');
},
created:function(){
console.log('2-created 创建完成');
},
beforeMount:function(){
console.log('3-beforeMount 挂载之前');
},
mounted:function(){
console.log('4-mounted 被挂载之后');
},
beforeUpdate:function(){
console.log('5-beforeUpdate 数据更新前');
},
updated:function(){
console.log('6-updated 被更新后');
},
activated:function(){
console.log('7-activated');
},
deactivated:function(){
console.log('8-deactivated');
},
beforeDestroy:function(){
console.log('9-beforeDestroy 销毁之前');
},
destroyed:function(){
console.log('10-destroyed 销毁之后')
}
})
</script>
</body>
5. Template制作模板
选项里的模板
<body>
<h1>template</h1>
<hr>
<div id="app">
{{message}}
</div>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
message : 'hello world'
},
template : `
<h2 style="color:red">我是选项模板</h2>
`
})
</script>
</body>
写在Template里的模板
<body>
<h1>template</h1>
<hr>
<div id="app">
{{message}}
</div>
<template id="dd2">
<h2 style="color:red">我是Template标签模板</h2>
</template>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
message : 'hello world'
},
template:'#dd2'
})
</script>
</body>
写在<script>标签里的模板
<body>
<h1>template</h1>
<hr>
<div id="app">
{{message}}
</div>
<script src="../assets/js/vue.js"></script>
<script type="x-template" id="dd3">
<h2 style="color:red">我是script标签模板</h2>
</script>
<script>
var app = new Vue({
el : '#app',
data : {
message : 'hello world'
},
template:'#dd3'
})
</script>
</body>
6. Component组件
全局注册组件
局部注册组件局部注册组件和全局注册组件是向对应的,局部注册的组件只能在组件注册的作用域里进行使用,其他作用域使用无效。
<body>
<h1>component</h1>
<hr>
<div id="app">
<greentea></greentea>
<klaus></klaus>
</div>
<script src="../assets/js/vue.js"></script>
<script>
Vue.component('greentea',{
template : `<div style="color:red">我是全局的组件</div>`
})
var app = new Vue({
el : '#app',
components : {
"klaus" : {
template : `<div style="color:blue">我是局部的klaus组件</div>`
}
}
})
</script>
</body>
组件props属性设置
<body>
<h1>component</h1>
<hr>
<div id="app">
<klaus :here="country"></klaus>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : function(){
return {
country : "CHINA"
}
},
components : {
"klaus" : {
template : `<div style="color:blue">from {{ here }}</div>`,
props:['here']
}
}
})
</script>
</body>
父子组件关系
<body>
<h1>component3父子组件关系</h1>
<hr>
<div id="app">
<klaus></klaus>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var city = {
template : `<div style="color:green">天津</div>`
}
var klausComponent = {
template : `<div style="color:red">klaus is handsome <city></city></div>`,
components : {
"city" : city
}
}
var app = new Vue({
el : '#app',
// template : `<div>qweqweqwe<klaus></klaus></div>`,
components : {
"klaus" : klausComponent
}
})
</script>
</body>
Component标签
<component></component>标签是Vue框架自定义的标签,它的用途就是可以动态绑定我们的组件,根据数据的不同更换不同的组件。
<body>
<h1>component4标签</h1>
<hr>
<div id="app">
<component :is="who"></component>
<button @click="changeComponent">change</button>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var componentA = {
template : `<div style="color:red">i am componentA</div>`
}
var componentB = {
template : `<div style="color:green">i am componentB</div>`
}
var componentC = {
template : `<div style="color:blue">i am componentC</div>`
}
var app = new Vue({
el : '#app',
data : {
who : 'componentA'
},
components : {
"componentA" : componentA,
"componentB" : componentB,
"componentC" : componentC
},
methods : {
changeComponent : function(){
if(this.who === 'componentA'){
this.who = 'componentB'
}else if(this.who === 'componentB'){
this.who = 'componentC'
}else{
this.who = 'componentA'
}
}
}
})
</script>
</body>
选项
propsData Option 全局扩展的数据传递
propsData 不是和属性有关,他用在全局扩展时进行传递数据
<body>
<h1>propsData</h1>
<hr>
<header></header>
<script src="../assets/js/vue.js"></script>
<script>
var header_a = Vue.extend({
template : `<p>{{message}}----{{a}}</p>`,
data : function(){
return {
message : 'Hello,I am header'
}
},
props : ['a']
})
new header_a({propsData:{a:1}}).$mount('header');
</script>
</body>
computed Option 计算选项
computed 的作用主要是对原数据进行改造输出。改造输出:包括格式的编辑,大小写转换,顺序重排,添加符号等等
<body>
<h1>computed option</h1>
<hr>
<div id="app">
<p>{{newPrice}}</p>
<ul>
<li v-for="news in reverseNews">{{ news.title }}-----{{ news.date }}</li>
</ul>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var newsList = [
{title : 'first news',date : '2017/8/23'},
{title : 'second news',date : '2017/8/29'},
{title : 'third news',date : '2017/9/10'},
{title : 'fourth news',date : '2017/11/20'},
{title : 'fifth new',date : '2017/12/31'}
]
var app = new Vue({
el : '#app',
data : {
price : 99,
newsList : newsList
},
computed : {
newPrice : function(){
return this.price = '$'+this.price;
},
reverseNews : function(){
return this.newsList.reverse()
}
}
})
</script>
</body>
Methods Option
<body>
<h1>methods option</h1>
<hr>
<div id="app">
{{ num }}
<!-- 1. 方法传值 -->
<p><button @click="add(2,$event)">add</button></p>
<!-- 2. 使用event -->
<!-- 3. 组件调用原生的方法 -->
<p><btn @click.native="add(1,$event)"></btn></p>
</div>
<!-- 4. 在作用域外调用Vue构造器的方法 -->
<button onclick="app.add(5)">外部ADD</button>
<script src="../assets/js/vue.js"></script>
<script>
var btn = {
template : `<button>组件ADD</button>`
}
var app = new Vue({
el : '#app',
data : {
num : 0
},
components : {
"btn" : btn
},
methods : {
add : function(number,event){
this.num += number;
console.log(event);
}
}
})
</script>
</body>
Watch Option
数据变化的监控
<body>
<h1>watch option</h1>
<hr>
<div id="app">
<p>today : {{temperature}}</p>
<p>advice : {{advice}}</p>
<p>theNumber : {{theNumber}}</p>
<p>
<button @click="rise">rise</button>
<button @click="decline">decline</button>
</p>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : {
temperature : 18,
advice : 'jack',
theNumber : ''
},
methods : {
rise : function(){
this.temperature += 5;
},
decline : function(){
this.temperature -= 5;
}
},
watch : {
temperature : function(newVal,oldVal){
if(newVal >= 26){
this.advice = 't-shirt'
}else if(newVal < 26 && newVal > 0){
this.advice = 'jack'
}else{
this.advice = 'overcoat'
}
}
}
})
app.$watch('advice',function(newVal,oldVal){
if(app.advice === 't-shirt'){
app.theNumber = 1
}else if(app.advice === 'jack') {
app.theNumber = 2
}else{
app.theNumber = 3
}
})
</script>
</body>
Mixins 混入选项操作
混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。以组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。
<body>
<h1>helloworld</h1>
<hr>
<div id="app">
{{num}}
<p><button @click="add">add</button></p>
</div>
<script src="../assets/js/vue.js"></script>
<script>
// 混入先执行,原生后执行
var addConsole = {
updated : function(){
console.log('数据发生变化,现在:'+this.num );
}
}
//全局最先执行
Vue.mixin({
updated:function(){
console.log('我是全局的update')
}
})
var app = new Vue({
el : '#app',
data : {
num : 1
},
methods : {
add : function(){
this.num++
}
},
updated : function(){
console.log('我是原生的updated');
},
mixins : [addConsole]
})
</script>
</body>
Extends Option 扩展选项
这和 mixins 类似,区别在于,组件自身的选项会比要扩展的源组件具有更高的优先级.
<body>
<h1>helloworld</h1>
<hr>
<div id="app">
${num}
<p><button @click="add">add</button></p>
</div>
<script src="../assets/js/vue.js"></script>
<script>
var extendsObj = {
updated : function(){
console.log('我是扩展的updated');
},
methods : {
//方法名相同是不执行的,只执行原生的方法
add : function(){
console.log('我是被扩展出来的方法');
this.num++;
}
}
}
var app = new Vue({
el : '#app',
data : {
num : 1
},
methods : {
add : function(){
console.log('我是原生的方法');
this.num++
}
},
updated : function(){
console.log('我是原生的updated');
},
//只能有一个扩展,和混入写法不相同
extends : extendsObj,
//修改插值的符号
delimiters : ['${','}']
})
</script>
</body>
参考 : https://segmentfault.com/a/1190000010095089
实例和内置组件
实例属性
<body>
<h1>Early Examples Demo</h1>
<hr>
<div id="app">
{{message}}
</div>
<script type="text/javascript">
var app=new Vue({
el:'#app',
data:{
message:'hello Vue!'
},
//在Vue中使用jQuery
mounted:function(){
$('#app').html('我是jQuery!');
}
})
</script>
</body>
实例方法
<body>
<h1>example methods Demo2</h1>
<hr>
<div id="app">
</div>
<p><button onclick="destroy()">销毁</button></p>
<p><button onclick="reload()">刷新</button></p>
<script src="../assets/js/vue.js"></script>
<script>
var greentea = Vue.extend({
template : `<p>{{message}}</p>`,
data : function(){
return {
message : 'hello,i am greentea'
}
},
mounted : function(){
console.log('mounted被创建');
},
destroyed : function(){
console.log('destroy被销毁');
},
updated : function(){
console.log('update更新之后');
}
})
var vm = new greentea().$mount('#app');
function destroy(){
vm.$destroy();
}
function reload(){
vm.$forceUpdate('updated被更新');
}
</script>
</body>
实例事件
<body>
<h1>helloworld</h1>
<hr>
<div id="app">
{{num}}
<p><button @click="add">add</button></p>
</div>
<p><button onclick="reduce()">reduce</button></p>
<script src="../assets/js/vue.js"></script>
<script>
var app = new Vue({
el : '#app',
data : function(){
return {
num : 1
}
},
methods : {
add : function(){
this.num++;
}
}
});
app.$on('reduce',function(){
console.log('执行了reduce方法');
this.num--;
});
app.$once('reduceOnce',function(){
console.log('只执行一次的方法');
this.num--;
});
function reduce(){
app.$emit('reduce');
}
function reduceOnce(){
app.$emit('reduceOnce');
}
//关闭事件
function off(){
app.$off('reduce');
}
</script>
</body>
内置组件-slot讲解
<body>
<h1>helloworld</h1>
<hr>
<div id="app">
<greentea>
<span slot="blogUrl">{{jspangData.blogUrl}}</span>
<span slot="netName">{{jspangData.netName}}</span>
<span slot="skill">{{jspangData.skill}}</span>
</greentea>
</div>
<template id="tep">
<div>
<p>博客地址:<slot name="blogUrl"></slot></p>
<p>网名:<slot name="netName"></slot></p>
<p>技术类型:<slot name="skill"></slot></p>
</div>
</template>
<script src="../assets/js/vue.js"></script>
<script>
var greentea = {
template : '#tep'
}
var app = new Vue({
el : '#app',
data : function(){
greenteaData : {
username : 'wang',
age : 24
};
},
components : {
'greentea' : greentea
}
})
</script>
</body>