一年前我跟你一样,对于vue是一点不知,但是经过一年的成长,现在我来谈谈对于vue的看法,让大家更多的了解使用vue框架。既然我们要学习vue,那什么是vue?首先vue 是一个构建用户界面的渐进式的框架,它是目前最火的一个框架,采用自底向上增量开发的设计,它的核心只关注视图层、容易学,低耦合,可重复使用一些视图逻辑,独立开发。
我们知道vue 是一个构建用户界面的渐进式的框架,基于mvvm模式开发,那我们必须知道库和框架的区别:
1.库(插件) - 提供某一个小功能,对项目的入侵性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求;例如vue.js,jquery.js…等,其实我们之前使用的引入js文件,就是使用的其中的库。
2.框架 - 框架是以整套完整的解决方案,对项目侵入性很大,项目如果需要更换框架,就需要重新构架整个项目,换句话说就要从头到脚彻底换新。
首先我们需要先了解vue的特点,它只关注视图层,容易学,而且轻量,灵活,适用于移动端项目,是渐进式框架等。
其次它的核心包括:1.响应式的数据变化,视图可以改变数据,数据也可以改变视图;2.通过Object.defineProperty()方法来实现响应式数据变化(此时不理解这个方法不要紧,后面解释数据双向绑定时候会详情解释这个方法);3.设计思想是MVVM;4.组件化系统,组件可维护,可复用。
MVVM是Model-View-ViewModel的缩写,Model层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View代表的是ui组件,它负责将数据模型转换成ui展现出来;ViewModel它是一个调度者,分割了M与V,每当V层想要获取保存数据都要由VM做中间处理。
在MVVM架构下,View与Model之间没有直接关系,而是通过VM进行交互,是VM提供了数据双向绑定,所以V层的数据变化会同步到M层中,而M层的数据变化也会立即反应到V层上。
MVVM和MVC区别不大,都是一种设计思想,前端操作的主要是MVC中的V层部分,然后将V层划分成了MVVM思想,而MVVM是由MVC中C层演变成VM层,最终MVVM模型解决了MVC中大量操作Dom的操作,提高了渲染性能,加载速度变快,用户体验好。vue是数据驱动,通过数据来显示视图层,而不是对于dom节点的操作。
1,直接使用cdn提供的免费连接
https://cdn.jsdelivr.net/npm/vue/dist/vue.js
https://cdn.jsdelivr.net/npm/[email protected]
2,使用npm安装:npm install vue
前提是先创建package.json安装依赖的清单列表:npm init
3,vue-cli脚手架直接生成vue项目
注:在此篇文章中教大家如何从上手到熟练的过程,先直接使用vue.js库,可以使用cdn免费的链接,也可以使用npm安装下载vue(在cmd命令中输入npm init生成一个package.json,然后输入npm install vue,会生成一个node_modules文件在里面vue文件下的dist文件中找到vue.js然后引入到你的html文本中就可以了)
1.先控制一个根元素取id名为app(这个名字是你随便取的,但是你取的名字下面需要挂载),以后所写的内容均需要在这个元素中进行;2.new Vue()如下步骤所示:
<body>
<div id="app">
<!-- 此处显示data中的msg数据,下面两个大括号表示插值表达式-->
{
{
msg }}
</div>
<script src="./js/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
//创建vue实例
el: '#app', //绑定元素
data: {
//此处的数据存放方式是对象
msg: 'hello world'
},
Object.freeze(msg)//当使用这个方法之后,会阻止修改data中msg数据
//注意区分:后面会进行组件开发,组件中的data必须是函数,因为
//函数有自己的作用域,每个data都是独立,可以各种操作不受影响
//而如果都用对象形式,则操作多个实例都会引用同一个对象,同一个堆内存
// data(){注意此处与上面的data相对比,此处是函数
// return{
// msg:'hello world'
// }
// }
})
vm.msg = '你好' //修改实例中的数据
</script>
</body>
<style>
[v-cloak]{
display: none;//使用插值表达式可以设置css样式解决刷新闪烁的问题
}
</style>
2.v-text与v-html 。v-text相当于原生javascript中的innerText,只识别文本不识别标签;v-html相当于原生javascript中的innerHTML,可以识别标签
<body>
<div id="app" v-cloak>
<p v-text="msg"></p>
<p v-html="msg"></p>
</div>
<script src="./js/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
//创建vue实例
el: '#app', //绑定元素
data(){
//存放数据
return{
msg:'hello world
'
}
}
})
</script>
</body>
如下图所示
3.v-bind,属性绑定,可以简写成:(冒号),只能实现单向数据的绑定
①.绑定属性方法
<body>
<div id="app" v-cloak>
<input type="button" :value="msg" />//绑定属性,用data中的数据
</div>
<script src="./js/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
//创建vue实例
el: '#app', //绑定元素
data(){
//存放数据
return{
msg:'修改'
}
}
})
</script>
</body>
<style>
.w{
background-color: #7FFFD4;
}
.e{
color: chocolate;
}
.r{
font-size: 20px;
}
</style>
</head>
<body>
<div id="box">
<!-- 数组中传入三元运算符 -->
<!-- <h1 :class="['w','e',flg ? 'r' : '']">我是一个h1</h1> -->
<!-- 数组中传入对象 -->
<!-- <h1 :class="['w','e',{r:flg}]">我是一个h1</h1> -->
<!-- 直接传入一个对象 -->
<!-- <h1 :class="{w:true,e:true,r:true}">我是一个h1</h1> -->
<!-- 在数据中引入样式 -->
<h1 :class="as">我是一个h1</h1>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#box',
data:{
flg:false,
as:{
w:true,e:true,r:false}
}
})
</script>
</body>
使用内联样式:
<h1 :style="{color:'red','font-size':'40px'}">这是一个h1</h1>
4.v-on,绑定事件,可以简写成@
①使用方法
<body>
<div id="app" v-cloak>
<!-- 绑定属性和事件 -->
<input type="button" :value="msg" @click="handlerClick"/>
</div>
<script src="./js/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
//创建vue实例
el: '#app', //绑定元素
data(){
//存放数据
return{
msg:'点击'
}
},
methods:{
//定义的逻辑事件放在methods中定义声明
handlerClick(){
alert('hello world')
}
}
})
</script>
</body>
.stop 阻止冒泡
.prevent 阻止默认事件
.once 事件值触发一次
.capture 添加时间侦听器时使用事件捕获模式
.self 清除捕获冒泡机制,值实行单一效果,点击谁实行谁的效果
.passive 滚动事件的默认行为(不能与prevent一起连用,连用失效)
使用方式:如点击此时点击不会跳转
注:事件修饰符有链接式写法,但是链接之后,前面的修饰符对后面的就不起作用了
③按键修饰符
我们知道很多网页比如你按enter键就会进入的效果,这就是使用了按键修饰符,按键修饰符有:.enter .tab .delete .esc .space .up .down .left .right等等,使用方法:@keyup.enter=“执行的函数方法”,也可以使用按键码执行相应的操作,即@key.13 = "执行的函数方法"若想获取按键码可以使用vue提供的一个方法,vue.config.keyCode.enter = 13;
5.v-for与key属性,列表循环与数据渲染,可以循环数组、对象、以及数字
<body>
<div id="box" v-cloak>
<!--v-for循环语法 ,key值确定唯一性,以免操作相同元素引起失误,故循环时候都加上key值,确定唯一性 -->
<p v-for="(item,key) in user" :key='item.id'> {
{
item.name}}-----{
{
item.gender}} </p>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#box',
data() {
return {
user: [{
id: 1,
name: 'tom',
gender: '男'
},
{
id: 2,
name: 'tony',
gender: '女'
},
{
id: 3,
name: 'toke',
gender: '男'
},
{
id: 4,
name: 'toome',
gender: '女'
}
]
}
}
})
</script>
</body>
如下图所示结果:
6.v-model,vue中唯一一个实现数据双向绑定的指令(除自定义指令外),它只能应用于表单控件中(input,textare,select),下面列举介绍几种数据双向绑定的效果以及v-model的原理
①.v-model的用法
<body>
<div id="box">
<h4>{
{
msg}}</h4>
<!-- 当改变input里面的数据内容,暂时h4里面的内容也会发生改变,这就是数据双向绑定 -->
<input type="text" v-model="msg" style="width: 100%;"/>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#box',
data:{
msg:'大家都是好同志,爱敲代码的好同志'
}
})
</script>
</body>
如下图所示:当你修改里面的内容立马与页面中h4标题一致
②.使用绑定属性与绑定方法共同来实现数据双向传递(oninput方法)
<body>
<div id="box">
<h4>{
{
msg}}</h4>
<!-- 当改变input里面的数据内容,暂时h4里面的内容也会发生改变,这就是数据双向绑定 -->
<input type="text" :value="msg" @input='changeHandler' style="width: 300px;"/>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#box',
data:{
msg:'大家都是好同志,爱敲代码的好同志'
},
methods:{
changeHandler(e){
//定义的点击事件
this.msg = e.target.value
}
}
})
</script>
</body>
③.v-model实行数据双向绑定的原理(刚学习vue的同学看不懂没关系,可以先行跳过)
/*
观察对象,属性一旦变化了,就调用render方法 ,如何知道属性变化了呢?
有观察者来观察这个对象,
整个监听的流程:把所有的数据都劫持到,改成getter和setter的形式
*/
//属性一旦变化了,就调用render方法:重新渲染页面
function rander(d) {
console.log('数据变化了,我要更新了', d);
}
//观察者,把data的属性都加上getter和setter的形式
function observer(data) {
if (typeof data === "object") {
for (key in data) {
defineResponse(data, key, data[key]);
}
}
}
function defineResponse(data, key, value) {
//{x:1,y:2}
observer(value)
//使用Object.defineProperty()来劫持各个属性的setter与getter,在数据变动时,触发相应的监听回调
Object.defineProperty(data, key, {
get() {
//console.log('get', value);
return value
},
set(newval) {
value = newval;
observer(newval);
console.log('set', newval);
rander(newval)
}
})
}
let data = {
n: 100,
h: {
x: 1, y: 2 }
}
observer(data);
// data.n = 200;
// console.log(data.n);
// data.h.x = 3;
// console.log(data.h);
data.h = {
x: 900 }
data.h.x = 1000;
console.log(data.h);
7.v-if与v-show两种都是显示与隐藏的效果,v-if每次显示与隐藏都有新元素的创建与销毁过程伴随,而v-show,只是css样式display的显示与隐藏,占据内存空间。
其中指令系统还包括v-else,v-else-if,一般v-if与v-else连用时,当不显示v-if时就显示v-else的内容;v-else-if是v-if与v-else的结合。
学习完上面的指令系统,接下来会有几个小的练习,希望可以帮助你更好掌握vue的指令。
1.跑马灯练习
要求:两个控制按钮,一个取名为‘跑起来’,另一个取名为‘停止’,分别控制页面的数据变化,数据为‘猥琐发育!别浪~~!’,前面的字符串自动拼接在后面。
<body>
<div id="box">
<input type="button" value="跑起来" @click="show"/>
<input type="button" value="停止" @click="pause"/>
<h4 v-cloak>{
{
msg}}</h4>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
//控制的元素
el:'#box',
//数据
data:{
msg:'别浪~~!猥琐发育!',
timer:null,
},
//方法
methods:{
show(){
//开始方法
// var _this = this; 如果使用箭头函数,可以不加这一步
if(this.timer){
return;
}else{
this.timer = setInterval(()=>{
var start = this.msg.substring(0,1);
var end = this.msg.substring(1);
this.msg = end + start;
},400)
}
},
pause(){
//暂停方法
clearInterval(this.timer);
this.timer = null;
}
}
})
</script>
</body>
<body>
<div id="app">
<div class="songList">
<div @click="handlerSong(index)" v-for="(item,index) in musicListData" :key='item.id' :class="{active:index==currentIndex}">//此处:class是绑定类名,active是一个类名
<h3>歌名:{
{
item.name }}</h3>
<h4>歌手:{
{
item.autor }}</h4>
</div>
</div>
<audio :src="musicListData[currentIndex].srcSong" controls="controls" autoplay="autoplay" @ended="handlerNext"></audio>
</div>
<script src="./js/vue.js"></script>
<script>
var musicData = [{
id: 1,
name: "少林英雄",
autor: "华语群星",
srcSong: "./static/华语群星 - 少林英雄.mp3"
},
{
id: 2,
name: "梧桐树",
autor: "连子",
srcSong: "./static/连子 - 梧桐树.mp3"
},
{
id: 3,
name: "扶桑树",
autor: "孟萌、刘泓君",
srcSong: "./static/孟萌、刘泓君 - 扶桑树.mp3"
},
{
id: 4,
name: "伪装",
autor: "王炜一",
srcSong: "./static/王炜一 - 伪装.mp3"
}
]
new Vue({
el: '#app',
data() {
return {
musicListData: [],//歌曲数存放
currentIndex: 0//默认显示播放曲目的下表索引
}
},
methods: {
handlerSong(index) {
//点击切换歌曲
this.currentIndex = index;
},
handlerNext() {
//当播放完此歌曲后播放下一首
this.currentIndex++;
if (this.currentIndex === 4) {
this.currentIndex === 0;
}
}
},
created() {
//这是晟敏周期里面的一个钩子函数,在此处先用,后面会详情解释
this.musicListData = musicData;
}
})
</script>
</body>
1.全局过滤器,在创建vue实例之前定义全局过滤器
语法:vue.filter(‘过滤器的名称’,function(msg,ele){//第一个参数固定代表管道符前面的数据,第二个参数代表需要执行的语句
//这里显示需要执行的ele数据的代码
})
使用:{ { msg | 过滤器的名称 }}
<body>
<div id="box">
<p>{
{
msg|fil(ele)}}</p>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
Vue.filter('fil', function(msg,ele) {
return msg.replace(/单纯/g, ele);
})
var vm = new Vue({
el: '#box',
data: {
msg: '我是一个单纯的孩子,以前很单纯,以后也很单纯',
ele:'爱笑'
}
})
</script>
</body>
如下图所示
过滤器可以多次被调用,即{ { msg | 过滤器1 | 过滤器2 }},所谓的全局过滤器,就是所有的vm实例都可以共享。
2.私有过滤器(局部过滤器),只能在控制的el节点里面使用,用法与全局过滤器一样,只是语法抒写会使用在局部,如下代码所示
<body>
<div id="box">
<p v-for="item in list" key='item.name'>{
{
item.name | fil}}---{
{
item.prince | fil1(2)}}</p>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#box',
data: {
list: [{
name: 'js入门1',
prince: 451
},
{
name: 'js入门2',
prince: 452
},
{
name: 'js入门3',
prince: 453
},
{
name: 'js入门4',
prince: 454
}
]
},
filters: {
//过滤器集合
fil(name) {
//过滤器1
return name.slice(0, 1).toUpperCase() + name.slice(1);
},
fil1(prince,pes){
//过滤器2
return prince.toFixed(pes);//保存小数后几位
}
}
})
</script>
</body>
如下图所示
注:过滤器调用时,如果私有过滤器与全局过滤器名字一致时,则会先找私有过滤器,然后在找全局过滤器。
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。
1.全局指令
当页面加载时,该元素将获得焦点,
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// el聚焦元素,指令放在哪个元素上面,el就指哪个元素
//表示行为js操作放在此处,被绑定元素插入到父节点时调用
el.focus()
},
bind:function(el){
//表示样式相关操作一般放在bind中,指令第一次绑定到元素时调用
el.style.color = 'red';
},
//一般只用前面两种方法,后面两种用的很少很少
updated:function(el){
//当vNode更新时候调用(可能会调用多次)
},
unbind:function(el){
//只调用一次,指令与元素解绑时候调用
}
})
2.局部指令(私有指令):与自定义过滤器一样,需要写在控制元素节点el当中
directives: {
focus: {
// 指令的定义,这里面的属性方法与全局的一样,都含有inserted,bind等
inserted: function (el) {
el.focus()
}
}
}
3.指令钩子函数中的参数
inserted,bind,update,unbind这些是指令的钩子函数,
他们的参数含有:(el、binding、vnode 和 oldVnode)。
①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 来进行。
动态绑定指令参数:
Vue.directive('fontWeight',{
bind:function(el,binding){
el.style.fontWeight = binding.value;
},
})//使用:v-fontWeight = '600';这样就显示加粗的效果
1.watch,它是一个侦听器,可以侦听数据的变化,使用语法如下代码所示
<body>
<div id="app">
<input type="text" v-model="first"/>
<input type="text" v-model="last"/>
<input type="text" v-model="fulls"/>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
first:'',
last:'',
fulls:''
},
watch:{
//侦听器
first(newval,oldval){
//这里的fist与数据中的名字保
//持一致,只要first发生变化,就会知道他的变化
//里面包含两个参数newval代表数据变化之后值,
//oldval代表数据原来的值
this.fulls = newval + this.last;
},
last(newval){
this.fulls = this.first + newval;
}
}
})
</script>
</body>
如果监听的数据形式是一个对象,则需要进行深度监听,代码如下
watch:{
obj:{
handler(newval,oldval){
console.log(obj.a)
},
immediate:true,//刷新加载
deep:true//是否可以深度监听
}
}
obj:{
a:‘’,
b:‘’
}
如下图所示
注:watch只能单向监听,如上所示,只能改变前面的值影响后面值的变化,不能改变后面的值影响前面,为了解决这一双向监听的功能,故出现了计算属性的方法
2.computed,computed定义了一些属性,叫做计算属性,计算属性本质是一个方法,但我们使用时是直接当做属性来使用,并不是方法,在引用时不能加();特别注意,在computed中的属性名不能与data中的名字重复,且声明computed中的属性之后,应该消除data中的一些名称仙童的属性,任何data中数据发生变化,整个computed中属性中的函数方法就会重新计算,计算结果会被缓存起来,方便下次重新使用。
如下代码所示:
<body>
<div id="app">
<input type="text" v-model="first"/>
<input type="text" v-model="last"/>
<input type="text" v-model="fulls"/>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
first:'',
last:''
},
computed:{
// fulls(){//单向绑定
// return this.first + this.last;
// }
fulls:{
//双向绑定
get(){
return this.first + ' ' + this.last;
},
set(value){
value = value.split(' ');
this.first = value[0];
this.last = value[1];
}
}
}
})
</script>
</body>
如下图所示:改变前后数据都会发生变化
3.watch、computed、methods三者的区别
computed是计算属性,有getter与setter属性,会根据属性进行缓存,getter返回属性值,setter接受属性值,属于同步操作。
watch是监听,里面属性函数方法中含有两个参数,分别代表新旧值的数据,当数据发生变化时候就会侦听到,属于一步操作。
methods是保持一些事件的储存位置,存放一些方法的空间。
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
条件渲染 (使用 v-if)
条件展示 (使用 v-show)
动态组件
组件根节点
这里是一个典型的例子:
<body>
<div id="app">
<input type="button" value="切换" @click="flag=!flag"/>
<transition enter-active-class='box' leave-active-class='box1' :duration=2000>
<h3 v-if="flag">我是一个h3</h3>
</transition>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
flag:false
}
})
</script>
</body>
<style>
/* .my-enter,.my-leave-to{
background-color: #204D74;
transform: translateX(80px);
transition-duration: 1s;
}
.my-enter-to,.my-leave{
background-color: red;
} */
.box{
transform: translate(100px);
transition-duration: 2s;
background-color: #255625;
}
.box1{
transform: translate(0px);
transition-duration: 2s;
background-color: red;
}
</style>
当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:
① 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
②如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
③如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)
在进入/离开的过渡中,会有 6 个 class 切换。
v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
<style>
[v-cloak]{
display: none;
}
li{
width: 100%;
border: 1px dashed #999999;
margin: 5px;
line-height: 35px;
padding-left: 5px;
font-size: 12px;
}
li:hover{
background-color: hotpink;
transition: all 0.8s ease;
}
/* 添加时候的效果(指进入的效果) */
.v-enter,.v-leave-to{
opacity: 0;
transform: translatey(80px);
}
.v-enter-active,.v-leave-active{
transition: all 0.6s ease;
}
/* 移除时候的效果(指出去时候的效果) */
/* .v-move与 .v-leave-active配合使用,能够实现列表后续的元素,渐渐地飘上来的效果*/
.v-move{
transition: all 0.6s ease;
}
.v-leave-active{
position: absolute;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<label>
id:<input type="text" v-model="id"/>
</label>
<label>
name:<input type="text" v-model="names"/>
</label>
<input type="button" value="添加" @click="add()" />
<!-- transition-group默认渲染成span元素 -->
<!-- appear指刚开始页面进入的渐入效果 -->
<transition-group tag='ul' appear>
<li v-for="(item,index) in list" :key='item.id' @click="del(index)">{
{
item.id }}---{
{
item.name }}</li>
</transition-group>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
id: '',
names: '',
list: [{
id: 1,
name: '赵高'
},
{
id: 2,
name: '秦桧'
},
{
id: 3,
name: '魏忠贤'
},
{
id: 4,
name: '严嵩'
}
]
},
methods: {
//添加
add() {
this.list.push({
id: this.id,
name: this.names
});
this.id = '';
this.names = ''
},
//删除
del(index){
this.list.splice(index,1)
}
}
})
</script>
</body>
可以在属性中声明 JavaScript 钩子
v-on:enter=“enter”
v-on:after-enter=“afterEnter”
v-on:enter-cancelled=“enterCancelled”
v-on:before-leave=“beforeLeave”
v-on:leave=“leave”
v-on:after-leave=“afterLeave”
v-on:leave-cancelled=“leaveCancelled”
// …
methods: {
// --------
// 进入中
// --------
beforeEnter: function (el) {
// …
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
enter: function (el, done) {
// …
done()
},
afterEnter: function (el) {
// …
},
enterCancelled: function (el) {
// …
},
// --------
// 离开时
// --------
beforeLeave: function (el) {
// …
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
leave: function (el, done) {
// …
done()
},
afterLeave: function (el) {
// …
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// …
}
}
这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用。
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css=“false”,Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
动画钩子详情请参照vue官网,vue动画钩子
1.对于生命周期我们先了解什么是生命周期?从vue实例创建、运行、到销毁的期间,总是伴随着各种各样的事件,这些事件统称为生命周期。
2.生命周期钩子:生命周期过程中的事件函数名叫做生命周期钩子。
3.vue的生命周期函数:
如下图所示
创建期间的生命周期函数:
beforeCreated:实例刚在内存模板中创建出来,此时还没有初始化好data与methods,换句话说此时data中的数据与methods中的方法不能使用与获取;
created:实例已经在内存中创建ok,此时data中的数据与methods中的方法可以获取查看,但是还没有开始编译模板;
beforeMoubted:此时已经完成模板的编译,只是在内存中渲染了模板,但是还没有将数据渲染到页面中;
mounted:已经完成了模板的编译,已经挂载到了页面的容器中;
运行期间的生命周期函数:
beforeUpdated:当数据发生变化时,此时data中的状态值已经保持最新,但是页面的数据还是旧的数据;
updated:实例已经更新完毕,此时data中的状态值已经与页面的显示数据保持一致,页面已经重新渲染好了;
销毁期间的生命周期函数:
beforeDestory:实例在销毁之前调用此步,解绑之间的束缚,但是里面的方法还有指令,过滤器都还可以用,只是在做准备工作;
destory:此时实例已经销毁,里面的方法还有data不能使用,所有的监听都会被移除。
如下代码所示:
<body>
<div id="box" style="width: 100px;">
<p id="p">{
{
msg }}</p>
<input type="button" value="修改msg" @click="msg='nihao'">
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#box',//控制的元素
data(){
//数据
return{
msg:'hello world'
}
},
methods:{
//方法
show(){
alert('hello')
}
},
beforeCreate(){
//实例刚在内存中被创建出来,此时还没有初始化好data与methods,不能找到里面的数据与方法
console.log(this.msg)//undefined
},
created(){
//实例已经在内存中创建ok,此时data与methods中的数据与方法可以拿到了
console.log(this.msg)//hello world
},
beforeMount(){
//此时模板已经编译完成,但是尚未把模板渲染到页面中,此时还是内置模板字符串
console.log(document.getElementById('p').innerText)//{
{ msg }}
},
mounted(){
//此时已经完成模板编译,页面中已经可以看见数据显示了
console.log(document.getElementById('p').innerText)//hello world
},
//当数据发生更新变化时,执行以下的钩子函数
beforeUpdate(){
//当数据发生变化时,此时data中的状态值是最新的,但是页面中的数据还是旧的
//因为此时还没有重新渲染dom节点
console.log('界面中的元素:'+ document.getElementById('p').innerText)//hello world
console.log('data中的msg数据:'+ this.msg)//nihao
},
updated(){
//此时data中的状态值与页面保持一致了,data中的数据是什么页面中的数据就显示什么
console.log('界面中的元素:'+ document.getElementById('p').innerText)//nihao
console.log('data中的msg数据:'+ this.msg)//nihao
},
beforeDestory(){
//vue已经从运行阶段到销毁阶段了,当执行此函数时,实例上的data与methods此时已经处于销毁状态
//但是此时还没有真正销毁,其中的数据还有methods都还可以用,只是处于准备状态(用的很少)
},
destoryed(){
//此时组件已经被完全销毁,组件不能被正常使用(一般用作定时器的清除)
},
//上面有创建销毁的过程,如果用户操作频繁,则对网站的性能消耗特别大
//下面的是vue的激活钩子函数,可以使用vue的内置组件 包裹元素
//这样达到当你再次使用此页面时还保持你原来想要的状态(根据要求使用,一般使用很少)
activated(){
//激活状态的钩子函数,
},
deactivated(){
//停止激活状态的钩子函数
}
})
</script>
</body>
组件的出现就是为了拆分vue实例的代码量的,能够让我们以不同的组件来划分不同的功能模块,将来我们需要什么样的功能,就去调用对应的组件即可。
组件化:是从UI界面的角度惊醒划分的,方便UI组件的重复使用;
模块化:是从代码逻辑的角度进行划分的,方便代码的分层开发,保证每个功能的单一。
定义在vue实例(new Vue({}))之前
Vue.component(‘组件名’,{
template:‘html代码’,
data(){…},
mehtods:{…}
})
<body>
<div id="app">
<we></we>
<hr />
<we></we>
<hr />
<we></we>
</div>
<template id="temp">//注template模板下只有一个根目录,这是vue的规定
<div>
<input type="button" value="+1" @click="adds"/>
<!-- <h4> {
{
count }} </h4> -->
<h4> {
{
counts }} </h4>
</div>
</template>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
var obj={
counts:0}
Vue.component('we',{
template:'#temp',
data(){
// return{
// count: 0
// }
return obj
},
methods:{
add(){
this.count++;
},
adds(){
this.counts++;
}
}
})
var vm = new Vue({
el:'#app'
})
</script>
</body>
定义在实例当中,如下代码所示:
<body>
<div id="app">
<h4>{
{
msg }}</h4>
<mycom></mycom>
<hr />
<mycom></mycom>
<hr />
<mycom></mycom>
</div>
<template id="temp">
<div>
<input type="button" value="+1" @click="add"/>
<h3>{
{
count }}</h3>
</div>
</template>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:'你好'
},
methods:{
adds(){
this.count++;
}
},
components:{
mycom:{
//这是创建的局部组件
template:'#temp',
data(){
return {
count:0}
},
methods:{
add(){
this.count++;
}
}
}
}
})
</script>
</body>
<body>
<div id="app">
<a href="" @click.prevent="qiehuan='log'">登录</a>
<a href="" @click.prevent="qiehuan='res'">注册</a>
<a href="" @click.prevent="qiehuan='asd'">其它</a>
<keep-alive>
<!-- component是一个占位符,is是属性,可以用来展示组件的名称 -->
<component :is = "qiehuan"></component>
</keep-alive>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
Vue.component('log',{
template:'登录页面
'
})
Vue.component('res',{
template:'注册页面
'
})
Vue.component('asd',{
template:'其它页面
'
})
var vm = new Vue({
el:'#app',
data:{
qiehuan:'log'
}
})
</script>
</body>
1.父组件向子组件传值
父组件通过props向子组件传值,子组件定义属性名,把父组件的数据绑定在属性上,然子组件中使用props接收,如下代码所示:
<body>
<div id="app">
<coml :message = 'msg'></coml>
</div>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:'这是实例的数据',
check:false,
num:23,
list:[{
id:1,name:'李四1'},{
id:2,name:'李四2'}]
},
methods:{
},
components:{
coml:{
template:'这是子组件上面的html代码----{
{ message }}
',
data(){
return{
msgs:'这是子组件上面的数据'}
},
props:['message'],//这里可以是数组,也可以是对象
//props: {
//message:{
//type:['String']//数据类型
//default:'父组件不给值时候,这就是默认值',
// required:true//这是设置必传,与default二选一
//}
//}
methods:{
}
}
}
})
</script>
</body>
2.父组件向子组件传递方法
父组件向子组件传递方法通过绑定自定义事件,定义事件属性名,然后在子组件中使用$emit()的方法使用,如下代码所示
<body>
<div id="app">
<coml @func = 'show'></coml>//自定义事件绑定
</div>
<template id="temp">
<div>
<h2>这是组件当中的html代码</h2>
<input type="button" value="按钮" @click="myclick"/>
</div>
</template>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:'这是父组件中的数据'
},
methods:{
show(){
console.log('这是父组件当中的方法')
}
},
components:{
coml:{
template:'#temp',
data(){
return{
msg1:'这是子组件当中的数据'}
},
methods:{
shows(){
console.log('这是子组件中的方法')
},
myclick(){
this.$emit('func')//使用此完成父传子的方法
}
}
}
}
})
</script>
</body>
3.子组件向父组件传值
子组件向父组件传值也是通过绑定自定义事件,然后子组件通过$.emit(‘方法名’,参数),这里的参数代表子组件上面的属性,可以是数据也可以是其他的。
<body>
<div id="app">
<coml @func = 'show'></coml>//这是绑定的自定义事件
<h4>{
{
msg }}</h4>
</div>
<template id="temp">
<div>
<h3>这是子组件中的html代码</h3>
<input type="button" value="按钮" @click="myclick"/>
</div>
</template>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:null
},
methods:{
show(data){
this.msg = data;
console.log(this.msg)//这是子组件的数据
}
},
components:{
coml:{
//这是创建的子组件
template:'#temp',
data(){
return{
msgs:'这是子组件中的数据'
}
},
methods:{
myclick(){
//这是使用的方法与携带的子组件的参数数据
this.$emit('func',this.msgs)
}
}
}
}
})
</script>
</body>
4.平行组件之间的传值
平行组件之间传值思路:
①.先创建一个过渡的bus对象 let bus = new Vue(),通过这个对象将数据传递过去
②.创建两个平行之间的组件test1,test2,确定1向2中传递数据
③.在1中设置数据,并且在1中调用方法使用 e m i t 方 法 , b u s . emit方法,bus. emit方法,bus.emit(‘方法的名字’,参数(指数据))
④.在2中接收参数,使用bus.$on(‘方法的名字’,(val)=>{val就是1中传递过来的数据})
<body>
<div id="app">
<mycom></mycom>
<mycon></mycon>
</div>
<template id="test1">
<span @click="handlerClick">传值</span>
</template>
<template id="test2">
<span>{
{
testdata }}</span>
</template>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
/*
平行组件之间传值思路:
1.先创建一个过渡的bus对象 let bus = new Vue(),通过这个对象将数据传递过去
2.创建两个平行之间的组件test1,test2,确定1向2中传递数据
3.在1中设置数据,并且在1中调用方法使用$emit方法,bus.$emit('方法的名字',参数(指数据))
4.在2中接收参数,使用bus.$on('方法的名字',(val)=>{val就是1中传递过来的数据})
*/
let bus = new Vue();
new Vue({
el:'#app',
data(){
return{
}
},
methods:{
},
components:{
mycom:{
template:'#test1',
data(){
return{
testData:'我是test1的数据'
}
},
methods:{
handlerClick(){
bus.$emit('func',this.testData)
}
}
},
mycon:{
template:'#test2',
data(){
return{
testdata:''
}
},
methods:{
add(){
bus.$on('func',(val)=>{
this.testdata = val;//val代表传过来的值
console.log(this.testdata)
})
}
},
created(){
this.add()
}
}
}
})
</script>
</body>
以上四种传值方式最好学习者能自己敲一敲代码,能在浏览器上面运行看看效果,能深层的了解传值的方式,希望这些代码可以帮助你加深学习的兴趣。
5.组件插槽(数据的分发)
<body>
<div id="app">
<asd>
//将下面的p标签分开到模板当中显示
<template slot='header'>
<p>头部标题1</p>
<p>头部标题2</p>
</template>
<template>
<p>内容1</p>
<p>内容2</p>
</template>
<template slot='foother'>
<p>底部标题1</p>
<p>底部标题2</p>
</template>
</asd>
</div>
<template id="tmpl">
<div>
<header>
<slot name='header'></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name='foother'></slot>
</footer>
</div>
</template>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
Vue.component('asd',{
template:'#tmpl',
})
var vm = new Vue({
el:'#app',
data:{
}
})
</script>
</body>
6.使用ref获取DOM元素和组件
给你的元素或者组件绑定一个ref=‘名字’,后面在方法中可以通过$refs.名字就可以获取你的元素与组件
<body>
<div id="app">
<input type="button" value="获取元素" @click="getelement"/>
<h3 ref='myh3'>我是一个特别的元素</h3>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
},
methods:{
getelement(){
//this.$refs是一个集合,包含了所有的ref,
//里面还包含其他属性,比如$root根节点,$parent父节点...等等
console.log(this.$refs.myh3.innerText)
}
}
})
</script>
</body>
首先需要下载路由,1.可以使用cdn的链接通道,必须在有网的情况下引入https://unpkg.com/vue-router/dist/vue-router.js,在引入vue-router之前必须先引入vue.js;
2.下载路由使用npm install vue-router;引入下面内容
import Vue from ‘vue’
import VueRouter from ‘vue-router’
Vue.use(VueRouter)
然后就可以使用路由了
如下步骤所示
<body>
<div id="app">
<router-link to="/login" tag='button'>登录</router-link>
<router-link to='/register' tag='button'>注册</router-link>
<router-view></router-view>//表示占位符,用来显示组件的信息
</div>
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script type="text/javascript">
//第一步:创建组件的模板对象
var login = {
template:'登录组件
',
data(){
},
methods:{
}
}
var register = {
template:'注册组件
',
data(){
},
methods:{
}
}
//第二步:创建路由对象
var vt = new VueRouter({
routes:[//表示路由匹配规则组合
{
path:'/login',name:'login',component:login},
{
path:'/register',name:'register',component:register}
]
})
//第三步:创建vue实例,并将路由对象挂载在app中
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
router:vt//挂载路由对象于app中
})
</script>
</body>
默认渲染成a标签,如果想要渲染成其他标签元素,则后面加上tag=‘元素’
路由分为一级路由与多级路由,如果路由需要嵌套,则需要在路由配置里面加上children属性,然后配置路径与展示页面,如下代码所示:
<style>
.box{
color: red;
}
.box:hover{
color: #7FFFD4;
}
</style>
<body>
<div id="app">
<!-- <a href="#/login">登录</a>
<a href="#/register">注册</a> -->
<!-- 默认渲染成a标签,如果想渲染成其它元素标签,则在里面加入tag=‘button’ -->
<router-link to='/login' tag='button'>登录</router-link>
<router-link to='/register' tag='button'>注册</router-link>
<!-- 这是vue-router提供的,专门用来当作显示占位符的,将来路由规则匹配到的组件就会展示在占位符中 -->
<router-view></router-view>
</div>
<!-- 二级路由 -->
<template id="login">
<div>
<router-link to='/login/login1'>登录1</router-link>
<router-link to='/login/login2'>登录2</router-link>
<router-view></router-view>
</div>
</template>
<script src="../../js/vue.js"></script>
<script src="../../js/vue-router.js"></script>
<script type="text/javascript">
//创建组件模板对象
//组件的模板对象
//一级路由的组件
var login = {
template:'#login',
methods:{
tos(){
this.$router.push({
path:'/register'});//强制跳转
//$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法,
//返回上一个history使用$router.go方法。
}
}
}
var register = {
template:'注册组件
',
methods:{
tol(){
this.$router.back();
}
}
}
//二级路由的小组件
var login1 = {
template:'小登陆1
'
}
var login2 = {
template:'小登陆2
'
}
// **创建组件(这是错误的方法)
// Vue.component('login',{
// template:'登录组件
'
// })
//创建路由对象,
//在new路由对象时候,可以为构造函数传递一个配置对象
var routerobj = new VueRouter({
//route//这表示路由匹配规则
routes:[
//每个路由规则都是一个对象,这个规则对象身上有两个属性
//属性1:path表示监听路由的链接地址
//属性2:component表示 如果前面匹配到的path,则展示对应组件component
//component的属性值必须是一个组件的模板对象,不能是组件的引用名称
//以及路由path必须加/
//{path:'/',component:login},//设置默认显示登录组件
{
path:'/',redirect:'/register'},//重定向,设置默认页面
{
path:'/login',component:login,
//二级路由新加的属性
children:[
{
path:'login1',component:login1},
{
path:'login2',component:login2}
]},
{
path:'/register',component:register}
],
//router-link-active设置选中路由的样式
//给选中的路由加一个class名
linkActiveClass:'box'
})
//创建vue实例对象
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
router:routerobj//将路由规则对象注册到这个实例上面,用来监听URL地址的变化,然后展示相应的组件
})
</script>
</body>
1.使用query方式传递参数
使用query方式传递参数,是直接在地址栏上面以?+参数形式传递,当你想要获取传递的参数时,使用this.$route.query.参数名,query传递参数时不需要配置路由匹配规则,如下代码所示:
<body>
<div id="app">
<!-- 这种传递参数的方法不需要修改path的匹配规则,可以直接的通过this.$route.query调用?后面的数据 -->
<router-link to="/login?id=10&name=lisi" tag='button'>登录</router-link>
<router-link to='/register' tag='button'>注册</router-link>
<router-view></router-view>
</div>
<script src="../../js/vue.js"></script>
<script src="../../js/vue-router.js"></script>
<script type="text/javascript">
//组件的模板对象
var login = {
template:'登录组件------{
{ $route.query.name }}
',
created(){
//组件声明周期钩子函数
console.log(this.$route.query.name)//$route是一个跳转的路由对象,
//每一个路由都会有一个route对象,是一个局部的对象,
//可以获取对应的name,path,params,query等
}
}
var register = {
template:'注册组件
'
}
//创建路由
var vt = new VueRouter({
routes:[
{
path:'/login',component:login},
{
path:'/register',component:register}
]
})
//创建vue实例
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
router:vt
})
</script>
</body>
2.使用params传递路由参数(路由匹配规则中匹配的是name中的路径)
<body>
<div id="app">
<router-link :to="{name:'login',params:{id:12,name:'lisi'}}" tag='button'>登录</router-link>
<router-view></router-view>
</div>
<script src="../../js/vue.js"></script>
<script src="../../js/vue-router.js"></script>
<script type="text/javascript">
//组件的模板对象
var login = {
template:'登录组件--{
{ $route.params.name }}---{
{ $route.params.id }}
',
created(){
//组件声明周期钩子函数
console.log(this.$route.params.id)//$route是一个跳转的路由对象,
//每一个路由都会有一个route对象,是一个局部的对象,
//可以获取对应的name,path,params,query等
}
}
//创建路由
var vt = new VueRouter({
routes:[
{
path:'/login/:id/:name',name:'login',component:login}
]
})
//创建vue实例
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
router:vt
})
</script>
</body>
3.响应路由参数的变化
当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用,此时想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:
<body>
<div id="app">
<!-- 动态绑定的to找的是匹配规则name的路径 -->
<router-link :to="{name:'User',params:{id:12,name:'lisi'}}" tag='button'>用户1</router-link>
<router-link :to="{name:'User',params:{id:11,name:'zhangsan'}}" tag='button'>用户2</router-link>
<router-view></router-view>
</div>
<script src="../../js/vue.js"></script>
<script src="../../js/vue-router.js"></script>
<script type="text/javascript">
//组件的模板对象
var User = {
template:'我是用户--{
{ $route.params.name }}---{
{ $route.params.id }}
',
watch:{
'$route'(to,from){
console.log(to.params.id)
}
}
}
//创建路由
var vt = new VueRouter({
routes:[
{
path:'/User/:id/:name',name:'User',component:User},
{
path:'/User:id/:name',name:'User',component:User}
]
})
//创建vue实例
var vm = new Vue({
el:'#app',
data:{
},
methods:{
},
router:vt
})
</script>
</body>
路由守卫是在路由跳转前做一些验证,比如登录前进行页面跳转验证
1.全局前置守卫
const router = new VueRouter({
... })
router.beforeEach((to, from, next) => {
// to.path即将要进入的目标 路由对象
//from.path当前导航正要离开的路由
//next()指向后执行的函数,且此函数必须执行。next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。
})
2.全局后置守卫
它和前置守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
router.afterEach((to, from) => {
// ...
})
3.路由独享守卫
你可以在路由配置上直接定义 beforeEnter 守卫,只会作用于被设置守卫的路由
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
4.组件内的守卫
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。
beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
beforeRouteLeave (to, from, next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
经过以上的分析总结,vue其实说难不难,说简单不简单,难在于使用时候需要了解其中的数据驱动的方法,以及对于原生js的编程能力要强,这是学习者需要掌握的;简单在于不需要编程者操作dom,能够简化很多多余的代码,而更多的关心数据的变化与视图的渲染,如果你是一位小白,之前没有接触过过vue的知识,这篇文章一定能够让你了解vue的一些基本用法,能够熟练的运用它们,在下一章中会介绍工作中使用的技术,vue全家桶(vue-cli,vue-router,axios,vuex,插件)以及webpack在vue中的配置使用。
如果你觉得这篇文章有帮到你还请点赞分享,文章中存在不足之处需要修改,还请留言告知!!!!!