Vue笔记

1.起步

创建一个html,然后通过如下方式引入 Vue:

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

   <!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

1.1 HelloWorld

<div id="app">
	<p>{{ msg }}</p><!-- {{}}插值表达式-->
</div>
<script type="text/javascript">
	var vm = new Vue({
		el:'#app',
		data:{
			msg:'Hello Vue!'
		}
	})
</script>

以上就成功创建了第一个Vue应用!Vue将数据和DOM之间建立了关联,所有东西都是响应式的。打开控制台修改msg的值,你将看到上例相应地更新。

除了文本插值,我们还可以像这样来绑定元素特性:

<div id="app-2">
	<span v-bind:title="message">
		鼠标悬停几秒钟查看此处动态绑定的提示信息!
	</span>
</div>
<script type="text/javascript">
	var app2 = new Vue({
		el: '#app-2',
		data: {
			message: '页面加载于 ' + new Date().toLocaleString()
		}
	})
</script>

v-bind特性被称为指令。指令带有前缀 v-以表示它们是 Vue 提供的特殊特性。该指令的意思是:“将这个元素节点的 title 特性和 Vue 实例的 message属性保持一致”。

v-text与v-cloak:

<style>
    [v-cloak]{
        display: none;
    }
</style>
<div id="app">
    <p v-cloak>{{ msg }}</p>
</div>
var vm = new Vue({
    el:'#app',
    data:{
        msg:'Hello World'
    }
})

使用v-cloak时当网速较慢时不会将插值表达式{{ msg }}显示出来,只有当加载完毕时才会渲染到页面上,且使用v-cloak时可以在插值表达式两侧写其他内容并且会显示到页面上

<div id="app">
    <p v-cloak></p>
</div>

结果为:

左边-------- Hello World 右边+++++++++++

但是如果使用v-text则不需要写样式,直接绑定即可解决问题,但是标签中不能写任何内容,否则会被覆盖

<div id="app">
    <p v-text="msg"></p>
    <p v-text="msg">Hello World</p>
</div>

如上其中第一个p标签和第二个p标签显示的内容是一样的Hello World并不会被显示出来

v-text和插值表达式共同点是:

其内容都会被当做文本来解析,即使内容是html格式

如果想把内容当作html来解析则使用v-html,同样v-html标签体中的内容也不会显示

<div id="app">
	<div v-html="msg">哈哈哈哈哈哈</div>
</div>
var vm = new Vue({
        el:'#app',
        data:{
        msg:'<h1>这是一个大大的H1</h1>'
    }
})

1.2条件循环v-if与v-for

条件:
控制元素是否显示:

<div id="app-3">
	<p v-if="seen">现在你看到我了</p>
</div>

<script type="text/javascript">
	var app3 = new Vue({
		el: '#app-3',
		data: {
			seen: true
		}
	})
</script>

当seen为true时会将p标签显示出来,为false时之前显示的消息消失了。

v-show与v-if功能一样可以控制隐藏与显示,但是不同点是v-if每次都会重新删除或者创建元素,而v-show则不会每次都进行DOM的删除和创建操作只是添加了display:none样式

v-if有较高的切换性能消耗
v-show有较高的初始化渲染消耗
如果元素涉及到频繁的切换,最好不要使用v-if,如果元素可能永远也不会被显示出来被用户看到则推荐使用v-if

循环:
v-for 指令可以绑定数组的数据来渲染一个项目列表:

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
      <!-- 也可以获得序号-->
       <li v-for="(todo,i) in todos">
      	索引值:{{i}}--->元素:{{ todo.text }}
    </li>
  </ol>
</div>
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: '学习 JavaScript' },
      { text: '学习 Vue' },
      { text: '整个牛项目' }
    ]
  }
})

可以看到:

1. 学习 JavaScript
2. 学习 Vue
3. 整个牛项目

在控制台里,输入 app4.todos.push({ text: ‘新项目’ }),你会发现列表最后添加了一个新项目。

v-for遍历对象

<div id="app-4">
    <p v-for="(value,key) in user">
        {{key}}:{{value}}
    </p>
</div>
<script type="text/javascript">
    var app4 = new Vue({
        el: '#app-4',
        data: {
            user:{
                id:'1',
                name:'zhangsan',
                sex:'男',
                age:'18'
            }
        }
    })
</script>

运行结果:

id:1

