Time-Traveler

时光旅人,向往美好

0%

创建项目

1
vue init webpack project

创建选项,一般只yes router选项,其他全no

启动项目

1
2
3
4
// 编译模式
npm run dev
// 打包模式
npm run build

注意事项

使用vue ui的方式创建项目的话,需要启动vue ui的时候给予命令行工具管理员权限

公共样式书写位置

src>assets>css中创建base.css,将公共样式写进去

导入方式1

1
2
//main.js最后一行添加
require('./assets/css/base.css');

导入方式2

1
@import "./assets/css/base.css";

给路径起别名

作用:防止路径变化而到导致资源失效

配置方法:在package.json同级目录创建vue.config.js文件,填写以下内容

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
configureWebpack: {
resolve: {
alias: {
//配置别名,修改后需要重新编译才能生效
assets: "@/assets",
components: "@/components",
views: "@/views",
},
},
},
};

使用方法:

1
2
<!--注意html中使用的时候,前面要加 ~ ,js中使用只需要包含 @ 就好了-->
<img src="~@/assets/image/tabbar/home.png" alt="">

bug记录

1.多次点击router-link会出现报错

1
Uncaught (in promise) NavigationDuplicated {_name: "NavigationDuplicated"

解决方法:将vue-router版本修改为3.0

1
npm i vue-router@3.0 -S

2.图片引入**:src**失效

原因:浏览器将相对路径识别为项目目录,故图片无法读取到

1
<img :src="abc" alt="">
1
2
3
4
5
6
7
8
9
10
export default {
data() {
return {
// 错误写法
// abc: "../../assets/image/tabbar/home.png"
// 正确写法
abc: require("../../assets/image/tabbar/home.png")
};
},
}

这个是windowTermial的setting.json文件,复制替换即可

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
{
"$schema": "https://aka.ms/terminal-profiles-schema",

"defaultProfile": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",

"copyOnSelect": false,

"copyFormatting": false,

"profiles": {
"defaults": {
"acrylicOpacity": 0.6,
"useAcrylic": false,
"startingDirectory": "G:\\Code"
},
"list": [
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "命令提示符",
"colorScheme": "Solarized Dark",
"commandline": "cmd.exe",
"hidden": false,
"backgroundImage": "C:\\Users\\王二蛋\\OneDrive\\图片\\壁纸\\windowTerminal\\Snipaste_2020-09-13_13-03-02.png",
"backgroundImageOpacity": 0.25,
"backgroundImageStretchMode": "fill"
},
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe",
"hidden": false
},
{
"guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}",
"hidden": true,
"name": "Azure Cloud Shell",
"source": "Windows.Terminal.Azure"
}
]
},

"schemes": [
{
"name": "Campbell",
"foreground": "#F2F2F2",
"background": "#0C0C0C",
"colors": [
"#0C0C0C",
"#C50F1F",
"#13A10E",
"#C19C00",
"#0037DA",
"#881798",
"#3A96DD",
"#CCCCCC",
"#767676",
"#E74856",
"#16C60C",
"#F9F1A5",
"#3B78FF",
"#B4009E",
"#61D6D6",
"#F2F2F2"
]
},
{
"name": "Solarized Dark",
"foreground": "#FDF6E3",
"background": "#073642",
"colors": [
"#073642",
"#D30102",
"#859900",
"#B58900",
"#268BD2",
"#D33682",
"#2AA198",
"#EEE8D5",
"#002B36",
"#CB4B16",
"#586E75",
"#657B83",
"#839496",
"#6C71C4",
"#93A1A1",
"#FDF6E3"
]
},
{
"name": "Solarized Light",
"foreground": "#073642",
"background": "#FDF6E3",
"colors": [
"#073642",
"#D30102",
"#859900",
"#B58900",
"#268BD2",
"#D33682",
"#2AA198",
"#EEE8D5",
"#002B36",
"#CB4B16",
"#586E75",
"#657B83",
"#839496",
"#6C71C4",
"#93A1A1",
"#FDF6E3"
]
},
{
"name": "Ubuntu",
"foreground": "#EEEEEC",
"background": "#2C001E",
"colors": [
"#EEEEEC",
"#16C60C",
"#729FCF",
"#B58900",
"#268BD2",
"#D33682",
"#2AA198",
"#EEE8D5",
"#002B36",
"#CB4B16",
"#586E75",
"#657B83",
"#839496",
"#6C71C4",
"#93A1A1",
"#FDF6E3"
]
},
{
"name": "UbuntuLegit",
"foreground": "#EEEEEE",
"background": "#2C001E",
"colors": [
"#4E9A06",
"#CC0000",
"#300A24",
"#C4A000",
"#3465A4",
"#75507B",
"#06989A",
"#D3D7CF",
"#555753",
"#EF2929",
"#8AE234",
"#FCE94F",
"#729FCF",
"#AD7FA8",
"#34E2E2",
"#EEEEEE"
]
}
],
"keybindings": [
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+c" },
{ "command": "paste", "keys": "ctrl+v" },
{ "command": "find", "keys": "ctrl+shift+f" },
{
"command": {
"action": "splitPane",
"split": "auto",
"splitMode": "duplicate"
},
"keys": "alt+shift+d"
}
]
}

