vue中created钩子函数与mounted钩子函数的使用区别:
- created: 是在实例创建完成后立即调用。在这一步,实例已完成以下配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
- mounted: 钩子函数一般是用来向后端发起请求拿到数据以后做一些业务处理。dom已经拿到了
插值操作
mustache
双大括号,不仅可以直接写变量,也可以写简单的表达式
<body>
<div id="app">
<p>{{message}}</p>
<p>{{message + " " + msg}}</p>
<p>{{count*3}}</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
message: 'Hello Vue.js!',
msg:'ddddd',
count:2,
},
})
</script>
</body>
v-once
该指令表示元素和组件只渲染一次,不会随着数据的改变而改变
<body>
<div id="app">
<!-- ///不希望界面随意跟随改变
//该指令表示元素和组件只渲染一次,不会随着数据的改变而改变 -->
<p v-once>{{message}}</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
message: 'Hello Vue.js!',
msg:'ddddd',
count:2,
},
})
</script>
</body>
v-html
不是简单的将string显示出来,而是可以让string中的标签以html格式显示
<body>
<div id="app">
<p v-html = "url"></p>
<p v-text="message"></p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
message: 'Hello Vue.js!',
url:'<a href="http://www.baidu.com">百度一下</a>',
count:2,
},
})
</script>
</body>
v-pre
v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的mustach语法
<body>
<div id="app">
<!-- //v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的musthch语法 -->
<!-- 显示Hello Vue.js! -->
<p>{{message}}</p>
<!-- 显示{{message}} -->
<p v-pre>{{message}}</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
message: 'Hello Vue.js!',
url: '<a href="http://www.baidu.com">百度一下</a>',
count: 2,
},
})
</script>
</body>
v-cloak
在某些情况下,我们浏览器可能会直接显示出未编译的mustache标签
<body>
<div id="app">
<!-- //在某些情况下,我们浏览器可能会直接显示出未编译的mustache标签 -->
<!-- //在vue解析之前,div中有属性v-cloak
//在vue解析之后,div中没有一个属性v-cloak -->
<p v-cloak>{{message}}</p>
</div>
<script>
var a = 2;
setTimeout(function () {
var app = new Vue({
el: "#app",
data: {
message: 'Hello Vue.js!',
},
})
}, 2000)
</script>
</body>
v-bind
属性需要绑定一些变量
简写的
<body>
<div id="app">
<a v-bind:href="url">百度一下</a>
<!-- //v-bind有一个对应的语法糖,也就是简写方式 -->
<img :src="imgSrc">
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
message: 'Hello Vue.js!',
url:"http://www.baidu.com",
imgSrc:"https://www.baidu.com/img/dong_8f1d47bcb77d74a1e029d8cbb3b33854.gif"
},
})
</script>
</body>
绑定class语法
- 对象语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../vue.js"></script>
<style>
.highlight {
background-color: red;
}
.big{
font-size: 19px;
}
</style>
</head>
<body>
<div id="app">
<p class="title" :class="{highlight:isHighlight,big:isBig}">你好</p>
<p class="title" :class="getClasses()">你好</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
isHighlight: true,
isBig:true
},
methods: {
highclick: function (index) {
this.isHigh = false;
},
getClasses: function () {
return {
highlight: this.isHighlight,
big: this.isBig
}
}
}
})
</script>
</body>
</html>
- 数组语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../vue.js"></script>
<style>
.highlight {
background-color: red;
}
.big {
font-size: 19px;
}
</style>
</head>
<body>
<div id="app">
<p class="title" :class="[isHighlight,isBig]">你好</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
isHighlight:'highlight',
isBig:'big'
},
methods: {
}
})
</script>
</body>
</html>
绑定style语法
- 对象语法
<body>
<div id="app">
//
<p style="color: red;">你好</p>
<p :style="{color:'red'}">你好</p>
<p :style="{color: fontColor,fontSize:sfontSize+'px'}">你好</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
fontColor:'red',
sfontSize:18,
},
methods: {
}
})
</script>
</body>
- 数组语法
<body>
<div id="app">
<p :style="[fontColor,sfontSize]">你好</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
fontColor:{color:'red'},
sfontSize:{fontSize:'18px'},
},
methods: {
}
})
</script>
</body>
计算属性
在模板中可以直接通过插值语法显示一些data中的数据
但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示。
-
计算属性中的setter和getter
-
计算属性的缓存
methods和computed看起来都可以实现我们的功能
计算属性会进行缓存,如果多次使用时,计算属性只会调用一次
<body>
<div id="app">
<p>{{getFullName()}}</p>
<p>{{FullName}}</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
firstName: "Lebron",
lastName: "James",
FullName:"Liu yun",
},
methods: {
getFullName: function () {
//this.FullName = "Liu yun";
return this.firstName + " " + this.lastName;
}
},
computed: {
// FullName:function(){
// return this.firstName + " "+ this.lastName;
// }
FullName: {
set: function (newValue) {
const names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1];
},
get: function () {
return this.firstName + " " + this.lastName;
}
}
}
})
</script>
</body>
结果显示:
let/var
事实上var的设计可以看成JavaScrip语言设计上的错误,但是这种错误多半不能修复和移除,因为需要向后兼容。let是更完美的var
一 变量提升
var存在变量提升,而let不存在变量提升,所以用let定义的变量一定要在声明后再使用,否则会报错。
test:function(){
//正常执行
console.log(a);
var a = 2;
//会发生异常
// console.log(b);
// let b =1;
}
二 作用域
var:只有全局作用域和函数作用域概念,没有块级作用域的概念。
let:只有块级作用域的概念 ,由 { } 包括起来,if语句和for语句里面的{ }也属于块级作用域。
ES5之前因为if和for都没有块级作用域的概念,所以在很多时候,我们都必须借助于function的作用域来解决外面变量的问题
ES6加入了let,let它有if和for的块级作用域
- var
//全局作用域例子
//也就是除了在函数内部定义的变量,其他都是全局变量。
for(var i=0;i<100;i++){
;
}
console.log(i); // 100
//函数作用域例子,如下 b会输出10 ,而a会报错“a is not defined”,为什么呢?
//因为对于不声明而直接赋值的变量(b),相当于全局变量。
//而对于在函数里声明赋值的变量(a),它只在函数内部有效,外部无法访问,否则会报错
function func(){
b=10;
var a=100;
}
func();//调用函数
console.log(b); // 10
console.log(a); //报错 a is not defined
- let
//例子1
//会报错“a is not defined”,因为在if代码块内,使用let声明变量之前,该变量都是不可用的,否则会报错
if(true){
a=123;
let a;
}
//例子2
//会报错“i is not defined”,因为用let定义的i只在for循环体内有效
for(let i=1;i<100;i++){
;
}
console.log(i)
三、重复声明
var:变量可以多次声明
let:变量不允许重复声明,let不允许在相同作用域内,重复声明同一个变量。不能在函数内部,重新声明同一个参数
四 例子
<body>
<div id="app">
<p >你好</p>
<button>Test1</button>
<button>Test2</button>
<button>Test3</button>
<button>Test4</button>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
},
methods: {
test: function () {
for (var i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);
}
},
mounted: function () {
let btns = document.getElementsByTagName('button');
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
alert('点击了' + i + '个');
}
}
}
})
</script>
</body>
结果显示:
都是4
const的使用
const 定义的变量 首次声明时,必须赋值
const定义的变量,不能修改其值
const定义的对象,可以修改对象里的属性,但不能改变它指向的对象地址
const a = 2;
//const aa;//会报错需要赋值
//a =3;会报异常
const obj = {
name:"ly",
age:19
}
obj.name = "ss";//可以正常执行
//会报异常
// obj = {
// name:'dd',
// age:20
// }
//属性的增强写法
const name ="sss";
const age = 20;
const obj2 = {
name,
age
}
console.log(obj2)
增强写法
//属性的增强写法
const name ="sss";
const age = 20;
const obj2 = {
name,
age
}
console.log(obj2)
// const obj3 ={
// test:function(){
// },
// test2:function(){
// }
// }
//增强写法
const obj3 = {
test(){
},
test2(){
}
}
事件监听
v-on介绍
缩写:@
预期:Function|Inline Statement | Object
参数:event
- 当方法不需要额外参数,那么方法的()不用添加,但是注意:方法本身有一个默认参数event,会默认将原生事件event传递进去
- 如果需要传入某个参数,同时需要event时,可以通过$event
vue会默认将浏览器生产的的event事件对象作为参数传入到方法
如果需要传入某个参数,同时需要event时,可以通过$event
修饰符
- .stop 调用event.stopPropagation()
- .prevent 调用event.preventDefault()
- .{keyCode| keyAlias} 只当事件时从特定键触发时才回调
- 监听组件根元素的原生事件
- .onece 只触发一次
阻止事件冒泡
<body>
<div id="app">
<div @click="divclick">
<p >ddddddd</p>
<button @click.stop="btnclick">maopao</button>
</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
},
methods: {
btnclick(){
console.log("button click");
},
divclick(){
console.log("div click");
}
},
})
</script>
</body>
阻止默认事件
<button @click.prevent="btnclick">maopao</button>
键盘事件
<input type="text" @keyup.enter="enterClick">
v-if 和v-show
v-show和v-if的用法非常相似,也用于决定一个元素是否渲染
v-if和v-show都可以决定一个元素是否渲染,那么开发中我们如何选择呢
v-if 当条件为false时,压根不会由对应的元素在Dom中
v-show当条件为false时,仅仅是将元素的display属性设置为none而已
开发中如何选择呢
当需要在显示与隐藏之间切片很频繁时,使用v-show
当只有一次切换时,通过使用v-if
注意:v-show没有渲染时,也是可以获取到dom,但是v-if不能获取到
<body>
<div id="app">
<p id="showif" v-if="isShow">你好</p>
<p id="showP" v-show="isShowdd">你好年</p>
<button @click="show">显示/隐藏</button>
<button @click="getDom">get</button>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
isShow: false,
isShowdd: false,
},
methods: {
show() {
this.isShow = !this.isShow;
this.isShowdd = !this.isShowdd;
},
getDom() {
var dd = document.getElementById("showP");
var ddddd = document.getElementById("showif");
console.log(dd);
console.log(ddddd)
}
}
})
</script>
</body>
v-else-if 和 v-else
<div id="app">
<p v-if="score>=90">优秀</p>
<p v-else-if="score>=80">良好</p>
<p v-else-if="score>=60">及格</p>
<p v-else>不及格</p>
</div>
用户登录案例
<body>
<div id="app">
<span v-if="isUser">
<label for="userName">用户账号</label>
<input type="text" id="userName" placeholder="用户账号" key="aaa">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="用户邮箱" key="bbbb">
</span>
<button @click="isUser=!isUser">切换类型</button>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
isUser: true,
},
})
</script>
</body>
问题:
如果我们在输入内容的情况下,切换了类型,我们会发现文字依然显示之前输入的内容
但是按道理讲,我们应该切换到另外一个元素中了
在另外一个input元素中,我们并没有输入内容
为什么会出现这个问题
原因:
这是因为vue在进行dom渲染时,处于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素
在上面的案列中,vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了
解决:
如果我们不希望vue出现类似重复利用的问题,可以给对应的input添加key,并且我们需要保证key的不同
组件的key属性
- 当某一层有很多相同的节点时,也就是列表节点时,我们希望插入一个新的节点
- 我们希望可以B和C之间加入一个F,DIff算法默认执行起来是这样的。即便把C更新成F,D更新成C,E更新成D,最后插入E,是不是很没有效率。
- 所以我们需要使用key来给每个节点,做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点
- 所以,key的主要作用是为了高效的更新虚拟DOM
<body>
<div id="app">
<ul>
<li v-for="(item,index) in movies" :key="item">{{item}}</li>
</ul>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
movies: ["dd", "cc", "aa"],
},
})
</script>
</body>
数组中响应式方法
<body>
<div id="app">
<ul>
<li v-for="(item,index) in movies" :key="item">{{item}}</li>
</ul>
<button @click="pushClick">push</button>
<button @click="popClick">pop</button>
<button @click="shiftClick">shift</button>
<button @click="unshiftClick">unshift</button>
<button @click="spliceClick">splice</button>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
movies: ["dd", "cc", "aa"],
},
methods:{
pushClick(){
this.movies.push('ddd');
},
popClick(){
this.movies.pop();
},
shiftClick(){
this.movies.shift();//从起始位置开始删除元素
},
unshiftClick(){
this.movies.unshift("cccc");//在开始位置添加元素
},
//添加,删除,修改元素
spliceClick(){
//this.movies.splice(0,2);//从0的位置开始,删除两个元素
//this.movies.splice(0,0,'dddd','cccc');//从0的位置开始添加两个元素
//this.movies.splice(0,2,'ddd','ccc');//修改前两个元素
Vue.set(this.movies,0,'aaaa');//vue中修改数组的方法
}
}
})
</script>
</body>
for of 和in
<script>
var a = 2;
let ddddd= ["dd", "cc", "aa"];
let test = function(){
for(let item of ddddd){
console.log(item);//打印的是元素的内容
}
for(let i in ddddd){
console.log(i);//打印的是元素在数组的index,与c#不一样
}
}
test();
</script>
reduce方法
let ddddd = [1, 2, 3, 4, 5, 6];
let test = function () {
this.total = ddddd.reduce((pre, n) => pre + n,0);//pre的默认值是0,n是每次循环时的值,第二次循环时pre是第一次的计算结果
console.log(this.total);
}
test();
filter map reudce的综合用法
let ddddd = [1, 2, 3, 4, 5, 6];
let test = function () {
//let total = ddddd.reduce((pre, n) => pre + n,0);//pre的默认值是0,n是每次循环时的值,第二次循环时pre是第一次的计算结果
let total = ddddd.filter(n => n < 3).map(n => n * 2).reduce((pre, n) => pre + n);
console.log(total);
}
test();
v-model
<body>
<div id="app">
<input type="text" v-model="message">
<p>{{message}}</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
message:"Hello Vue",
},
methods: {
}
})
</script>
</body>
实现原理
<body>
<div id="app">
<!-- <input type="text" v-model="message"> -->
<!-- 实现原理 -->
<input type="text" :value="message" @input="message = $event.target.value">
<p>{{message}}</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
message:"Hello Vue",
},
methods: {
}
})
</script>
</body>
v-model结合radio使用
当有多个radio控件时,如果有只能单选的需求,需要给每个radio加上name属性,且属性值一样;或者v-model绑定了同一属性
<body>
<div id="app">
<label for="male">
<input type="radio" value="male" name="sex" v-model="sex">男
</label>
<label for="female">
<input type="radio" value="female" name="sex" v-model="sex">女
</label>
<p>你的性别是:{{sex}}</p>
</div>
<script>
var a = 2;
var app = new Vue({
el: "#app",
data: {
sex:"male",
},
})
</script>
</body>
v-model结合checkbox的使用
<body>
<div id="app">
<label for="male">
<input type="checkbox" value="basketball" v-model="interest">篮球
</label>
<label for="female">
<input type="checkbox" value="football" v-model="interest">足球
</label>
<label for="female">
<input type="checkbox" value="badminton" v-model="interest">羽毛球
</label>
<p>你的兴趣是:{{interest}}</p>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
interest:[],
},
})
</script>
</body>
v-model结合select的使用
<body>
<div id="app">
<select name="abc" id="" v-model="fruit" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="葡萄">葡萄</option>
</select>
<p>你选的水果是:{{fruit}}</p>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
fruit:"苹果"
},
})
</script>
</body>
v-model修饰符
- lazy修饰符:
默认情况下,v-model默认是在input事件中同步输入框的数据的
lazy修饰符可以让数据在失去焦点或者回车是才更新 - number修饰符
默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当作字符串类型进行处理
number修饰符可以让在输入框中输入的内容自动转成数字类型; - trim修饰符
如果输入的内容首尾有很多空格,通常我们希望将其去除
trim修饰符可以过滤内容的左右两边的空格
设置template
setting–>Editor–>Code Style–> Live Templates–>+ -->template text, abbreviation(快捷键),description
es6
`` 可以生成字符串,有点是可以换行,‘’或“” 换行都需要+