Vue2 - 23-03-26

First Post:

Last Update:

Vue2 - 23-03-26

一个错误

1
2
3
4
5
6
7
8
9
10
11
ERROR in ./src/components/MyList.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/MyList.vue?vue&type=script&lang=js&)
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: D:\CODE_VsCode\VUE\vue_study\脚手架之后的内容\vue_test\src\components\MyList.vue: Legacy octal literals are not allowed in strict mode. (7:16)

5 | data(){
6 | todos[
> 7 | {id:001, title:抽烟, done: true},
| ^
8 | {id:002, title:喝酒, done: false},
9 | {id:003, title:开车, done: false}
10 | ]

记得serve之前保存文件!!!

另一个错误

卡在这里不动了。。。

1
2
3
4
5
6
7
 npm run serve

> [email protected] serve
> vue-cli-service serve

INFO Starting development server...
[24%] building (12/33 modules)

检查template里面是不是有错误,编译失败

子组件向父组件传数据

实现方式:父组件先向子组件传函数,子组件在合适的时候将数据通过调用父组件的函数,将数据传给父组件

css中父元素被hover的时候触发子元素的属性

1
2
3
li:hover button {
display: block;
}

获取点击事件的元素

e.target.value/e.target.checked

1
2
3
4
v-on:click(funName)
funName(e) {
log(e.target.value)/log(e.target.checked)
}

自行练习了一遍

App.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
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
<template>
<div class="todo-container">
<div class="todo-wrap">
<MyHeader
:addTodo="addTodo"/>
<MyList
:todos="todoList"
:changeDone="changeDone"
:deleteTodo="deleteTodo"
/>
<MyFooter
:todos="todoList"
:checkAll='checkAll'
:clearDone="clearDone"
/>
</div>
</div>
</template>

<script>
import MyHeader from "./components/MyHeader.vue"
import MyList from "./components/MyList.vue"
import MyFooter from "./components/MyFooter.vue"
export default {
name:'App',
components:{MyHeader, MyList, MyFooter},
data() {
return {
todoList:[
{id:'001', title:'抽烟', done:false},
{id:'002', title:'喝酒', done:true},
{id:'003', title:'吃饭', done:false},
]
}
},
methods:{
addTodo(todo) {
// console.log('收到了todo',todo);
this.todoList.unshift(todo)
},
changeDone(id) {
this.todoList.forEach(todo => {
if(todo.id === id) todo.done = !todo.done
});
},
deleteTodo(id) {
this.todoList = this.todoList.filter((todo)=>{
return todo.id!=id
})
},
checkAll(value) {

this.todoList.forEach((todo)=>{
todo.done = value
})
},
clearDone() {
if(confirm("将要清除所有已完成项") ){
this.todoList=this.todoList.filter(todo=> !todo.done)
}
}
}
}
</script>

<style>
/*base*/
body {
background: #fff;
}

.btn {
display: inline-block;
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
text-align: center;
vertical-align: middle;
cursor: pointer;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
border-radius: 4px;
}

.btn-danger {
color: #fff;
background-color: #da4f49;
border: 1px solid #bd362f;
}

.btn-danger:hover {
color: #fff;
background-color: #bd362f;
}

.btn:focus {
outline: none;
}

.todo-container {
width: 600px;
margin: 0 auto;
}
.todo-container .todo-wrap {
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}

</style>

Header.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
33
34
35
36
37
38
<template>
<div class="todo-header">
<input type="text" placeholder="请输入你的任务名称,按回车键确认" @keyup.enter="addATodo"/>
</div>
</template>

<script>
import {nanoid} from 'nanoid'
export default {
name:'MyHeader',
props:["addTodo"],
methods:{
addATodo(e){
const todo = {id:nanoid(),title:e.target.value,done:false}
this.addTodo(todo)
e.target.value=''
}
}
}
</script>

<style scoped>
/*header*/
.todo-header input {
width: 560px;
height: 28px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
padding: 4px 7px;
}

.todo-header input:focus {
outline: none;
border-color: rgba(82, 168, 236, 0.8);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
}
</style>

MyList.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
33
34
35
36
37
38
39
40
<template>
<ul class="todo-main">
<!-- 每一份都是独一无二的vc -->
<MyItem
v-for="todo in todos"
:key="todo.id"
:todoItem="todo"
:changeDone='changeDone'
:deleteTodo='deleteTodo'
/>
</ul>
</template>

<script>
import MyItem from './MyItem.vue'
export default {
name:'MyList',
components:{MyItem},
props:['todos','changeDone','deleteTodo']
}
</script>

<style scoped>
/*main*/
.todo-main {
margin-left: 0px;
border: 1px solid #ddd;
border-radius: 2px;
padding: 0px;
}

.todo-empty {
height: 40px;
line-height: 40px;
border: 1px solid #ddd;
border-radius: 2px;
padding-left: 5px;
margin-top: 10px;
}
</style>

MyItem.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
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
<template>
<li>
<label>
<input type="checkbox" :checked="todoItem.done" @change="handleDone"/>
<span>{{todoItem.title}}</span>
</label>
<button class="btn btn-danger" @click="handleDelete">删除</button>
</li>
</template>

<script>
export default {
name:'MyItem',
props:['todoItem','changeDone','deleteTodo'],
methods:{
handleDone(){
// console.log('点了');
this.changeDone(this.todoItem.id)
},
handleDelete(){
if(confirm("确认要删除这一项吗??")) this.deleteTodo(this.todoItem.id)
}
}
}
</script>

<style scoped>
/*item*/
li {
list-style: none;
height: 36px;
line-height: 36px;
padding: 0 5px;
border-bottom: 1px solid #ddd;
}

li:hover {
background-color: #ebebeb;
}

li:hover button {
display: block;
}

li label {
float: left;
cursor: pointer;
}

li label li input {
vertical-align: middle;
margin-right: 6px;
position: relative;
top: -1px;
}

li button {
float: right;
display: none;
margin-top: 3px;
}

li:before {
content: initial;
}

li:last-child {
border-bottom: none;
}
</style>

MyFooter.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
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
<template>
<div class="todo-footer" v-show="todoTotal>0">
<label>
<input type="checkbox" v-model="isAll"/>
</label>
<span>
<span>已完成{{todoDone}}</span> / 全部{{todoTotal}}
</span>
<button class="btn btn-danger" @click="clearDone">清除已完成任务</button>
</div>
</template>

<script>
export default {
name:'MyFooter',
props:['todos','checkAll','clearDone'],
computed:{
todoTotal(){
return this.todos.length;
},
todoDone(){
return this.todos.reduce((pre,todo)=>{
return pre += todo.done? 1: 0
},0)
},
isAll:{
get(){
return this.todoDone === this.todoTotal
},
set(checked){
this.checkAll(checked)
}
}
}
}
</script>

<style scoped>
/*footer*/
.todo-footer {
height: 40px;
line-height: 40px;
padding-left: 6px;
margin-top: 5px;
}

.todo-footer label {
display: inline-block;
margin-right: 20px;
cursor: pointer;
}

.todo-footer label input {
position: relative;
top: -1px;
vertical-align: middle;
margin-right: 5px;
}

.todo-footer button {
float: right;
margin-top: 5px;
}
</style>

WebStorage

(window.)localStorage/sessionStorage . setItem([key],[value])
(window.)localStorage/sessionStorage . getItem([key])
单删(window.)localStorage/sessionStorage . removeItem([key])
全删(window.)localStorage/sessionStorage . clear

转字符串JSON.stringify / 恢复对象JSON.parse

TodoList新增本地存储功能

防止初始的时候key不存在

todoList: JSON.parse(localStorage.getItem("todos")) || []

实现

1
2
3
4
5
6
7
8
watch:{
todoList:{
deep:true,
handler(value) {
localStorage.setItem('todos',JSON.stringify(value))
}
}
}