Vue笔记

Vue笔记

let 定义变量, const 定义常量

var是JS的一个设计错误,用var定义的变量出了代码块依然能访问

1
2
3
4
{
var a = 10;
}
console.log(a);

而let不行

1
2
3
4
{
let a = 10;
}
console.log(a);

const定义的常量不能被第二次赋值

Vue基本格式

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<div id="vue_det">
<p>{{site}}</p>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
site: "hello"
}
})
</script>

el 绑定元素,#为ID选择器,同理,可以使用.类选择器和div标签选择器等

vue生命周期

v-once

在标签中加上这个的时候,值只改变一次

v-pre

原封不动的显示出来

v-cloak

斗篷,没啥用

v-text

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<div id="vue_det">
<p v-text="aaa"></p>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
aaa: "你好"
}
})
</script>

aaa对应的值会显示在v-text属性为aaa的标签中

v-html

设置元素的innerHTML

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<div id="vue_det">
<p v-html="aaa"></p>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
aaa: "<a href=''#'>这是测试的HTML</a>"
}
})
</script>

aaa对应的HTML值,会被解析后显示在v-html属性为aaa的标签中

v-on

为元素绑定事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>
<div id="vue_det">
<button v-on:click="bbb">{{msg}}</button>
<button @click="ccc()">{{msg}}</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
msg:"点我"
},
methods:{
bbb:function(){
alert("bbb");
},
ccc:function(){
alert("ccc");
}
}
})
</script>

使用v-click@click均可绑定事件

实时改变值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div id="vue_det">
<div id="vue_det">{{msg}}</div>
<button @click="aaa">{{btn}}</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
btn:"点击后改变值",
msg:"要被改变的"
},
methods:{
aaa:function(){
this.msg = "这是改变后的"
}
}
})
</script>

一个计数器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<body>
<div id="vue_det">
<button @click="add()">{{btn1}}</button>
<div>{{num}}</div>
<button @click="sub()">{{btn2}}</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#vue_det',
data: {
btn1:"sub",
btn2:"add",
num:1
},
methods:{
add:function(){
this.num--;
},
sub:function(){
this.num++;
}
}
})
</script>

v-show

显示和隐藏元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<body>
<div id="vue_det">
<div v-show="flg">这是文字</div>
<button @click="show()">{{btn1}}</button>
<button @click="hide()">{{btn2}}</button>
</div>
</body>
<script>
var app = new Vue({
el:"#vue_det",
data:{
btn1:"显示",
btn2:"隐藏",
flg:true
},
methods:{
show:function(){
this.flg = true;
},
hide:function(){
this.flg = false;
}
}
})
</script>
  • 原理是修改元素的display,实现显示隐藏
  • 指令后面的内容最终都会解析成布尔类型
  • 数据改变之后,对应元素的显示状态会同步跟新

v-if

根据表达式的真假,切换元素的显示和隐藏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div id="app">
<button @click="showOrHide">{{msg}}</button>
<p v-show="isShow">文字文字文字</p>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
msg:"显示或隐藏",
isShow:false
},
methods:{
showOrHide:function(){
this.isShow = ! this.isShow;
}
}
})
</script>

v-show相比,v-if是直接操作DOM树

v-if中也可以写表达式

v-show对资源消耗小

v-bind

使用动态的值

1
<img v-bind:src="变量">
1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<div id="app">
<p v-bind:style="bg">文字文字文字</p>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
bg:"background:red"
}
})
</script>

其中v-bind可以简写为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body>
<div id="app">
<img :src="imgSrc" :title="imgTitle">
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
imgSrc:"https://model-1253780623.cos.ap-guangzhou.myqcloud.com/live2d/model/rem/remu2048/texture_00.png",
imgTitle:"衣服贴图"
}
})
</script>

使用两种方法来判断是否应用样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<style>
.active{
border: 1px solid red;
}
</style>
<div id="app">
<img :src="imgSrc" :title="imgTitle +'!!!'" :class="isAcitve?'active':''">
<img :src="imgSrc" :title="imgTitle +'!!!'" :class="{active:isAcitve}">
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
imgSrc:"https://model-1253780623.cos.ap-guangzhou.myqcloud.com/live2d/model/rem/remu2048/texture_00.png",
imgTitle:"衣服贴图",
isAcitve:false
}
})
</script>

其中isAcitve?'active':''为三元运算符号

{active:isAcitve}表示,active是否有效,取决于isAcitve为真或假(推荐)

