Vue2.0基础知识
小白新手常规操作之笔记摘要!!本文主要总结了Vue2.0最最最最基础知识
1、Vue2.0在页面标签的用法
<!DOCTYPE html>
<html>
<head>
<!DOCTYPE html>
<title>Vue.js基础指令</title>
<link rel="icon" href="/Vue.js/favicon.ico" /><!--title的图标设置-->
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<style type="text/css">
.class1 {
background: #444;
color: #eee;
}
</style>
</head>
<body>
<div id="vue_det" style="width: 100%;margin:auto;">
<!--{{}}绑定数据-->
<!--{{}}绑定数据也可以是有返回值的函数方法-->
<h1>site : {{site}}</h1>
<h2>{{details()}}</h2>
<!--v-model作用:实现双向绑定-->
<span>v-model双向绑定</span>
<label for="r1"></label>
<input type="checkbox" v-model="use" id="r1">
<br />
<span>v-bind单向绑定</span>
<!--v-bind 单向绑定,数据只能从data流向页面-->
<input type="checkbox" :value="use" id="r1">
<br />
<p> v-model.lazy修饰符</p>
<!--修饰符:lazy作用:只有当文本框内容完成(鼠标聚焦事件和回车事件),p标签内容才会改变-->
<input v-model.lazy="texttitle" />
<p>文本框内容:{{texttitle}}</p>
<!--v-once指令,初次动态渲染后,就视为静态内容,
以后的数据改变不会引起v-once所在结构的更新-->
<p v-once><span>v-once指令 </span>{{texttitle}}</p>
<!--v-bind:属性名=‘表达式’简写为>>>:属性名=‘表达式’ 作用:属性绑定-->
<!-- <div v-bind:class="{'class1':use}">v-bing:class 指令</div> -->
<div :class="{'class1':use}">v-bing:class 指令</div>
<!--v-if满足条件才会渲染到HTML -->
<p v-if="isIf">if隐藏与显示</p>
<!--v-show始终渲染到HTML-->
<p v-show="isShow">Show隐藏与显示</p>
<br />
<p>【for循环:】</p>
<!--此处的in可以修改为of-->
<!--【(value,name,index) in object】比较 item in object-->
<!--(value,name,index) in object:输出的是下标,属性名称,对应的值;
item in object:输出的是:对应的值
(value,name) in object:输出的是属性名称,对应的值;-->
<div v-for="(value,index) in object" v-if="index!=2">
{{index}}.{{value}}
</div>
<!--计算属性(computed)和方法函数(methods)调用最大的明显的区别是有无括号
例如:页面调用:methods--》方法名(),
computed--》方法名
-->
<!--cimputed基于缓存,相关依赖发生时才会取值-->
<p>【计算属性(computed)和方法函数(methods)】</p>
<p>原始字符:{{Messgae}}</p>
<p>计算后反转字符{{reversedMessage}}</p>
<p>使用方法后反转字符{{reversedMessage2()}}</p>
<p><button @click="getSetMessage='你好呀'">改变计算属性的值</button> </p>
<p>【过滤器】</p>
<!--v-text 作用:用于输出纯文本元素,v-html 作用:用于输出HTML元素-->
<!--过滤器 过滤器也可以串联。可以用在v-bind指令中-->
<!--,过滤器也可以进行传值,如:{{a | filter('b','c')}},filter接收的第一个参数是a,依次是b,c-->
<p v-bind:id="rawId | formatId" style="background-color: #444;color: white;">
{{Messgae | capitalize | capitUpper('测试','YJ')}}
</p>
<!--v-on:事件名称=‘函数名称’简写为>>>@事件名称=‘函数名称’ 作用:监听DOM事件-->
<!-- <button v-on:click="onclickMessgae" style="width: 120px;height: 20px;">反转字符</button> -->
<button @click="onclickMessgae" style="width: 120px;height: 20px;">反转字符</button>
<button @click="onclickCS('测试')" style="width: 120px;height: 20px;">带参数的click</button>
<!--原生js阻止冒泡>>>>>>使用Vue阻止冒泡:@click.stop=‘方法名’-->
<!-- 冒泡发生的情景:子元素和父元素绑定了相同的事件,然后点击了子元素,父元素也触发了该事件 -->
<div @click="ZuZhiMP" style="width: 120px;border: 1px solid cadetblue;">
外层div
<div @click="ZuZhiMP" style="width: 120px;border: 1px solid cadetblue;">
里层div
</div>
</div>
<!--阻止默认行为>>>>>使用Vue阻止默认行为:href.prevent='地址' -->
<a href="http://www.baidu.com" @click="ZuZhiAction">百度</a>
<!-- 一次事件,只会执行一次 -->
<div @click.once="OneEvent">一次事件</div>
<!--capture 在父子事件中,加【capture】无论先点哪一个,都会先执行这个-->
<div @click.capture="OneEvent">外层div执行顺序
<div @click="OneEvent">内嵌div</div>
</div>
<!--监听事件-->
<p style="font-size: 25px;">计数器:{{counter}} <input type="text" v-model="counter"></p>
<button @click="counter++" style="font-size: 25px;">监听属性</button>
<!-- //注册全局自定义指令 v-focus -->
<p>全局指令 v-focus:<input type="text" v-focus></p>
<!-- 自定义全局组件 -->
<div>
<input type="text" v-model="texttitle">
<br />
<child v-bind:message="texttitle"></child>
</div>
<p>组件和for循环:</p>
<div>
<!--ref设置:允许我们获取对DOM元素、子组件实例或Vue实例的引用,
以便在Vue组件的方法中进行操作或者访问-->
<input type="text" v-model="name" ref="Inputname">
<button @click="add">添加</button>
<todo-item v-for="item in items" v-bind:todo="item">
</todo-item>
</div>
<p>单纯的for循环</p>
<!--key 的作用:
更新组件时判断两个节点是否相同,相同就复用
不同就删除创建新的-->
<ul>
<input type="text" v-model="name">
<button @click="add">添加</button>
<input type="text" v-model="keyWord" placeholder="请输入名称">
<button @click="UpdateBork">更换数据</button>
<!--不加key,添加时,原本勾选的会变成已经添加的,加key时,文本框添加后,还是原本勾选的-->
<li v-for="item in items" :key="item.id">
<input type="checkbox" />{{item.name}} | {{item.age}}
</li>
<p>搜索结果:</p> <!--模糊查询此处的v-for不是data的数据,而是事件里面的函数-->
<li v-for="item in fileitems" :key="item.id">
<input type="checkbox" />{{item.name}} | {{item.age}}
</li>
</ul>
<!-- 自定义局部组件 -->
<div>
<runoob></runoob>
</div>
<p v-color="curColor">我自定义参数</p>
<!--ref和this.$nextTick()的用法-->
<p>ref和this.$nextTick()的用法</p>
<button ref="tar" type="button" name="button"
@click="testClick">{{testTick}}</button>
</div>
<br /><br />
<script type="text/javascript">
//注册组件 (全局) 组件名称
Vue.component('child', {
//props是子组件用来接受父组件传递过来的一个自定义属性
//父组件的数据通过props传子组件,子组件显示,需要声明props
props: ['message'], //声明
template: '<span>{{message}}</span>'
})
Vue.component('todo-item', {
props: ['todo'],
template: '<li><input type="checkbox"> {{todo.name}}</li>'
})
//局部组件
var Child = {
template: '<h5>局部组件</h5>'
}
//注册全局自定义指令 v-focus
Vue.directive('focus', {
//当绑定元素插入到DOM中
//inserted:绑定指令的元素被添加到父元素上的时候执行
//(指业务逻辑代码中用到了元素事件)
//el -->被绑定指令的那个元素
inserted: function(el) {
//聚焦元素
el.focus();
}
});
//自定义参数
Vue.directive('color', {
//bind:指令被绑定到元素上的时候执行(指令业务逻辑
//代码中没有用到元素事件)
//el -->被绑定指令的那个元素
bind: function(el, obj) {
el.style.color = obj.value;
}
})
//全局过滤器
Vue.filter('capitUpper', function(value, a, b) {
//console.log(a+b);
if (!value) return '';
value = value.toString();
return value + '1234';
})
var cnt = 1;
var data = {
site: "Vue教程",
use: false,
isIf: false,
Messgae: "zxcvb",
isShow: false,
counter: 1,
texttitle: '事件',
rawId: 'someHoId',
newId: 3,
name: '',
keyWord: '',
curColor: 'green',
testTick:'初始值',
object: { //对象
title: 'How to',
Name: 'Jone Doe',
age: '12'
},
items: [{ //数组
id: '1',
name: 'Alice',
age: 25
},
{
id: '2',
name: 'Bob',
age: 30
},
{
id: '3',
name: 'Charlie',
age: 35
}
]
};
//data:{}和data(){return{}},最大的区别是组件数据的共享
//data:{}是对象方式定义数据,父子组件时,修改一个data的属性另一个data属性也会修改;
//data(){return{}}是函数方式定义数据,每一个组件都会调用一次data函数,返回新的data对象
// var 定义也可以省去。
//export default {}是在构建工具中使用。
var vm = new Vue({ //Vue的"V"大写
//el,template,render函数的优先级:el<template<render.
//例如:el和template同时存在,会显示template的内容。
//template: "<div id='haha'>SVYJ</div>",
//vm.$mount("#vue_det")和el:'',作用是一样的
//如果el和$mount都存在,绑定的元素有差异,那么以el为主,
el: '#vue_det', //标签对应的id 绑定节点,el不存在时才会使用vm.$mount("#vue_det")
// render: function(createElement) {
// return createElement('h1', '我是render出来的HTML,年龄' + this.site);
// },
//对象的方式
data: data,
//函数的方式
// data(){
// return{
// site: "菜鸟教程",
// use: false,
// isIf: false,
// Messgae: "zxcvb",
// isShow: false
// }
// },
//局部组件
components: {
'runoob': Child
},
//局部过滤器
filters: {
capitalize: function(value) {
if (!value) return '';
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
},
//对象,过滤器
formatId(value) {
return `SC-${value}` //此处的是``,而不是‘’,单引号
}
},
//函数方法 methods和computed,效果是一样的,但是,computed是基于缓存的
methods: {
//ES6+语法-->UpdateBork() {}
//JavaScript对象-->UpdateBork:function(){}
//以上两种方式都可以
//函数
details: function() {
return this.site + " - 学的不仅是技术,更是梦想!";
},
//有返回值的点击事件
onclickMessgae: function() {
//split('') 报数据拆分为数组
//reverse(),反转的意思,只对数组有效,所以要跟在split('')后面
//join('') 重组,把数组合成一个字符串
return this.Messgae = this.Messgae.split('').reverse().join('');
},
//有参数的点击事件
onclickCS(a) {
alert(a);
},
//阻止冒泡
ZuZhiMP(event) {
alert('测试!')
//使用Vue阻止冒泡时,注销这段
//event.stopPropagation(); //原生js阻止冒泡
},
//阻止默认行为
ZuZhiAction(event) {
alert('不可跳转')
event.preventDefault(); //阻止原生js默认行为
},
//一次事件,只会执行一次
OneEvent(event) {
alert('一次事件!')
},
reversedMessage2: function() {
cnt += 1;
return cnt + '-' + this.Messgae.split('').reverse().join('');
},
//添加
add() {
//push(),末尾添加N个元素,console.log(this.item.push({}))并返回新的长度
//unshift(),向数组的开头添加N个元素,并返回新的数组长度
this.items.unshift({
id: ++this.newId,
name: this.name,
age: ++this.newId,
})
//console.log(this.$refs.Inputname);
//shift(),用于删除数组的第一个元素 console.log(this.items.shift()),并返回值
//pop(),删除数组的最后一个元素,console.log(this.items.pop())并返回值
//splice(1)-->保留前一个元素之后的全部删除
//splice(2,1)-->从索引位置(index:2)删除,删除一个元素
//splice(1,2,'a','b')-->从索引位置(index:1)删除,删除两个元素,并添加两个元素替代被删除的元素
//splice(1,0,'a')-->从索引位置(index:1)添加,添加两个元素
//reverse() 颠倒数组中元素的顺序 this.items.reverse()
},
//事件:ref和this.$nextTick的用法
testClick(){
this.testTick='改变了的值';
//这时候直接打印,由于dom还没有更新
//值还是改变之前的值
console.log(this.$refs.tar.innerText);
//this.$nextTick方法是当数据被修改后使用这个方法
//会回调获取更新后的dom在渲染出来
this.$nextTick(()=>{
//dom元素更新后执行,这里打印的是更新之后的值
console.log(this.$refs.tar.innerText);
})
},
//Vue的更新语法,暂有问题
UpdateBork() {
//Vue.set(this.items, 1, 'sss');
//this.$set('对象','属性','值'); 或 this.set('对象','属性','值');
}
},
//1、在实例化之前被调用
beforeCreate: function() {
//这个方法的时候data还没有加载,所以此方法一般用不到
console.log("[beforeCreate]组件实例化之前执行的函数");
},
//2、实例被创建后调用
//实例化初始之后,被添加到DOM元素之前触发
created: function() {
console.log("[created]组件实例化完毕,但是页面还没有显示");
},
//3、在元素*(虚拟DOM)已经准备好被添加到DOM,但是还没有添加时触发
beforeMount: function() {
//要保证有el,或者vm.$mount(),负责这里不会执行
console.log("[beforeMount]组件挂载前,但页面还未显示,但是虚拟的DOM已经配置");
},
//4、html加载完成后执行,执行顺序:子组件-父组件
mounted: function() {
// 如果有template属性模板,会用模板替换外部的el,
//只要有此属性,直接卸载外部el找中的内
// 这将没有任何意义了
// template只能有一个更元素,不能是文本节点,
// 真实的dom渲染完了,可以操作dom了
console.log("[mounted]组件挂载后,此方法执行后,页面显示");
},
//5、数据更新将要对DOM做一些修改时的触发
//数据发生改变,还没有渲染之前
beforeUpdate: function() {
//当页面依赖的数据发生变化时才执行,一般用watch来替换,这个方法不好用
//页面依赖的数发生变化,数据已变化,页面还没有渲染
console.log("[beforeUpdate]组件更新前,但是页面还没有显示,但是虚拟DOM已配置")
},
//6、在DOM的更新已经完成后触发
//数据重新渲染之后
updated: function() {
//重新渲染页面后执行,可以执行操作DOM
console.log("[updated]组件更新后,此方法执行后, 页面显示");
},
//7、在组件即将被销毁并且从DOM上移出时触发
beforeDestroy: function() {
console.log("[beforeDestroy]组件销毁前")
},
//8、组件被销毁后触发
destroyed: function() {
console.log("[destroyed]组件销毁");
},
//计算属性,
computed: {
reversedMessage: function() {
cnt += 1;
return cnt + '-' + this.Messgae.split('').reverse().join('');
},
//模糊查询
fileitems() {
return this.items.filter((p) => {
return p.name.indexOf(this.keyWord) !== -1
})
},
//计算属性中get和set
getSetMessage: {
////getter
get: function() {
return this.Messgae.split('').reverse().join('');
},
//// setter
set: function(newValue) { //例如:点击事件传的参数
this.Messgae = newValue;
}
}
},
//监听事件
watch: {
// (1).Vue中的watch默认不监测对象内部值的改变(一层)。
// (2).配置deep:true可以监测对象内部值改变(多层)。
// 备注:
// (1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
// (2).使用watch时根据数据的具体结构,决定是否采用深度监视。
counter: function(val) {
deep: true, //深度监视
console.log((val));
},
}
});
//document.write(vm.$data==data) // true
//监听事件
vm.$watch('counter', function(nval, oval) {
alert('计数器的变化:' + oval + '变为' + nval + '');
})
</script>
</body>
</html>
2、Vue2.0钩子方法的讲解
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>钩子函数的介绍</title>
</head>
<body>
<!-- 前沿:
通过前面几节的学习,我们已经对vue有了初步的了解,vue可以帮我们干什么,
而接下来就介绍vue的生命周期和它常用的钩子函数,
那么我们就来看看对于vue的生命周期.
1. 理解生命周期的含义
生命周期:就是一个组件从实例化创建并添加到DOM开始 ,一直到组件被销毁的整个过程 。
生命周期函数(钩子函数): 就是在Vue生命周期的整个过程的不同阶段被调用的函数
2. 生命周期图
首先来一下官网的对于vue生命周期的图解, 官网上目前有8个生命周期函数,
还有两个我们之后再看. 先看看基本的8个钩子函数
3. 钩子函数的理解
通过打断点的方式,让我们好好理解声明周期的钩子函数,
你们也可以自己复制代码进行测试好好理解Vue的钩子函数 -->
<script>
new Vue({
el: "#app",
data: {},
methods: {},
// 1. 在实例化之前被调用
beforCreate: function() {
// 这个方法的时候data还没有加载,所以此方法用不到
// 一般不会再这里处理什么事情
alert("组件实例化之前执行的函数");
debugger;
},
// 2. 实例化初始之后,被添加到DOM元素之前触发
created: function() {
// 可以在这里发送ajax,初始化操作
alert("组件实例化完毕,但页面还未显示");
debugger;
},
// 3. 在元素(虚拟DOM)已经准备好被添加到DOM,但是还没有添加时触发
beforeMount: function() {
// 要保证有el,或者vm.$mount() 否则这里不会执行
alert("组件挂载前,但页面还未显示,但是虚拟DOM已经配置");
debugger;
},
// 4. 会在元素创建后触发
mounted: function() {
// 如果有template属性模板,会用模板替换外部的el,
//只要有此属性,直接卸载外部el找中的内
// 这将没有任何意义了
// template只能有一个更元素,不能是文本节点,
// 真实的dom渲染完了,可以操作dom了
alert("组件挂载后,此方法执行后,页面显示");
debugger;
},
// 5. 在数据更新将要对DOM做一些修改时触发
beforeUpdate: function() {
// 当页面依赖的数据发生变化时才执行,一般用watch来替换,这个方法不好用
// 页面依赖的数据发生变化,数据已变化,页面还没有渲染
alert("组件更新前,但页面还未显示,但是虚拟DOM已经配置");
debugger;
},
// 6. 后在DOM的更新已经完成后触发
updated: function() {
// 重新渲染页面后执行, 可以操作DOM了
alert("组件更新后,此方法执行后,页面显示");
debugger;
},
// 7. 在组件即将被销毁并且从DOM上移出时触发
beforeDestroy: function() {
//没什么意义,死了就什么都干不了了
alert("组件销毁前");
debugger;
},
// 8. 组件被销毁后触发
destroyed: function() {
alert("组件销毁");
debugger;
}
})
</script>
<!--4. 绑定节点
我们之前学到一直是使用vue配置对象里的el来绑定DOM节点
生命周期图告诉我们,如果我们没有el属性就会查找vue实例对象有没有通过$mount方法来绑定DOM元素
其实就算你是用el绑定了DOM元素,在Vue源码中也是会转为$mount处理 -->
<div id="app">
<div v-html="msg"></div>
</div>
<div id="haha"></div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "hello"
},
}) vm.$mount("#haha")
</script>
<!-- 同时我们还会发现,如果el和$mount都存在,绑定的元素有差异,那么以el为主,
因为生命周期图告诉我们只有当el属性不存在的时候,才会查看$mount方法 -->
<!--5. template模板编译
我们之前学习一直使用的都是没有template模板的, 根据生命周期图显示,
如果我们没有template,模板,我们就会将el 属性对应的挂在点作为我们的模板
如果有template模板,我们就会用以后的模板替换之前的模板 -->
<div id="app"> {{ msg }}</div>
<script>
const vm = new Vue({
el: "#app",
template: "<div id='haha'>我是小当家</div>",
data: {
msg: "hello"
},
})
</script>
<!-- 5.1 注意template模板里只能有一个根标签
所以下面的写法会报错,是错误的写法 -->
const vm =
new Vue(
{
template:` <div id='haha'> 我是小当家 </div> <span></span> `,
data: { msg:"hello" },
}
)
<!-- 5.2 改变数据绑定的位置
如果有template 模板,我们动态绑定的数据,就需要在模板中绑定 -->
<div id="app"> {{ msg }}</div>
<script>
const vm = new Vue({
el: "#app",
template: "<div id='haha'>我是小当家{{ msg }}</div>",
data: {
msg: "hello"
},
})
</script>
<!-- 6. 关于mounted钩子函数中获取DOM元素的问题
6.1 正常在mounted钩子函数里获取DOM -->
<div id="app">
<div v-html="msg"></div>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "<h2 id='box'>hello</h2>"
},
mounted() {
console.log("mounted:");
console.log(box);
},
})
</script>
<!-- 我们会发现获取DOM元素完全没有问题,
6.2 更改DOM节点内容
如果我们动态的修改了DOM节点,那么我们在获取看看 -->
<div id="app">
<div v-html="msg"></div>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "<h2 id='box'>hello</h2>"
},
mounted() { // 动态修改DOM 节点
this.msg = `<h2 id="box">你好</h2>`
// 获取DOM 节点
console.log(box);
},
})
</script>
<!-- 这是我们就会发现我们获取的还是原先的DOM节点,
此时去获取节点内容就会有问题,
获取的DOM节点并不是更改后最新的DOM节点
6.3 解决动态DOM 节点的问题
我们可以使用$nextTice来解决此类问题
在下次 DOM 更新循环结束之后执行延迟回调。
在修改数据之后立即使用这个方法,
获取更新后的 DOM。
$nextTick(),是将回调函数延迟在下一次dom更新数据后调用,
简单的理解是:数据更新后,在dom重新渲染完毕,自动执行该函数,
通过$nextTick 方法来异步操作vue实例
示例: -->
<div id="app">
<div v-html="msg"></div>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "<h2 id='box'>hello</h2>"
},
mounted() {
// 动态修改DOM 节点
this.msg = `<h2 id="box">你好</h2>`
// 获取DOM 节点 console.log(box);
// 通过$nextTick异步处理方法来获取就会得到最新的值
this.$nextTick(() => {
console.log(box);
})
},
})
</script>
<!-- 上面的示例,我们打印了2次box ,box是DOM元素的id,可以用来获取DOM元素,
但是此时两次获取的DOM元素展示的结果不一样
$nextTick.png
第一次获取box虽然数据已经改变, 页面也准备重新渲染新的DOM元素,
但是此时DOM还没有更新完成,就获取box,获取的就是原来的DOM元素内容,
$nextTick方法会在DOM元素更新完成以后才会触发回调函数,
在回调函数中获取的box才是更改后最新的DOM元素
建议在组件学习后在回来看:
带有子组件的示例: -->
<div id="app">
<child ref="child"></child>
</div>
<template id="child">
<div> <span v-for="a in arr">{{a}}</span> </div>
</template>
<script>
var vm = new Vue({
// 根实例
el: '#app',
data: {
radio: 'home',
},
mounted() {
console.log(1);
// 在执行父组件的mounted
// console.log(this.$refs.child.$el.innerHTML);
// 这里打印的是 1,2,3的数组
// 这里可以选择$nextTick方法,这个是在页面渲染完毕后执行
this.$nextTick(() => {
console.log(this.$refs.child.$el.innerHTML);
// 这个时候才4,5,6
})
},
components: {
child: {
template: '#child',
data() {
return {
arr: [1, 2, 3]
}
},
mounted() {
console.log(
2);
// 先打印子组件的mounted
this.arr = [4, 5, 6];
// 说明这里mounted是异步的
}
}
}
});
</script>
</body>
</html>

浙公网安备 33010602011771号