name:zhangsan

sex:男

age:18

在遍历对象的键值对时除了 value ,key在第三个位置还有一个索引

v-for="(value,key,index) in user"

v-for迭代数字

<div id="app-4">
    <p v-for="count in 10">
        这是第 {{count}} 次循环
    </p>
</div>

count迭代从1开始

v-for中key的使用

使用key来强制数据关联

<div id="app-4">
    <label>id:<input type="text" v-model="id"/></label>
    <label>name:<input type="text"v-model="name"/></label>
    <button type="button" @click="add">添加</button>

    <!-- 注意:v-for循环的时候,key属性只能使用number获取string-->
    <!-- 注意:key在使用的时候,必须使用v-bind属性绑定的形式指定key的值 -->
    <p v-for="item in list" :key="item.id">
        <input type="checkbox"/>{{item.id}}-{{item.name}}
    </p>
</div>
		
<script type="text/javascript">
    var app4 = new Vue({
        el: '#app-4',
        data: {
            list:[
                {id:1, name:'赵高'},
                {id:2, name:'嬴政'},
                {id:3, name:'李斯'},
                {id:4, name:'荀子'}
            ]
        },
        methods:{

            add: function(){//添加方法
                this.list.push({id:this.id, name: this.name});
            }
        }
    })
</script>

1.3数据绑定v-bind

<div id="app-2">
    <span v-bind:title="message">
        鼠标悬停几秒钟查看此处动态绑定的提示信息!
    </span>
</div>
var app2 = new Vue({
	el: '#app-2',
    data: {
		message: '页面加载于 ' + new Date().toLocaleString()
	}
})

v-bind是vue中提供的用于绑定属性的指令,v-bind可以简写为:要绑定的属性,v-bind中还可以写合法js表达式如:

<div id="app-2">
    <span v-bind:title="message + 'hellod world'">
        鼠标悬停几秒钟查看此处动态绑定的提示信息!
    </span>
</div>

1.4事件绑定v-on

为了让用户和你的应用进行交互,我们可以用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法:

<div id="app">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">逆转消息</button>
</div>
var app5 = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})

注意reverseMessage方法中,我们不用直接操作DOM即可更新状态

除了v-on:click,v-on事件可以绑定:mouseenter 、mouseleave等事件

v-on事件缩写:@事件名

事件修饰符:

.stop阻止冒泡
.prevent阻止默认事件
.capture添加事件侦听器使用事件捕获模式
.self只当事件在该事件本身(比如不是子元素)触发时触发回调
.once事件只触发一次

1.5事件修饰符案例

<div id="app">
    <div class="innder" @click="divhandler">
        <button type="button" @click="btnhandler">戳他</button>
    </div>
</div>
var vm = new Vue({
    el:'#app',
    data:{

    },
    methods:{
        divhandler:function(){
            console.log('这是触发了inner div的点击事件')
    	 },
        btnhandler:function(){
            console.log('这是触发了 btn 按钮的点击事件')
        }
    }
})

运行结果:(冒泡机制限制性当前的事件再往外冒)

这是触发了 btn 按钮的点击事件
事件修饰符.html:29 这是触发了inner div的点击事件

如果想要阻止冒泡则在@click上加.stop:

<div id="app">
    <div class="innder" @click="divhandler">
        <button type="button" @click.stop="btnhandler">戳他</button>
    </div>
</div>

执行结果(阻止了事件向外冒泡):

这是触发了 btn 按钮的点击事件

阻止默认行为.prevent

<div id="app">
	<a href="www.baidu.com" @click="linkClick">点我到百度</a>
</div>

如上点击会跳转到百度,如果想阻止a标签的默认跳转事件则:

//创建vue实例得到ViewModel
var vm = new Vue({
	el:'#app',
	data:{

	},
	methods:{
		linkClick:function(){
			alert("弹出");
		}
	}
})

1.6简单案例:跑马灯效果

<div id="app">
	<input type="button" value="浪起来" @click="lang"/>
	<input type="button" value="低调"@click="stop"/>
		
	<h4>{{ message }}</h4>
</div>
	