Vue图片切换效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<body>
<div id="app">
<img :src="imgSrcList[imgIndex]" width="500px">
<button @click="lastImgFun" v-show="imgIndex>0">{{lastImg}}</button>
<button @click="nextImgFun" v-show="imgIndex<imgSrcList.length-1">{{nextImg}}</button>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
nextImg:"下一张",
lastImg:"上一张",
imgSrcList:[
'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0044.jpg',
'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0045.jpg',
'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0039_1613799292227_88.jpg',
'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0062_1614511056097_10.jpg',
'https://zhfhz.gitee.io/images/%E6%91%84%E5%BD%B1/DSC_0058_1614511054295_12.jpg'
],
imgIndex:0
},
methods:{
lastImgFun:function(){
this.imgIndex--
},
nextImgFun:function(){
this.imgIndex++
}
}
})
</script>

v-for

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<body>
<div id="app">
<ul>
<li v-for="(item,index) in list" :title="item">
{{index}}--{{item}}
</li>
</ul>
<button @click="add">添加</button>
<button @click="del">移除</button>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
list :[1,2,3,4,5]
},
methods:{
add: function(){
this.list.push("添加一个");
},
del:function(){
this.list.shift(); //移除
this.list.splice(i,j) //移除从i开始的j个
}
}
})
</script>

item代表list中的值index代表编号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<body>
<div id="app">
<ul>
<li v-for="(item,index) in list" :title="item">
{{index}}--{{item}}
</li>
</ul>
<input type="text" @keyup.enter="add(txt)" v-model="txt" value="txt">回车添加
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
list :[1,2,3,4,5],
txt:""
},
methods:{
add:function(p1){
this.list.push(p1);
console.log(p1)
}
}
})
</script>

其中p1为形参可以接收传递进来的实参

v-model可以实现双向绑定

axios

功能强大的网络请求库

1
2
3
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
axios.get(地址?查询字符串).then(function(response){},function(err){});
axios.post(地址,{key:value,key2:value2}).then(function(response)(),function(err){});

天气查询小工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<body>
<div id="app">
<input type="text" @keyup.enter="add(txt)" v-model="txt" value="txt">回车查询
<ul>
<li v-for="item in list" :title="item">
{{item}}
</li>
</ul>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
list :[],
txt:""
},
methods:{
add:function(p1){
that = this
this.list = [];
axios.get("https://restapi.amap.com/v3/weather/weatherInfo?key=5d2d3e6c0d5188bec134fc4fc1b139e0&city=" + this.txt +"&extensions=base").then(function(response){
var dateJson = response.data.lives[0];
console.log(response.data.lives[0]);
that.list.push("时间:" + dateJson['reporttime']);
that.list.push("城市:" + dateJson['province'] + dateJson['city']);
that.list.push("湿度:" + dateJson['humidity']);
that.list.push("气温:" + dateJson['temperature']);
that.list.push("天气:" + dateJson['weather']);
that.list.push("风向:" + dateJson['winddirection']);
that.list.push("风力:" + dateJson['windpower']);
},function(err){

});

}
}
})
</script>

使用多个class

1
2
3
4
5
6
7
8
9
10
11
   <style>
.c1{
color: red;
}
.c2{
background-color: blue;
}
</style>
<div id="app">
<div :class="{c1:true,c2:false}">今天的天气很好</div>
</div>

在网页上应用了c1的class,c2没有应用

computed 计算函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<div id="app">
<div>{{aaaAndBbb}}</div>
</div>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{
a:'aaa',
b:'bbb'
},
computed:{
aaaAndBbb:function (){
return this.a + this.b;
}
}
})
</script>

直接调用aaaAndBbb就可以返回aaabbb

ES6增强写法

1
2
3
4
5
6
7
8
const  a = {
aaa(){
console.log("aaa");
},
bbb(){
console.log("bbb");
}
}

调用event变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<div id="app">
<button @click="clickGo('123',$event)">123456</button>
</div>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{

},
methods:{
clickGo:function (a,b){
console.log(a, b);
}
}
})
</script>

sopt 阻止冒泡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body>
<div id="app">
<div @click="divClick">
<button @click.stop="butClick">点我</button>
</div>
</div>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{

},
methods:{
divClick:function (){
console.log("div事件冒泡");
},
butClick:function (){
console.log("按钮事件冒泡,我阻止了div事件冒泡");
}
}
})
</script>

点击按钮,只有按钮事件被执行

prevent 阻止默认事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div id="app">
<form action="#">
<input type="submit" value="提交" @click.prevent="butClick">
</form>
</div>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{

},
methods:{
butClick:function (){
console.log("按钮事件冒泡,我阻止了原来的提交事件");
}
}
})
</script>

点击提交后<input>默认的提交事件会被阻止

一些数组方法

push 在最后添加一个元素
pop 删除数组最后一个元素
shift 删除数组中的第一个元素
unshift 在数组的最前面添加元素
splice 在某个位置插入元素