let 与 const 关键字

let能享有块级作用域的特点,一个变量在同一个作用域中无法被let声明2次

const声明的变量一旦创建就必须初始化,且后续无法修改

tips: const声明的复杂对象,只能保证指向的地址不变,地址所存储内容无法保证不被修改

三个高级js数组函数

1
2
3
4
5
6
7
8
9
10
11
12
// filter: 过滤
new_arr = old_arr.filter(fun(n){
// 逻辑 return true 时,将n加入new_arr,否则不加入
})
// map: 计算
new_arr = old_arr.map(fun(n){
// return 计算结果,将计算结果push到new_arr中
})
// reduce: 汇总
res = old_arr.reduce(fun(preValue,n){
// return preValue和n的计算逻辑,例如preValue+n,计算数组中数字的总和
},0)//这里0为preValue的默认值

08-函数扩展

02-Array.from()

01-主要作用

将对象转换成数组

可以将所有拥有Iterator(遍历器)接口的数据结构转换成数组

02-第二个参数

传入一个方法,用于将处理后的数据放入返回的数组,类似于map函数

1
2
Array.from({ length: 2 }, () => 'jack')
// ['jack', 'jack']

03-Array.of()

01-主要作用

将一组值转换为数组

1
2
3
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

与Array方法的区别,没有参数,一个参数,大于等于两个参数的结果不同,需要额外记忆

1
2
3
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

04-copyWithin()

01-主要作用

在数组内部,将数组的某些位置的成员,替换为另一个位置的一个或者一组的成员

第一个参数代表目标位置,第二个参数代表替换的内容,第三个参数代表到第几个结束

1
Array.prototype.copyWithin(target, start = 0, end = this.length)
1
2
// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)

05-find和findIndex

01-find()的使用方法

find用于找到数组中符合规范的某个成员,并返回该成员

该方法的参数是一个回调函数

1
2
[1, 4, -5, 10].find((n) => n < 0)
// -5

该回调函数的可传入的三个参数分别是,当前值,当前位置和原数组

1
2
3
[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10

02-findIndex()的使用方法

findIndex用于找到数组的某个成员,并返回该成员的下标

使用方法与find一致,区别只有返回值不同

03-find和findIndex方法的第二个参数

第二个参数用于绑定回调函数的this对象

1
2
3
4
5
function f(v){
return v > this.age;
}
let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person); // 26

04-可以发现NaN

indexOf方法无法识别数组中的NaN成员

06-fill()数组填充方法

01-主要作用

给一个给定的数组填充数据

1
2
3
4
5
['a', 'b', 'c'].fill(7)
// [7, 7, 7]

new Array(3).fill(7)
// [7, 7, 7]

02-第二、三个参数

用于指定填充的开始和结束的位置

07-entries(),keys()和values()遍历器对象生成方法

01-主要作用

遍历器对象包括,数组,字符串,类数组对象等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"

02-手动遍历

1
2
3
4
5
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']

08-includes

01-主要作用

判断数组内是否包含与参数相同的成员,返回值为布尔值

区别于indexOf,可以正确判断NaN

02-第二个参数

用于指定起始位置

09-flat(),flatMap()数组拉平方法

01-flat()主要作用

将套娃数组拉平,参数代表要拉平几层

如果无论多少都要拉平,使用参数Infinity