<script type="text/javascript">
	var vm = new Vue({
		el:'#app',
		data:{
			message:'猥琐发育,别浪!',
			intervalId:null//在data上定义定时器id
		},
		methods:{
			lang: function() {
				//注意在vm实例中想要获取data上的数据,或者想要调用methods中的方法
				//必须要使用this来进行访问
				var that = this;//解决内部访问问题
				
				//在开启之前先将之前开启的定时器关闭,避免重复开启
				clearInterval(this.intervalId)
				that.intervalId = setInterval(function(){
					//截取第一个字符串
					var start = that.message.substring(0,1);
					//截取剩下的字符串
					var end = that.message.substring(1);
					//拼接剩下的字符串
					that.message = end + start;
				},400)
				//vue会监听自己身上data中所有数据的改变,只要数据发生变化,就会自动更新DOM
			},
			stop:function() {
				clearInterval(this.intervalId)
			}
		}
	})
	/*
		分析:
		1.给【浪起来按钮】绑定一个点击事件:v-on
		2.在按钮的事件处理函数中,写相关的业务逻辑代码:拿到message字符,然后
		调用字符串的substring来进行字符串截取操作,把第一个字符截取出来,放到最后
		一个位置即可
		3.为了实现点击一下按钮自动截取的功能需要2步骤中的代码,放到一个定时器中
	*/
		
</script>

1.7v-model指令

v-bind只能实现数据的单项绑定,从M自动绑定到V,无法实现数据的双向绑定

v-model它能轻松实现表单输入和应用状态之间的双向绑定。

<div id="app-6">
  <p>{{ message }}</p>
  <input v-model="message">
</div>
var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'
  }
})

注意v-model只能运用在表单元素中

input(radio,text,address,email…)

select

checkbox

textarea

1.8v-model简易计算器

<div id="app">
    <input type="text" v-model="n1" />

    <select v-model="opration">
        <option value ="+">+</option>
        <option value ="-">-</option>
        <option value ="*">*</option>
        <option value ="/">/</option>
    </select>

    <input type="text" v-model="n2" />

    <input type="button" value="=" @click="sulotion"/>

    <input type="text" v-model="result" />
</div>
<script type="text/javascript">
    var vm = new Vue({
        el:'#app',
        data:{
            n1:0,
            n2:0,
            result:0,
            opration:'+'
        },
        methods:{
            sulotion:function(){//计算器计算方法
                //逻辑
               sulotion:function(){//计算器计算方法
					var codeStr = 'parseInt(this.n1)'+ this.opration +'parseInt(this.n2)'
					this.result = eval(codeStr);
				}
            }
        }
    })
</script>

1.9在vue中使用样式

1.数组方式:class="['thin','red','i']"

<style type="text/css">
    .red{
        color: red;
    }
    .thin{
        font-weight: 200;
    }
    .i{
        font-style: italic;
    }
    .active{
        letter-spacing: 0.5em;
    }
</style>

<div id="app">
	<h1 :class="['thin','red','i']">这是一个h1,测试vue中使用样式</h1>
</div>
<script type="text/javascript">
	var vm = new Vue({
		el:'#app',
		data:{

		},
		method:{

		}
	})
</script>

2.在数组中使用三元表达式::class="['thin','red',flag?'active':'']"

<div id="app">
	<h1 :class="['thin','red',flag?'active':'']">这是一个h1,测试vue中使用样式</h1>
</div>

其中flag是data中定义的变量

3.在数组中使用对象代替三元表达式提高可读性{'active':flag}

<h1 :class="['thin','red',{'active':flag}]">这是一个h1,测试vue中使用样式</h1>

4.直接使用对象:

:class="{'thin':true,'red':true,'active':true}"

<h1 :class="{'thin':true,'red':true,'active':true}">这是一个h1,测试vue中使用样式</h1>

5.间接绑定:

<div id="app">
	<h1 :class="classObj">这是一个h1,测试vue中使用样式</h1></div>
</div>
var vm = new Vue({
    el:'#app',
    data:{
        classObj:{'thin':true,'red':true,'active':true}
    }
})

6.使用style

也可以间接绑定

<div id="app">
	<h1 :style="{color:'red', font-weight:'200' }">这是一个h1,测试vue中使用样式</h1></div>
</div>

3.v-on按键修饰符

3.1作用说明

文档地址:https://cn.vuejs.org/v2/guide/events.html

在监听键盘事件时,我们经常需要监听常见的键值,vue允许v-on在监听键盘事件时添加按键修饰符:
- enter
- table
- delete (捕获‘删除’和‘退格’键)
- esc
- space
- up
- down
- left
- right
1.0.8+支持单字母按键别名