JavaScript 可变参数 …

1
2
3
function aaa(...num){
console.log(num);
}

该函数可接受任意个参数。

点击哪个哪个变红

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<div id="app">
<ul>
<li v-for="(item,index) in a" :class="{rrr:isRed == index}" v-on:click="toRed(index)">{{index + " . " + item}}</li>
</ul>
</div>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{
a:["aaa","bbb","ccc","ddd"],
isRed:-1
},
methods:{
toRed:function (a){
this.isRed = a;
}
}
})
</script>

key

splice

插入替换元素

过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
{{jg_one | addOne}}
</div>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{
jg_one:50
},
filters:{
addOne(jg){
return jg + 100;
}
}
})

filters中定义过滤器,在变量后,使用|来使用过滤器,过滤器自动把前面的变量当做参数传入

in

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
<div id="app">
<ul v-for="i in t">
<li>{{i}}</li>
</ul>
</div>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{
t:["aaa","bbb","ccc"]
}
})
</script>

使用in来遍历t列表

filter()

list.filter()

1
2
3
4
5
let a = [1,2,3,4,5,6];
let b = a.filter(function (n){
return n > 3
})
console.log(b)

filter类似于过滤器,本示例中输出 [4,5,6]

map()

1
2
3
4
5
let a = [1,2,3,4,5,6];
let b = a.map(function (n){
return n * 2
})
console.log(b)

map返回函数中操作的结果,本示例中输出[2, 4, 6, 8, 10, 12]

reduce()

1
2
3
4
5
let a = [1,2,3,4,5,6];
let b = a.reduce(function (pre,n){
return pre += n
},0)
console.log(b)

reduce有三个参数,reduce(function(初始数,正在取出的数),初始数的初始值)

本示例中输出21

以上三个函数均可以用箭头函数来执行

1
2
3
let a = [1,2,3,4,5,6];
let b = a.reduce((pre,n) => pie + n)
console.log(b)

v-model在checkbox中的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<div id="app">
<input type="checkbox" value="111" v-model="a">111
<input type="checkbox" value="222" v-model="a">222
<input type="checkbox" value="333" v-model="a">333
{{a}}
</div>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{
a:[]
}
})
</script>

在选中复选框后,{{a}}处会实时渲染出a数组本示例全选中后显示的是: [ "111", "222", "333" ]

v-model的一些操作

v-model.lazy

用于在鼠标失去焦点或者按下回车的时候同步值

v-model.number

用于把用户输入的数字转换为数字形式

v-model.trim

用于将用户输入的内容两边的空格去除

组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<div id="app">
<mya></mya>
</div>
<script>
// 注册
Vue.component('mya', {
template: '<h1>自定义组件!</h1>'
})

// 创建根实例
new Vue({
el: '#app'
})
</script>
</body>

局部组件和全局组件

局部组件

只可以在声明的vue中使用

全局组件

声明了之后,可以在任意位置使用

父子组件的通信

  • 注意子组件中的data必须是一个函数
props
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<body>
<div id="app">
<cpn v-bind:cmsg="msg"></cpn>
</div>

<template id="mb">
<div>{{cmsg}}</div>
</template>
</body>
<script>

const mb = {
template:"#mb",
props:["cmsg"]
}

const vm = new Vue({
el:"#app",
data:{
msg:"Hello"
},
components:{
cpn:mb
}
})
</script>

如代码中所示,在父组件vue中定义了一个msg,又定义了一个子组件 mb ,我们的目的是在app节点之外,访问到msg这个变量的值,首先我们要做的是在根节点中使用cpn:mb绑定这个模板mb,然后在模板对象中使用props:['cmsg'] 设置父节点映射到子节点中的变量名。然后,在根节点中创建一个模板<cpn>,使用 v-bind:cmsg=:"msg" 来绑定子节点中的cmsg和父节点中的msg,这样就可以在子节点中访问到父节点中的内容了。

类型限定
1
2
3
4
5
6
7
8
9
10
11
props:{
cmsg:String
}
//或者这样
props:{
cmsg:{
type:String,
default:'123', //默认值,类型是对象或者数组时,对象要是一个函数
required:true //使用时必传该参数
}
}
子传父
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<body>
<div id="app">
<cpn @btnclick="cpnClick"></cpn>
</div>

<template id="mb">
<button @click="btnClick(msg)">{{msg}}</button>
</template>
</body>
<script>
const mb = {
template:"#mb",
data(){
return{
msg:"Hello"
}
},
methods:{
btnClick:function (msg){
this.$emit('btnclick',msg)
}
}
}

const vm = new Vue({
el:"#app",
data:{
},
methods: {
cpnClick:function (msg){
console.log(msg)
}
},
components:{
cpn:mb
}
})
</script>