02-flatMap()主要作用

将套娃数组拉平一层并使用传入的参数(方法),将数组转换成新数组返回

03-区别

flatMap()只能展开一层数组

09-数组的扩展

10-对象的扩展

01-Object.is

01-主要作用

用于严格比较两个值是否相等

02-与严格相等符号(===)比较

1
2
3
4
5
+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true

02-Object.assign()

01-主要作用

用于将对象进行合并(可枚举属性)

1
2
3
4
5
6
7
const target = { a: 1, b: 1 };

const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

02-注意事项

1.如果有同名属性,后面的会覆盖前面的

2.只有一个参数,则返回该参数本身

3.参数不是对象,则会转为对象然后返回

4.本拷贝为浅拷贝

5.可以处理数组,但是会把数组视为对象

03-常见应用场景

1.为对象添加属性

1
2
3
4
5
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}

2.为对象添加方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});

// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};

3.克隆对象

4.合并多个对象

5.为对象设置默认值

1
2
3
4
5
6
7
8
9
10
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};

function processContent(options) {
options = Object.assign({}, DEFAULTS, options);
console.log(options);
// ...
}

默认值为DEFAULT对象,一旦options中有对应的同名属性,就会替代

jQuery:1.基础

jQuery是一个封装好的js库,目的是让你‘写得更少,做得更多’。

1.jQuery选择器

基础选择器

1
$('选择器') 	// 格式,单引号双引号都行

几个容易忘记的选择器

1
2
3
4
$('div,p,li') 	// 并集选择器
$('li.current') // 交集选择器
$('ul>li') // 子代选择器,tips:只会选择亲儿子,孙子辈的不会被选择
$('ul li') // 后代选择器

筛选选择器

1
2
3
4
5
$('li:first')	// 获取第一个li元素
$('li:last') // 最后一个
$('li:eq(2)') // 索引号为2的元素
$('li:odd') // 奇数
$('li:even') // 偶数

筛选方法(重点)

1
2
3
4
5
6
7
8
$('li').parent()				// 查找父级
$('ul').children('li') // 相当于$('ul>li')
$('ul').find('li') // 相当于$('ul li')
$('.first').siblings('li') // 查找兄弟
$('.first').nextAll() // 查找当前元素之后的所有兄弟
$('.last').preAll() // 查找当前元素之前的所有兄弟
$('div').hasClass('protected') // 查找包含特定的类的元素
$('li').eq(2) // 相当于$('li:eq(2)')

排他思想实现

1
2
3
4
<!--html-->
<button>Button</button>
<button>Button</button>
<button>Button</button>
1
2
3
4
5
6
7
//js
<script>
$('button').click(function () {
$(this).css('background-color','pink');
$(this).siblings('button').css('background-color','');
});
</script>

tips: jquery自带隐式迭代

1.淘宝购物服饰精选(排他思想实现)

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
<!--css略-->
<!--html部分代码-->
<div class="box">
<div class="left">
<ul>
<li>0</li>
<!--省略1-8-->
<li>9</li>
</ul>
</div>
<div class="right">
<div>0</div>
<!--省略1-8-->
<div>9</div>
</div>
</div>
<!--js部分代码-->
<script>
$(function () {
//默认显示第一个元素
$('.right>div').eq(0).show();
$('.left ul li').click(function () {
// 高亮选中,恢复其他
$(this).css('background-color','yellowgreen');
$(this).siblings().css('background-color','');
// 获取选中的小标,用于选中展示哪张图片
var index = $(this).index();
// 显示选中,隐藏其他
$('.right>div').eq(index).show();
$('.right>div').eq(index).siblings('div').hide();
})
})
</script>

<!--上方排他部分,可以缩减为-->
<script>
$('.right>div').eq(index).show().siblings('div').hide();
</script>

image-20200716173733895

image-20200716173800132

2.jQuery样式修改

jq的css表达式只有一个参数时,获取该参数的值

1
2
3
4
$('选择器').css('样式名');
// 例如某div的宽度为300px
console.log($('div').css('width'));
// 打印出来的值为300px

jq的css表达式有两个参数时,修改第一个参数css的值为第二个参数