3.2案例

#app{
    width: 600px;
    margin: 0 auto;
}
table {
    width:100%;
    border-collapse: collapse;
    color: black;
    margin-top: 15px;
}

th {
    color: white;
    background-color: dodgerblue;
}

table,
tr,
td,
th {
    text-align: center;
    border: 1px solid #FF0000;
}
<div id="app">
    <label>id:<input type="text" v-model="id" /></label>
    <!-- #### 重点看这里:-->
    <!-- 注册keydown事件,不加修饰符时只要按键改变就会触发,所以要加按键修饰符 -->
    <label>姓名:<input type="text" v-model="name" @keydown.enter="add"/></label>
    <button type="button" @click="add">添加</button>

    <table>
        <thead>
            <tr>
                <th>选择</th>
                <th>ID</th>
                <th>姓名</th>
                <th>操作</th>
            </tr>
        </thead>
        <tr v-show="list.length ==0">
            <td colspan="4">当前列表没有任何数据</td>
        </tr>
        <tr v-for="user in list" :key="user.id">
            <td><input type="checkbox" /></td>
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
            <td><a href="#" @click="deleteEle">删除</a></td>
        </tr>
    </table>
</div>
var app4 = new Vue({
    el: '#app-4',
    data: {
        list: [
        		{
            		id: 1,
            		name: '赵高'
        		},
              	{
                   id: 2,
                   name: '嬴政'
              	},
              	{
                   id: 3,
                   name: '李斯'
              	},
              	{
                   id: 4,
                   name: '荀子'
              	}
              ],
        id: 0,
        name: null
    },
    methods: {
        add: function() { //添加方法
            this.list.push({
                id: this.id,
                name: this.name
            });
        },
        deleteEle: function(id) {
            var index = this.list.findIndex(function(item) {
                //根据item中的id属性来判断这个item是否是上面id中
                //对应的数据,如果是返回一个true ,否返回false,继续下面的一条数据的遍历,以此类推
                return item.id == id; //如果返回true,那么findIndex方法会将这个item对应的id返回到外面接受
            });
            //删除
            this.list.splice(index, 1);
        }
    }
})

3.3 可以自定义按键别名

Vue.config.keyCodes.f2 = 113;//f2自定义按键名称,113对应的键盘码
console.log(Vue.config.keyCodes)

3.4 自定义指令

在vue2.0中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通DOM元素进行底层操作,这时候就会用到自定义指令。

自定义指令最重要的两个部分就是钩子函数和钩子函数对应的参数。

3.4.1 钩子函数

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

bind只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置。

inserted被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。

update所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

componentUpdated指令所在组件的 VNode 及其子 VNode 全部更新后调用。

unbind只调用一次,指令与元素解绑时调用。

3.4.2钩子函数参数

指令钩子函数会被传入以下参数:

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 }
vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

3.4.3 自定义全局属性指令用法

//vue1.0中提供了一个Vue.directive(自定义指令名称,回调函数)来供程序员自定义指令
//注意:在定义指令时不需要加v-前缀但是使用时必须加v-前缀
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
    // 当被绑定的元素插入到 DOM 中时……
    inserted: function(el) {
        // 聚焦元素
        el.focus()
    }
})

//定义一个v-color指令
Vue.directive('color', {
    // 当被绑定的元素被绑定时
    bind: function(el,binding) {
        el.style.color = binding.value;
    }
})

使用自定义指令

<input type="text" v-focus v-color="customColor" placeholder="请输入筛选条件" v-model="searchtext" />

3.4.4 自定义私有指令

var app4 = new Vue({
    el: '#app-4',
    data: {},
	directives: {
        focus: {
            // 指令的定义
            inserted: function(el) {
                el.focus()
         }
     }
}

使用自定义元素

<input type="text" v-focus placeholder="请输入筛选条件" v-model="searchtext" />

3.4.5 函数简写

在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写:

Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})

3.4.6 对象字面量

如果指令需要多个值,可以传入一个 JavaScript 对象字面量。记住,指令函数能够接受所有合法的 JavaScript 表达式。

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Vue.directive('demo', function (el, binding) {
  console.log(binding.value.color) // => "white"
  console.log(binding.value.text)  // => "hello!"
})

4.vue生命周期