我们的目的是把子组件中的msg传给父组件,首先,我们要在子组件中定义一个方法btnClick其中this.$emit('btnclick',msg)用来传递参数,this.$emit('btnclick')用于把event对象发送到父组件中,后面跟着的msg表示只发送msg参数,在父组件中,我们要创建一个cpnClick函数来接收参数,接下来,我们要用<cpn @btnclick="cpnClick"></cpn>btnclickcpnClick绑定在一起。

当子组件中的按钮被点击时,调用子组件中的btnClick函数,该函数使用$emit通过绑定的函数把数据传送到父节点。

父访问子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>
<div id="app">
<button @click="btnClick">Click</button>
<cpn1></cpn1>
</div>

<template id="mb1"></template>
</body>
<script>
const vm = new Vue({
el:"#app",
methods:{
btnClick(){
console.log(this.$children);
}
},
components :{
'cpn1':{
template:"#mb1",
} }
})
</script>

slot

Vue插槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="app">
<cpn1>
<div>你好</div>
</cpn1>
</div>

<template id="mb1">
<div>
hello
<slot></slot>
</div>
</template>
</body>
<script>
const vm = new Vue({
el:"#app",
components:{
'cpn1':{
template:"#mb1"
}
}
})
</script>

使用<slot>来定义插槽

插槽类似于接口,在模板定义了里面的内容之后,使用<slot>来放置一个插槽接口,这操作后,我们就可以在使用这个模板的时候,使用类似于<div>你好</div>的操作往模板里放进任意元素。

具名插槽使用

在使用插槽的时候,如果我们定义了多个插槽,那么在使用的时候,在一个插槽中放入东西,所有插槽就会跟着改变,所以,我们可以给插槽定义一个名字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
	<div id="app">
<cpn1>
<div slot="a1">你好1</div> <!--使用a1插槽-->
</cpn1>
<cpn1>
<div slot="a2">你好2</div><!--使用a2插槽-->
</cpn1>
<cpn1>
<div slot="a3">你好3</div><!--使用a3插槽-->
</cpn1>
</div>

<template id="mb1">
<div>
<slot name="a1"></slot><!--定义a1插槽-->
<slot name="a2"></slot><!--定义a2插槽-->
<slot name="a3"></slot><!--定义a3插槽-->
</div>
</template>
</body>
<script>
const vm = new Vue({
el:"#app",
components:{
'cpn1':{
template:"#mb1"
}
}
})
</script>

编译作用域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<body>
<div id="app">
<cpn1>
<div v-show="isShow">你好</div>
</cpn1>
</div>

<template id="mb1">
<div>
<slot></slot>
<div v-show="isShow">今天的天气很好</div>
</div>
</template>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{
isShow:true
},
components:{
'cpn1':{
template:"#mb1",
data(){
return{
isShow:false
}
}
}
}
})
</script>

如本示例:

我们在模板中定义了一个div他的v-show=isSwho,我们在使用该模板的时候,在插槽中定义了一个div他的v-show=isShow,但是在浏览器中渲染的时候,今天天气很好不会被渲染出来,你好会被渲染出来,这是因为,在模板中定义的isShow使用的是模板中定义的值,而在根节点app中定义的isSwho使用的是根节点data中的值。

插槽总结:父组件替换插槽标签,但是内容由子组件来提供

需要在多个界面进行展示

内容在子组件,希望父组件告诉我们如何展示

在插槽中使用组件中定义的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<body>
<div id="app">
<cpn1></cpn1>
<cpn1>
<template slot-scope="slot">
<ul>
<li v-for="item in slot.data">{{item}}</li>
</ul>
</template>
</cpn1>
</div>
<template id="mb1">
<slot :data="Name"></slot>
<div>hello</div>
</template>
</body>
<script>
const vm = new Vue({
el:"#app",
data:{
},
components:{
"cpn1":{
template:"#mb1",
data(){
return{
"Name":["111","222","333"]
}
}
}
}
})
</script>

如代码所示:我们在子组件中第定义了一个变量Name,并且子组件中有一个插槽,我们的目的是在自定义插槽中的内容的时候,可以调用在组件中定义的变量。

首先在定义插槽的slot标签中,使用:data="Name"来创建一个data变量,这里的data可以是任意名称。

接下来我们在使用的时候

1
2
3
4
5
6
7
<cpn1>
<template slot-scope="slot">
<ul>
<li v-for="item in slot.data">{{item}}</li>
</ul>
</template>
</cpn1>

要先在模板插槽中定义一个 template或其他的节点,slot-scope="slot"使用slot或其他变量名来定义接收到的变量,然后使用slot.data来调用变量

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020-2021 ZHF
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信