1
2
3
4
5
6
7
8
$('选择器').css('样式名',‘值’)
// 例如修改某div的宽度为300px
$('div').css('width',‘300px’)
// 等价于
var div = document.querySelector('div');
div.style.width = '300px';
// tips:当参数为数值时,可以不加单位,不加引号,但是尽量不要用
$('div').css('width',300);

一次性修改多项参数的时候,可以使用对象的写法

1
2
3
4
5
6
7
8
$('div').css({
'width': '400px',
//参数为数值时可以省略引号和单位
height: 400,
backgroundColor: 'black'
//注意这里符合属性要使用驼峰命名法
//同时非数值型参数不可以省略引号
})

类操作(实例请查看购物车修改商品背景部分)

1
2
3
$('选择器').addClass('css类名');    	// 添加类
$('选择器').removeClass('css类名'); // 删除类
$('选择器').toggleClass('css类名'); // 切换类 添加删除集合在一起

tips: 类名不要加点’.’,Class记得C大写

3.jQuery效果API

  1. 下滑上滑(下拉菜单实例)

    1
    2
    3
    $('选择器').slideDown(500,swing,fn);		// 下滑
    $('选择器').slideUp(500,swing,fn); // 上滑
    $('选择器').slideToggle(500,swing,fn); // 切换滑动
  2. 淡入淡出(图片聚焦实例)

    1
    2
    3
    4
    fadeIn([s],[e],[fn])		//淡入
    fadeOut([s],[e],[fn]) //淡出
    fadeTo([[s],o,[e],[fn]]) //调整透明度
    fadeToggle([s,[e],[fn]]) //切换淡入淡出
  3. 自定义动画

    1
    animate(params,[speed],[easing],[fn])

    tips:params需要以对象的形式传入

1.下拉菜单更加简便的写法(hover())

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
40
41
<!--原版-->
<!--没有动画效果,需要定义两个动作-->
<script>
$(function () {
$('body>ul>li').mouseover(function () {
$(this).children('ul').show();
});
$('body>ul>li').mouseleave(function () {
$(this).children('ul').hide();
});
});
</script>
<!--新版-->
<!--更加简洁好理解-->
<script>
$(function () {
$('body>ul>li').hover(function () {
$(this).children('ul').slideDown();
},function f() {
$(this).children('ul').slideUp();
})
});
</script>
<!--高级缩减版-->
<!--非常简洁-->
<script>
$(function () {
$('body>ul>li').hover(function () {
$(this).children('ul').slideToggle();
})
});
</script>
<!--升级缩减版-->
<!--防止出现动画排队的情况-->
<script>
$(function () {
$('body>ul>li').hover(function () {
$(this).children('ul').stop().slideToggle();
})
});
</script>

2.图片焦点聚集实例

原理:将选中的图片的兄弟透明度变为0.5

1
2
3
4
5
6
7
8
9
10
<!--css和html略-->
<script>
$(function () {
$('.box div').hover(function () {
$(this).siblings('div').stop().fadeTo(500,0.5)
},function () {
$(this).siblings('div').stop().fadeTo(500,1);
})
})
</script>

效果图

image-20200717170242529

3.手风琴效果简单实现

模仿原型

image-20200718165444761

image-20200718165454862