所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos())。这是因为箭头函数绑定了父上下文,因此 this 与你期待的 Vue 实例不同,this.fetchTodos 的行为未定义。

4.1生命周期图示

在这里插入图片描述

4.2生命周期方法

beforeCreate
类型:Function

详细:

在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

created
类型:Function

详细:

在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

beforeMount
类型:Function

详细:

在挂载开始之前被调用:相关的 render 函数首次被调用。

该钩子在服务器端渲染期间不被调用。

mounted
类型:Function

详细:

el 被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时vm.$el也在文档内。

注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick替换掉 mounted

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

该钩子在服务器端渲染期间不被调用。
beforeUpdate
类型:Function

详细:

数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。

updated
类型:Function

详细:

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。

注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated:

updated: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been re-rendered
  })
}

beforeDestroy
类型:Function

详细:

实例销毁之前调用。在这一步,实例仍然完全可用。

该钩子在服务器端渲染期间不被调用。

destroyed
类型:Function

详细:

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

该钩子在服务器端渲染期间不被调用。

5.进入/离开 & 列表过渡

5.1 概述

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
包括以下工具:

在 CSS 过渡和动画中自动应用 class
可以配合使用第三方 CSS 动画库,如 Animate.css
在过渡钩子函数中使用 JavaScript 直接操作 DOM
可以配合使用第三方 JavaScript 动画库,如 Velocity.js

5.2 transition过渡

Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡

  • 条件渲染 (使用 v-if)
  • 条件展示 (使用 v-show)
  • 动态组件
  • 组件根节点
.fade-enter-active,
.fade-leave-active {
    transition: opacity .5s;
}

.fade-enter,
.fade-leave-to
/* .fade-leave-active below version 2.1.8 */
{
    opacity: 0;
}
<div id="demo">
    <button v-on:click="show = !show">
        Toggle
    </button>
    <transition name="fade">
        <p v-if="show">hello</p>
    </transition>
</div>
new Vue({
    el: '#demo',
    data: {
        show: true
    }
})

当插入或删除包含在transition 组件中的元素时,Vue 将会做以下处理:

  1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
  2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
  3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的nextTick 概念不同)

过渡的类名

对需要进行动画控制的元素使用transition标签包裹有一个name属性值自定义如name=“fade”,但是使用css控制时的前缀必须与name值一致如fade-enter 。

在进入/离开的过渡中,会有 6 个 class 切换,以下v表示name值。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

在这里插入图片描述
对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。如果你使用了 <transition name="my-transition">,那么 v-enter 会替换为my-transition-enter

v-enter-activev-leave-active 可以控制进入/离开过渡的不同的缓和曲线。

5.3 利用钩子函数进行一半动画的控制

.show{
    transition: all 0.4s ease;
}
<div id="app">
    <button type="button" @click="show = !show">隐藏/显示</button>

    <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
        <p v-if="show" class="show">Hello Animate css</p>
    </transition>
</div>
new Vue({
    el:'#app',
    data:{
        show:true
    },
    methods:{
        //这里主要通过js定义当前实现动画的初始位置,el表示当前操作的元素
        beforeEnter:function(el){
            el.style.transform = "translate(100px,0)";
        },
        //通过js定义动画的结束位置
        enter:function(el,done){
            //设置刷新状态
            el.offsetWidth;
			
            //设置动画的结束位置
            el.style.transform = "translate(0px,0)";

            //手动调用done,保证动画即时结束
            done();
        },
        //动画的状态复原设置
        afterEnter:function(el){
            this.show = !this.show;
        }
    }
})

6.组件注册

组件名

在注册一个组件的时候,我们始终需要给它一个名字。比如在全局注册的时候我们已经看到了:

Vue.component('my-component-name', { })

该组件名就是Vue.component 的第一个参数

你给予组件的名字可能依赖于你打算拿它来做什么。当直接在 DOM 中使用一个组件 (而不是在字符串模板或单文件组件) 的时候,我们强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)。这会帮助你避免和当前以及未来的 HTML 元素相冲突

组件名大小写

定义组件名的方式有两种:

使用 kebab-case

Vue.component('my-component-name', {  })

当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>

使用 PascalCase

Vue.component('MyComponentName', {  })

当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name><MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

6.1注册全局组件

到目前为止,我们只用过 Vue.component 来创建组件:

Vue.component('my-component-name', { })

这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。比如:

Vue.component('component-a', {  })
Vue.component('component-b', {  })
Vue.component('component-c', {  })

new Vue({ el: '#app' })

使用组件

<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。

6.2定义组件的三种方式

第一种方式

//方法1:定义组件
var login = Vue.extend({
    template:'<h1>登陆页面</h1>'
})
//注册组件
Vue.component('login',login);
<div id="app">
	<login></login>
</div>

第二种方式

//方法2:定义一个全局组件
Vue.component('register',{
    template:'<h1>注册页面</h1>'
})
<div id="app">
    <register></register>
</div>

第三种方式

//方法3:定义一个账号组件,建议使用方法三
Vue.component('account',{
    template:'#account',
    data:function(){
        //与vue对象不同的是组件中的data是一个function,
        //所以要这么写
        return {
            message:'账户组件'
        }
    },
    methods:{
        login:function(){
            alert("Hello VueJs")
        }
    }
})

模板的事件写在对应的模板中

全局组件引用了一个在html中定义的组件模板account

<!--组件模板的定义 template和script定义都可以但是建议使用template-->
<template id="account">
    <div>
        {{message}}
        <a href="#" @click.prevent="login">登陆</a> |
        <a href="#">注册</a>
    </div>
</template>

也可以使用script定义但是建议使用template标签

 <script type="x-template" id="account">
     <div>
    	<a href="#">登陆</a> |
		<a href="#">注册</a>
	</div>
</script>

值得注意的是,所有子元素必须使用一个共同的根标签包围,如div

6.3局部注册

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

然后在 components 选项中定义你想要使用的组件:

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

或者是在组件中定义子组件

//定义一个账号组件
Vue.component('account',{
    template:'<div><h1>账号组件</h1><login></login></div>',
    //在账号组件中定义一个登陆子组件
    components:{
        'login':{
            template:'<h2>登陆子组件</h2>'
        }
    }
})

对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。

6.4组件的动态切换

首先注册两个组件,login和regist

Vue.component('login',{
    template:'<h1>登陆页面</h1>'
})
Vue.component('regist',{
    template:'<h1>注册页面</h1>'
})
<div id="app">
    <a href="#" @click.prevent="cname = 'login'">登陆</a> |
    <a href="#" @click.prevent="cname = 'regist'">注册</a>
    <!-- 利用component标签中的:is参数来进行组件的切换 -->
    <component :is="cname"></component>
</div>

组件的切换使用component标签的is属性

new Vue({
    el:'#app',
    data:{
        cname:'login'
    }
})

只要控制is的值即可控制组件的显示,如上通过点击事件改变cname的值来切换组件

7.vue-router路由

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为

7.1路由写法和传参

引入vuejs和vue-router

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
//准备组件
var Ap = Vue.extend({});

var login = Vue.extend({
    template:'<div><h1>登陆</h1></div>'
})

var regist = Vue.extend({
    template:'<div><h1>注册{{name}}</h1></div>',
    data:function(){
        return {
            name:''
        }
    },
    created:function() {//在页面渲染是将参数赋值给name
        this.name = this.$route.params.name
    }
})

//实例化路由规则对象
var router = new VueRouter({
    routes:[
        {path:'/',redirect:'/login'},//如果是/则自动重定向到login
        {path:'/login',component:login},
        {path:'/regist/:name',component:regist}//获取参数
    ]
});

//开启路由对象
new Vue({
    el:'#app',
    router:router//开启路由对象
})
<div id="app">
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/login">登陆</router-link>
    
    <!--通过router-link指定参数 -->
    <router-link to="/regist/zhangsan">注册</router-link>

    <!-- 路由出口 -->
 	<!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
</div>

7.2嵌套路由

//准备组件
//准备组件
var App = Vue.extend({});

var account = Vue.extend({
    template:'<div><h1>账号组件</h1></div>'
})

var login = Vue.extend({
    template:'<div><h1>登陆</h1></div>'
})

var regist = Vue.extend({
    template:'<div><h1>注册</h1></div>'
})

//实例化路由规则对象
var router = new VueRouter({
    routes:[
        {
            path:'/account',
            component:account,
            children:[
                {
                    path:'login',
                    component:login
                },
                {
                    path:'regist',
                    component:regist
                }
            ]
        }
    ]
});

//开启路由对象
new Vue({
    el:'#app',
    router:router//开启路由对象
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值