1
2
3
4
5
6
7
8
9
10
11
12
<!--html部分代码-->
<ul>
<li class="odd">
<div class="big odd">这个是1</div>
<div class="small odd">1</div>
</li>
<!--中间以奇偶排列增加6个li,略-->
<li class="even">
<div class="big odd">这个是8</div>
<div class="small odd">8</div>
</li>
</ul>
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
40
41
/*css部分代码*/
li>div{
color: #11999e;
font-weight: bolder;
font-size: 40px;
line-height: 60px;
}
ul {
width: 620px;
height: 60px;
margin: 200px auto;
}
li {
float: left;
width: 60px;
height: 60px;
}
.big {
display: none;
height: 60px;
width: 200px;
text-align: center;
}
.small {
display: inline-block;
height: 60px;
width: 60px;
text-align: center;
}
.odd .big {
background-color: #cbf1f5;
}
.odd .small{
background-color: #e3fdfd;
}
.even .big {
background-color: #a6e3e9;
}
.even .small{
background-color: #71c9ce;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//js完整代码
$(function () {
$('li').eq(0).css('width','200px');
$('li').eq(0).children('.big').show();
$('li').eq(0).children('.small').hide();

$('li').mouseover(function () {
// 将其他兄弟的宽度全部恢复成60px
$(this).siblings('li').stop().animate({'width':'60px',},500);
// 将自己的宽度变成200px
$(this).stop().animate({'width':'200px',},500);
// 将自己的子节点big淡入,small淡出
$(this).children('.big').stop().fadeIn('fast').siblings('.small').stop().fadeOut('fast');
// 将其他兄弟的子节点big淡,small淡入
$(this).siblings('li').children('.big').stop().fadeOut('fast').siblings('.small').stop().fadeIn('fast');
})
})

4.jQuery获取属性

  1. 获取元素固有属性

    1
    2
    3
    4
    // 获取
    $('选择器').prop('属性');
    // 修改
    $('选择器').prop('属性','值');
  2. 获取元素的自定义属性

    1
    2
    3
    4
    // 获取
    $('选择器').attr('属性');
    // 修改
    $('选择器').attr('属性','值');

5.jQuery获取文本值

  1. 设置获取元素内容

    1
    2
    3
    4
    // 获取
    $('选择器').html();
    // 修改
    $('选择器').html('内容');
  2. 设置获取元素文本内容

    1
    2
    3
    4
    // 获取
    $('选择器').text();
    // 修改
    $('选择器').text('内容');
  3. 获取设置表单值

    1
    2
    3
    4
    // 获取
    $('选择器').val();
    // 修改
    $('选择器').val('内容');

购物车功能

详情查看P058购物车案例

6.jQuery遍历元素

1
2
3
4
5
6
$(element).each(function(index,element){
// 遍历内容
// index为当前循环的下标
// element为当前选中的dom元素
// 注意这里要使用需要转换成jQuery元素
})

7.jQuery创建元素

1
var li = $('<li></li>');

8.jQuery添加与删除元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 添加在该元素内部的最后
$('ul').append('<li></li>');
// 添加在该元素内部的最前
$('ul').prepend('<li></li>'first);

// 添加在兄弟元素的后面
$('.first').after('<div class='second'></div>');
// 添加在兄弟元素的前面
$('.second').after('<div class='first'></div>');

// 删除匹配到的元素
$('element').remove();
// 删除匹配到的元素的所有子元素(匹配到的元素没有删除)
$('element').empty();
$('element').html('');

jQuery:2.事件操作

事件绑定

1
$('ele').on(events[,select],fn);

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 绑定单个事件
$('div').on('mouseenter',function(){
$(this).css('background-color','skyblue');
})
// 绑定多个事件,1.使用对象的形式
$('div').on({
mouseenter:function () {
$(this).css('background-color','#95e1d3');
},
click:function () {
$(this).css('background-color','#eaffd0');
},
mouseleave:function () {
$(this).css('background-color','#fce38a');
}
})
// 绑定多个事件,2.放在同一个参数中
$('div').on('mouseenter mouseleave',function () {
$(this).toggleClass('current');
})

事件委派

1
2
3
4
5
$('ele').on(events[,select],fn);

$('ul').on('click','li',function(){
// tips:这里事件绑定的是ul元素,但是是用li触发的
})

tips:这里on可以给未来的元素绑定事件

事件解绑

1
2
3
$('ele').off()						//解绑ele所有的事件处理
$('ele').off('click') //解绑ele上的点击事件
$('ele').off('click','sonEle') //解绑事件委托

tips:如果想让绑定的事件只执行一次,可以使用one()**取代on()**

自动触发事件

1
2
3
$('ele').click()   				//模拟点击效果
$('ele').trigger('click') //效果等同
$('ele').triggerHandler('click')//效果等同,但不会触发元素的默认行为

事件对象

阻止冒泡

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="parent">
<div class="son"></div>
</div>
<script>
$('.parent').on('click',function(){
console.log('父盒子');
})
$('.son').on('click',function(event){
console.log('子盒子');
// 阻止事件冒泡
event.stopPropagation();
})
</script>

jQuery:3.对象操作

1
$.extend( [deep ], target, object1 [, objectN ] )

tips:注意深浅拷贝的概念

  1. 浅拷贝:对于简单数据来说,深拷贝和浅拷贝都一样,会创建一个新的值。但是对于复杂数据如对象,会直接引用合并前的对象内容,所以修改新对象中的数据会影响到原对象的数据。
  2. 深拷贝:会对对象中的每个数据都进行复制,遇到复杂数据也会重新创建一个一模一样的对象,而不是引用。

jQuery:4.位置操作

  1. **offset()**:获取设置文档的偏移值

    1
    2
    3
    4
    5
    6
    $(ele).offset();		//获取偏移值
    $(ele).offset().top; //获取顶部偏移值
    $(ele).offset({ //设置偏移值
    top:200,
    left:200
    });

    注意设置的时候要以对象的形式

优先级:局部组件大于全局组件

重点: 所有组件都继承了vue的原型

1.局部组件

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
<div id="app">
<cpm :key="index" v-for="(item,index) in id" :id="index"></cpm>
</div>
<script>
// 局部组件
const cpmc = Vue.extend({
props: ["id"],
data: function () {
return {};
},
template: `
<div>
<h2>这个是组件{{id+1}}</h2>
<p>红红火火恍恍惚惚</p>
</div>
`,
}
);

let vue = new Vue({
el: "#app",
data: {
message: 1,
id: [{ id: 0 }, { id: 1 }, { id: 3 }, { id: 4 }, { id: 5 }],
},
methods: {},
components: {
'cpm': cpmc,
},
});
</script>

2.全局组件

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
<div id="app">
<comp></comp>
</div>
<script src="../../js/vue.js"></script>
<script>

//全局组件
Vue.component('comp',{
data: function(){
return {
items: [1,2,3,4,5],
}
},
template: `
<div>
<h2 :key="index" v-for="(item,index) in items">{{index+1}}</h2>
</div>
`
})
const app = new Vue({
el: '#app',
data: {
message: ''
}
})
</script>

3.组件模板的分离

1.使用script的方式引入,type选择text/x-template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="app">
<cpn></cpn>
</div>
<!-- 下面全局组件会找到id为cpn的script标签,
将里面的内容作为模板渲染到整个dom中 -->
<script type="text/x-template" id="cpn">
<h2>这个是写在script里面的模板</h2>
</script>
<script src="../../js/vue.js"></script>
<script>
Vue.component("cpn", {
template: "#cpn",
});
const app = new Vue({
el: "#app",
data: {
message: "",
},
});
</script>

2.使用template的方式引入,注意id为组件注册的id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div id="app">
<cpn></cpn>
</div>
<!-- 下面全局组件会找到id为cpn的template标签,
将里面的内容作为模板渲染到整个dom中 -->
<template id="cpn">
<h2>这个是写在template标签里面的模板</h2>
</template>
<script src="../../js/vue.js"></script>
<script>
Vue.component("cpn", {
template: "#cpn",
});
const app = new Vue({
el: "#app",
data: {
message: "",
},
});
</script>

4.参数使用问题

在组件中,参数data对应的是一个函数,数据存放在函数return的对象中。

1
2
3
data: function () {
return {//数据,};
},

5.相同组件多次引用,之间数据不互通

6.父子传参

1.数组类型

1
props: ['parm1','parm2']

2.对象类型

1
2
3
4
5
6
7
props: {
'parm1': Array,//这里对象对用的参数用于限制传参进来的参数数据类型
'parm2': {
type: String,
default: 'default_num' //默认值,如果没有传参进来,就使用默认值
}
}

3.驼峰命名注意点

参数如果是用驼峰命名法的话,注意在使用的时候要使用’-‘连接两个单词

1
2
3
<cpm :c-name="parm1" :c-movies="parm2">

props: ['cName','cMovies']

7.子父传参

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
40
41
42
43
44
45
46
47
<!-- 子组件模板内容 -->
<template id="tags">
<div>
<!-- 设置子组件的点击事件 -->
<button :key="item.id" v-for="item in tags_list" @click="btnClick(item)">{{item.name}}</button>
</div>
</template>


<div id="app">
<!-- 引用模板,注册监听事件,与子组件的点击事件中传回的第一个参数同名,接收默认自带子组件传递过来的数据,这里cpnClick括号内不写,下方监听函数也可以直接使用item参数 -->
<tags @item-click="cpmClick"></tags>
</div>
<script src="../../js/vue.js"></script>
<script>
Vue.component("tags", {
template: "#tags",
data: function () {
return {
tags_list: [
{ id: "aaa", name: "热门推荐" },
{ id: "bbb", name: "男生上衣" },
{ id: "ccc", name: "男生裤子" },
{ id: "ddd", name: "女生上衣" },
{ id: "eee", name: "女生裤子" },
],
};
},
methods: {
btnClick: function(item){
// 设置子组件的点击事件,传回的数据名称以及数据
this.$emit('item-click',item);
}
}
});
const app = new Vue({
el: "#app",
data: {
message: "",
},
methods: {
cpmClick: function(item){
console.log('触发了父组件的点击事件,收到了'+item.name+'按钮传来的参数');
}
}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
@click="btnClick(item)"

btnClick: function(item){
// 将参数传递给父组件
this.$emit('item-click',item);
}

@item-click="cpmClick"

cpmClick: function(item){
// 处理逻辑
}

tips:传参只能使用‘-’命名法,否则失效

8.所有的组件都继承vue原型(学习vue-cli之后补充)

在main.js文件添加

1
Vue.prototype.name = 'Jamie'

之后在所有组件中,只要使用

1
console.log('this.name');

即可打印出来

1
Jamie

原理就是先修改了vue的原型之后,所有继承于vue的组件对象中都拥有这个原型属性

1.表单操作

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<div id="app">
<form action="http://itcast.cn">
<div>
<span>姓名:</span>
<span>
<input type="text" v-model='uname'>
</span>
</div>
<div>
<span>性别:</span>
<span>
<input type="radio" id="male" value="1" v-model='gender'>
<label for="male"></label>
<input type="radio" id="female" value="2" v-model='gender'>
<label for="female"></label>
</span>
</div>
<div>
<span>爱好:</span>
<input type="checkbox" id="ball" value="1" v-model='hobby'>
<label for="ball">篮球</label>
<input type="checkbox" id="sing" value="2" v-model='hobby'>
<label for="sing">唱歌</label>
<input type="checkbox" id="code" value="3" v-model='hobby'>
<label for="code">写代码</label>
</div>
<div>
<span>职业:</span>
<select v-model='occupation' >
<option value="0">请选择职业...</option>
<option value="1">教师</option>
<option value="2">软件工程师</option>
<option value="3">律师</option>
</select>
</div>
<div>
<span>个人简介:</span>
<textarea v-model='desc'></textarea>
</div>
<div>
<!--注意要使用js的方式来提交-->
<input type="submit" value="提交" @click.prevent='handle'>
</div>
</form>
</div>
</body>
<script>
let app = new Vue({
el: '#app',
data: {
uname: 'Jamie',
gender: 1,
hobby: ['1','2'],
occupation: 1,
desc: 'Jamie is a softwareEngineer!',
},
method:{
}
})
</script>

这里,**@input的作用是DomLinsteners:value的作用是DataBindings**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<!--这里三行的作用等价-->
<input type="text" v-model="msg"><br>
<input type="text" v-bind:value="msg" v-on:input="handle"><br>
<input type="text" :value="msg" @input="msg=$event.target.value"><br>
<div>{{msg}}</div>
</div>
<script src="../../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
msg: '',
},
methods: {
handle: function (event){
//使用最新的输入域中的内容来更新msg的内容
this.msg = event.target.value;
}
}
})
</script>

事件修饰符可以串联,**@click.stop.prevent=’fun’**

1.阻止事件冒泡(.stop)

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
<!--正常情况下,父盒子的点击事件会被冒泡触发,使用.stop修饰
之后,就可以阻止事件冒泡-->
<div id="app" @click="handleFather">
<button @click.stop="handle">click</button>
</div>
<script src="../../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {

},
methods: {
handleFather: function (){
alert('I am father!')
},
// 当直接调用函数名作为指令的时候,事件对象会
// 作为第一个参数传进来,(有参数则为最后一个)
handle: function (event){
// 这里也有同样的作用
// event.stopPropagation();
alert('I am son!');
}
}
})
</script>

2.阻止默认行为(.prevent)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<!--被prevent修饰之后,a标签的工作不再是跳转了-->
<a href="https://www.baidu.com" @click.prevent="handle">百度</a>
</div>
<script src="../../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
},
methods: {
handle: function (event){
console.log('点击了!');
}
}
})
</script>