Create by jsliang on 2019-1-2 08:46:46
Recently revised in 2019-1-10 08:19:41
Привет друзья, если вы считаете, что эта статья неплохая, не забудьте датьstar, ВашstarЭто моя мотивация научиться подбрасывать!Адрес GitHub
【2019-08-16】Привет друзья, потому чтоjsliangБиблиотека документации подверглась рефакторингу, некоторые ссылки на эту статью могут быть битыми, иjsliangУ меня нет сил поддерживать старые статьи на стороне Nuggets, извините за это. Для тех, кому нужно получать последние статьи, щелкните адрес GitHub выше и перейдите в библиотеку документов, чтобы просмотреть скорректированные статьи.
Друзья, которые следят за Vue, возможно, знают, что несколько дней назад Юшен опубликовал динамику на Weibo:
Затем, более подробное понимание младшего партнера, может знать этот сверхсекретный код для написания, это TodoList!
Просто мы отложили в сторону Vue-Cli, используя самый элементарный способ развития тодолиста, однако этот тодолист тоже-тодолист.
TodoList в этой статье дополняет три функциональных модуля текущего, списка завершения и корзины и реализует следующие функции:
- добавить задачу
- изменить состояние
- Изменить задачи
- удалить задачу
- Дисплей готовой продукции:
-
кодовый адрес:Тысяча костей успеха - кодовый адрес
-
адрес проекта:Тысяча костей успеха - адрес в Интернете
Итак, друзья, которые хотят знать, как реализован этот TodoList, давайте посмотрим!
каталог
Чем отличается передок без закидывания от соленой рыбы?
2 Предисловие
После серии подбрасываний и ссылок на «работы новых людей» разных воротил синтезируются различные методы записи TodoList, от 0 до 1, без использования Vue-Cli для создания собственного TodoList, который будет позже связан с платформой Node Koa.MySQL предоставляет интерфейс для реализации TodoList для масс!
Если вы хотите практиковать этот навык, вы должны сначала пойти во дворец, а(⊙o⊙)... Нет, сначала вы должны научитьсяОсновы Vue серии Vue.
Анализ трех проектов
В нашей обычной работе, когда мы получаем проект дизайна PSD или дизайн прототипа, мы должны разделить наши функции, HTML, CSS, JS, чтобы облегчить последующее обслуживание и производство, давайте сначала посмотрим на это. Взгляните на наш пользовательский интерфейс:
Сумма(⊙o⊙)…
Ну -_-||
Это ужасно, мы до сих пор строим HTML по этой форме, и используем сначала JS для реализации функции, а потом заливаем CSS.
Вот структура каталогов:
Четыре скелета — HTML
Теперь давайте закончимindex.htmlАрхитектура.
потомindex.cssа такжеindex.jsЭти два файла могут быть пустыми, потому что сначала мы настраиваем скелет, а затем выполняем JS-события и рендеринг CSS.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="shortcut icon" href="./img/favicon.ico" type="image/x-icon">
<title>功成千骨</title>
<!-- css 区 -->
<link rel="stylesheet" href="./css/reset.css">
<link rel="stylesheet" href="./css/index.css">
<style>
.content-list {
display: flex;
}
</style>
</head>
<body>
<!-- html 区 -->
<div class="main-container" id="app">
<!-- 头部标题 -->
<div class="header">
<h3>功成千骨</h3>
</div>
<!-- 内容区 -->
<div class="content">
<!-- 输入区 -->
<div class="content-input-todo">
<input type="text" placeholder="第 n 个敌人" "v-model="todo">
<button>进击</button>
</div>
<!-- 列表区 -->
<div class="content-list">
<!-- 未完成 -->
<div class="content-list-todo">
<h4>千军万马取敌首</h4>
<p>(待完成)</p>
<ul>
<li>
<input type="checkbox">
<span class="todo-title">敌军 1</span>
<span class="icon-recycle">×</span>
</li>
<li>
<input type="checkbox">
<span class="todo-title">敌军 2</span>
<span class="icon-recycle">>×</span>
</li>
<li>
<input type="checkbox">
<span class="todo-title">敌军 3</span>
<span class="icon-recycle">×</span>
</li>
</ul>
</div>
<!-- 已完成 -->
<div class="content-list-finish">
<h4>敌羞吾去脱他衣</h4>
<p>(已完成)</p>
<ul>
<li>
<input type="checkbox">
<span class="todo-title">亡军 1</span>
<span class="icon-recycle">×</span>
</li>
<li>
<input type="checkbox">
<span class="todo-title">亡军 2</span>
<span class="icon-recycle">×</span>
</li>
<li>
<input type="checkbox">
<span class="todo-title">亡军 3</span>
<span class="icon-recycle">×</span>
</li>
</ul>
</div>
<!-- 回收站 -->
<div class="content-list-recycle">
<h4>溃不成军鸟兽散</h4>
<p>(回收站)</p>
<ul>
<li>
<span class="content-list-recycle-back">返回</span>
<span class="todo-title">逃军 1</span>
<span class="icon-delete">×</span>
</li>
<li>
<span class="content-list-recycle-back">返回</span>
<span class="todo-title">逃军 2</span>
<span class="icon-delete">×</span>
</li>
<li>
<span class="content-list-recycle-back">返回</span>
<span class="todo-title">逃军 3</span>
<span class="icon-delete">×</span>
</li>
</ul>
</div>
</div>
<!-- -->
</div>
<!-- 底部信息 -->
<div class="footer">
<p>不折腾的前端</p>
<p>和咸鱼有什么区别</p>
<p>@2019 <a href="" target="_blank">jsliang 文档库</a></p>
</div>
</div>
<!-- js 区 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
<script src="./js/index.js"></script>
</body>
</html>
На данный момент содержимое страницы выглядит следующим образом:
Пять функций - JS
После создания скелета веб-страницы давайте сначала запустим его.
Вы можете представить себе создание человека-скелета с помощью приведенных выше шагов HTML, и теперь вам нужно произнести заклинание, чтобы заставить человека-скелета бежать.
Беги, скелетон~
5.1 Данные страницы
Теперь, когда мы обрабатываем страницу, нам нужно рассмотреть, какие части нужно превратить в данные:Вход,список дел,завершение,незаконченный объект.
Итак, давайте сначала сделаем простое извлечение:
фрагмент кода index.html
<!-- 内容区 -->
<div class="content">
<!-- 输入区 -->
<div class="content-input-todo">
<input type="text" placeholder="第 n 个敌人" v-model="todo">
<button>进击</button>
</div>
<!-- 列表区 -->
<div class="content-list">
<!-- 未完成 -->
<div class="content-list-todo">
<h4>千军万马取敌首</h4>
<p>(待完成)</p>
<ul>
<li v-for="todoItem in todoInfos" :key="todoItem.id">
<input type="checkbox" v-model="todoItem.isChecked">
<span class="todo-title" v-text="todoItem.todoTitle"></span>
<span class="icon-recycle">x</span>
</li>
</ul>
</div>
<!-- 已完成 -->
<div class="content-list-finish">
<h4>敌羞吾去脱他衣</h4>
<p>(已完成)</p>
<ul>
<li v-for="finishItem in finishInfos" :key="finishItem.id">
<input type="checkbox" v-model="finishItem.isChecked">
<span class="todo-title" v-text="finishItem.todoTitle"></span>
<span class="icon-recycle">x</span>
</li>
</ul>
</div>
<!-- 回收站 -->
<div class="content-list-recycle">
<h4>溃不成军鸟兽散</h4>
<p>(回收站)</p>
<ul>
<li v-for="recycleItem in recycleInfos" :key="recycleItem.id">
<span class="content-list-recycle-back">返回</span>
<span class="todo-title" v-text="recycleItem.todoTitle"></span>
<span class="icon-delete">x</span>
</li>
</ul>
</div>
</div>
</div>
Вот, мы оцифровали страницу, теперь смотрим на нашуindex.jsсодержание:
index.js
var app = new Vue({
el: "#app",
data: {
id: 1,
todo: "",
todoInfos: [
{
id: 7,
isChecked: false,
todoTitle: "敌军 1",
},
{
id: 8,
isChecked: false,
todoTitle: "敌军 2",
},
{
id: 9,
isChecked: false,
todoTitle: "敌军 3",
},
],
finishInfos: [
{
id: 1,
isChecked: true,
todoTitle: "亡军 1",
},
{
id: 2,
isChecked: true,
todoTitle: "亡军 2",
},
{
id: 3,
isChecked: true,
todoTitle: "亡军 3",
},
],
recycleInfos: [
{
id: 4,
isChecked: false,
todoTitle: "逃军 1",
},
{
id: 5,
isChecked: false,
todoTitle: "逃军 2",
},
{
id: 6,
isChecked: false,
todoTitle: "逃军 3",
},
]
}
})
Таким образом, мы проходимv-forРендеринг данных завершен, и страница такая же, как и раньше:
5.2 Сокращение данных
Здесь мы останавливаемся на мгновение и наблюдаемtodoInfos,finishInfos,recycleInfosТри массива и обнаружили, что они похожими структуры. Итак, мы просто сливаемся?
index.js
var app = new Vue({
el: "#app",
data: {
id: 1,
todo: "",
todoInfos: [
{
id: 7, // id 唯一且自增
isChecked: false, // 未完成和放弃为 false,完成为 true
isEdit: false, // 是否在编辑
todoTitle: "敌军 1",
state: 0, // 0 - 未完成,1 - 完成,2 - 放弃完成
},
{
id: 8, // id 唯一且自增
isChecked: false, // 未完成和放弃为 false,完成为 true
isEdit: false, // 是否在编辑
todoTitle: "敌军 2", // todo 标题
state: 1, // 0 - 未完成,1 - 完成,2 - 放弃完成
},
{
id: 9, // id 唯一且自增
isChecked: false, // 未完成和放弃为 false,完成为 true
isEdit: false, // 是否在编辑
todoTitle: "敌军 3", // todo 标题
state: 2, // 0 - 未完成,1 - 完成,2 - 放弃完成
},
]
}
})
Таким образом, мы можем изменить HTML так, чтобы он проходилstateЧтобы различать эти три части данных:
фрагмент кода index.html
<!-- 内容区 -->
<div class="content">
<!-- 输入区 -->
<div class="content-input-todo">
<input type="text" placeholder="第 n 个敌人" v-model="todo">
<button>进击</button>
</div>
<!-- 列表区 -->
<div class="content-list">
<!-- 未完成 -->
<div class="content-list-todo">
<h4>千军万马取敌首</h4>
<p>(待完成)</p>
<ul>
<li v-for="todoItem in todoInfos" :key="todoItem.id" v-if="todoItem.state == 0">
<input type="checkbox" v-model="todoItem.isChecked">
<span class="todo-title" v-if="!todoItem.isEdit" v-text="todoItem.todoTitle"></span>
<span class="icon-recycle">x</span>
</li>
</ul>
</div>
<!-- 已完成 -->
<div class="content-list-finish">
<h4>敌羞吾去脱他衣</h4>
<p>(已完成)</p>
<ul>
<li v-for="finishItem in todoInfos" :key="finishItem.id" v-if="finishItem.state == 1">
<input type="checkbox" v-model="finishItem.isChecked">
<span class="todo-title" v-if="!finishItem.isEdit" v-text="finishItem.todoTitle"></span>
<span class="icon-recycle">x</span>
</li>
</ul>
</div>
<!-- 回收站 -->
<div class="content-list-recycle">
<h4>溃不成军鸟兽散</h4>
<p>(回收站)</p>
<ul>
<li v-for="recycleItem in todoInfos" :key="recycleItem.id" v-if="recycleItem.state == 2">
<span class="content-list-recycle-back">返回</span>
<span class="todo-title" v-if="!recycleItem.isEdit" v-text="recycleItem.todoTitle"></span>
<span class="icon-delete">x</span>
</li>
</ul>
</div>
</div>
</div>
На данный момент наша страница все еще такая же, как и до модификации, но данные были реализованы.
Далее приступаем к написанию функционального метода добавления, удаления и изменения данных.
5.3 Добавление данных
первый, добавляем в HTML событие клика, конечно, если приходится каждый раз нажимать на кнопку, это будет слишком хлопотно, давайте просто добавим событие ввода с клавиатуры:
фрагмент кода index.html
<!-- 输入区 -->
<div class="content-input-todo">
<input type="text" placeholder="第 n 个敌人" v-model="todo" @keyup.enter="addTodoItem">
<button @click="addTodoItem">进击</button>
</div>
потом, добавляем в JS метод click:
index.js
var app = new Vue({
el: "#app",
data: {
id: 1,
todo: "",
todoInfos: [
// 已不需要,注释掉
// {
// id: 7, // id 唯一且自增
// isChecked: false, // 未完成和放弃为 false,完成为 true
// isEdit: false, // 是否在编辑
// todoTitle: "敌军 1",
// state: 0, // 0 - 未完成,1 - 完成,2 - 放弃完成
// },
]
},
methods: {
addTodoItem() {
// 每次点击,往数组中添加一组数据
this.todoInfos.push({
id: this.id, // id 唯一且自增
isChecked: false, // 未完成和放弃为 false,完成为 true
isEdit: false, // 是否在编辑
todoTitle: this.todo, // todo 标题
state: 0, // 0 - 未完成,1 - 完成,2 - 放弃完成
})
// id 自增
this.id++;
// 清空输入框
this.todo = "";
},
}
})
наконец, давайте проверим, реализованы ли новые функции:
5.4 Изменить состояние
Ниже мы продолжаемisCheckedа такжеstateизменяется, так что данные изменяются в этих трех состояниях:
| столбец | условие |
|---|---|
| отменен |
isChecked: false,state: 0
|
| завершенный |
isChecked: true,state: 1
|
| корзина | state: 2 |
В этой главе мы реализуемотменен -> завершенный, здесь вам нужно только изменить HTML-код:
фрагмент кода index.html
<!-- 未完成 -->
<div class="content-list-todo">
<h4>千军万马取敌首</h4>
<p>(待完成)</p>
<ul>
<li v-for="todoItem in todoInfos" :key="todoItem.id" v-if="todoItem.state == 0">
<input type="checkbox" v-model="todoItem.isChecked" @change="todoItem.state = 1">
<span class="todo-title" v-if="!todoItem.isEdit" v-text="todoItem.todoTitle"></span>
<span class="icon-recycle">x</span>
</li>
</ul>
</div>
<!-- 已完成 -->
<div class="content-list-finish">
<h4>敌羞吾去脱他衣</h4>
<p>(已完成)</p>
<ul>
<li v-for="finishItem in todoInfos" :key="finishItem.id" v-if="finishItem.state == 1">
<input type="checkbox" v-model="finishItem.isChecked" @change="finishItem.state = 0">
<span class="todo-title" v-if="!finishItem.isEdit" v-text="finishItem.todoTitle"></span>
<span class="icon-recycle">x</span>
</li>
</ul>
</div>
Мы можем проверить результаты ниже:
ОК, успешно завершенобыть законченным -> завершенныйтрансформация.
5.5 Модификации
Теперь реализуем щелчокtodoTitle, в режим модификации щелкните в другом месте после модификации или нажмите кнопку Enter, чтобы изменить данные:
фрагмент кода index.html
<!-- 列表区 -->
<div class="content-list">
<!-- 未完成 -->
<div class="content-list-todo">
<h4>千军万马取敌首</h4>
<p>(待完成)</p>
<ul>
<li v-for="todoItem in todoInfos" :key="todoItem.id" v-if="todoItem.state == 0">
<input type="checkbox" v-model="todoItem.isChecked" @change="todoItem.state = 1">
<span class="todo-title" v-text="todoItem.todoTitle" v-if="!todoItem.isEdit" @click="todoItem.isEdit = true"></span>
<input v-if="todoItem.isEdit" @blur="todoItem.isEdit = false" @keyup.enter="todoItem.isEdit = false" type="text" v-model="todoItem.todoTitle">
<span class="icon-recycle">x</span>
</li>
</ul>
</div>
<!-- 已完成 -->
<div class="content-list-finish">
<h4>敌羞吾去脱他衣</h4>
<p>(已完成)</p>
<ul>
<li v-for="finishItem in todoInfos" :key="finishItem.id" v-if="finishItem.state == 1">
<input type="checkbox" v-model="finishItem.isChecked" @change="finishItem.state = 0">
<span class="todo-title" v-text="finishItem.todoTitle" v-if="!finishItem.isEdit" @click="finishItem.isEdit = true"></span>
<input v-if="finishItem.isEdit" @blur="finishItem.isEdit = false" @keyup.enter="finishItem.isEdit = false" v-model="finishItem.todoTitle" type="text">
<span class="icon-recycle">x</span>
</li>
</ul>
</div>
<!-- 回收站 -->
<div class="content-list-recycle">
<h4>溃不成军鸟兽散</h4>
<p>(回收站)</p>
<ul>
<li v-for="recycleItem in todoInfos" :key="recycleItem.id" v-if="recycleItem.state == 2">
<span class="content-list-recycle-back">返回</span>
<span class="todo-title" v-text="recycleItem.todoTitle" v-if="!recycleItem.isEdit" @click="recycleItem.isEdit = true"></span>
<input v-if="recycleItem.isEdit" type="text" @blur="recycleItem.isEdit = false" @keyup.enter="recycleItem.isEdit = false" v-model="recycleItem.todoTitle">
<span class="icon-delete">x</span>
</li>
</ul>
</div>
</div>
Здесь нам нужно только нажатьspanПри маркировке изменитеisEditсостоянии, то есть войти в режим редактирования, и одновременно вinputМетка теряет фокус или нажимает кнопку «Ввод» после завершения ввода, и данные можно изменить.
Наконец, давайте посмотрим на реализацию:
5.6 Восстановление данных
Точно так же, если мы хотим выбросить данные в корзину, нам нужноstateИзмените его на 2.
Если данные должны быть возвращены из корзины для завершения, нам нужно только поставитьstateИзмените его на 0.
фрагмент кода index.html
<!-- 未完成 -->
<div class="content-list-todo">
<h4>千军万马取敌首</h4>
<p>(待完成)</p>
<ul>
<li v-for="todoItem in todoInfos" :key="todoItem.id" v-if="todoItem.state == 0">
<input type="checkbox" v-model="todoItem.isChecked" @change="todoItem.state = 1">
<span class="todo-title" v-text="todoItem.todoTitle" v-if="!todoItem.isEdit" @click="todoItem.isEdit = true"></span>
<input v-if="todoItem.isEdit" @blur="todoItem.isEdit = false" @keyup.enter="todoItem.isEdit = false" type="text" v-model="todoItem.todoTitle">
<span class="icon-recycle" @click="todoItem.state = 2">x</span>
</li>
</ul>
</div>
<!-- 已完成 -->
<div class="content-list-finish">
<h4>敌羞吾去脱他衣</h4>
<p>(已完成)</p>
<ul>
<li v-for="finishItem in todoInfos" :key="finishItem.id" v-if="finishItem.state == 1">
<input type="checkbox" v-model="finishItem.isChecked" @change="finishItem.state = 0">
<span class="todo-title" v-text="finishItem.todoTitle" v-if="!finishItem.isEdit" @click="finishItem.isEdit = true"></span>
<input v-if="finishItem.isEdit" @blur="finishItem.isEdit = false" @keyup.enter="finishItem.isEdit = false" v-model="finishItem.todoTitle" type="text">
<span class="icon-recycle" @click="finishItem.state = 2">x</span>
</li>
</ul>
</div>
Достижение результата:
5.7 Полное удаление
первый, мы добавляем событие клика в HTML и передаем параметры в тело метода
фрагмент кода index.html
<!-- 回收站 -->
<div class="content-list-recycle">
<h4>溃不成军鸟兽散</h4>
<p>(回收站)</p>
<ul>
<li v-for="recycleItem in todoInfos" :key="recycleItem.id" v-if="recycleItem.state == 2">
<span class="content-list-recycle-back" @click="recycleItem.state = 0; recycleItem.isChecked = false">返回</span>
<span class="todo-title" v-text="recycleItem.todoTitle" v-if="!recycleItem.isEdit" @click="recycleItem.isEdit = true"></span>
<input v-if="recycleItem.isEdit" type="text" @blur="recycleItem.isEdit = false" @keyup.enter="recycleItem.isEdit = false" v-model="recycleItem.todoTitle">
<span class="icon-delete" @click="deleteInfo(recycleItem)">x</span>
</li>
</ul>
</div>
потом, мы пишемdeleteInfoудалитьtodoInfosданные в:
Фрагмент кода index.js
methods: {
addTodoItem() {
// 每次点击,往数组中添加一组数据
this.todoInfos.push({
id: this.id, // id 唯一且自增
isChecked: false, // 未完成和放弃为 false,完成为 true
isEdit: false, // 是否在编辑
todoTitle: this.todo, // todo 标题
state: 0, // 0 - 未完成,1 - 完成,2 - 放弃完成
})
// id 自增
this.id++;
// 清空输入框
this.todo = "";
},
/**
* 这里使用了三种写法
* 1. map + splice
* 2. splice + findIndex
* 3. filter
*/
// // 1. map + splice 写法
// deleteInfo(recycleItem) {
// this.todoInfos.map((item, index) => {
// if(item.id == recycleItem.id) {
// this.todoInfos.splice(index, 1);
// }
// })
// },
// // 2. splice + findIndex 写法
// deleteInfo(recycleItem) {
// this.todoInfos.splice( this.todoInfos.findIndex( v => v.id === recycleItem.id), 1);
// },
// 3. filter 写法
deleteInfo(recycleItem) {
this.todoInfos = this.todoInfos.filter( (x) => {
return x.id != recycleItem.id;
})
}
}
заинтриговали, помнитеЧетыре варианта написания слова фенхель, Итак, вот три способа удаления данных. Мы не будем здесь оценивать потери производительности. Используйте любой из них.
На данный момент завершенная функция выглядит так:
На данный момент мы завершили реализацию всех функций~
Шесть скинов - CSS
Итак, мы возвращаемся к нашей большой проблеме, которая состоит в том, чтобы добавить скин на эту страницу и сделать эту страницу красивой.
6.1 Сброс стилей
enm... Поскольку разные браузеры отображают некоторые элементы DOM по-разному, давайте сначала сбросим стиль браузера:
reset.css
/*
* reset 的目的不是让默认样式在所有浏览器下一致,而是减少默认样式有可能带来的问题。
* The purpose of reset is not to allow default styles to be consistent across all browsers, but to reduce the potential problems of default styles.
* create by jsliang
*/
/** 清除内外边距 - clearance of inner and outer margins **/
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* 结构元素 - structural elements */
dl, dt, dd, ul, ol, li, /* 列表元素 - list elements */
pre, /* 文本格式元素 - text formatting elements */
form, fieldset, legend, button, input, textarea, /* 表单元素 - from elements */
th, td /* 表格元素 - table elements */ {
margin: 0;
padding: 0;
}
/** 设置默认字体 - setting the default font **/
body, button, input, select, textarea {
font: 18px/1.5 '黑体', Helvetica, sans-serif;
}
h1, h2, h3, h4, h5, h6, button, input, select, textarea { font-size: 100%; }
/** 重置列表元素 - reset the list element **/
ul, ol { list-style: none; }
/** 重置文本格式元素 - reset the text format element **/
a, a:hover { text-decoration: none; }
/** 重置表单元素 - reset the form element **/
button { cursor: pointer; }
input { font-size: 18px; outline: none; }
/** 重置表格元素 - reset the table element **/
table { border-collapse: collapse; border-spacing: 0; }
/** 图片自适应 - image responsize **/
img { border: 0; display: inline-block; width: 100%; max-width: 100%; height: auto; vertical-align: middle; }
/*
* 默认box-sizing是content-box,该属性导致padding会撑大div,使用border-box可以解决该问题
* set border-box for box-sizing when you use div, it solve the problem when you add padding and don't want to make the div width bigger
*/
div, input { box-sizing: border-box; }
/** 清除浮动 - clear float **/
.jsliang-clear:after, .clear:after {
content: '\20';
display: block;
height: 0;
clear: both;
}
.jsliang-clear, .clear {
*zoom: 1;
}
/** 设置input的placeholder - set input placeholder **/
input::-webkit-input-placeholder { color: #919191; font-size: 16px } /* Webkit browsers */
input::-moz-placeholder { color: #919191; font-size: 16px } /* Mozilla Firefox */
input::-ms-input-placeholder { color: #919191; font-size: 16px } /* Internet Explorer */
6.2 Замена неба на солнце
Тогда мы сталкиваемся с проблемой, как его украсить?
Мозг болит, пойдем в инет и своруем скин:
Отлично, тогда давайте изменим CSS:
index.css
/* 共用 */
html, body {
height: 100%;
}
body {
background: url("../img/background.jpg") no-repeat center;
background-size: 100% 100%;
}
/* 多项选项框 */
input[type="checkbox"] {
width: 25px;
height: 25px;
background-color: #fff;
-webkit-appearance: none;
border: 1px solid deepskyblue;
border-radius: 2px;
outline: none;
}
input[type="checkbox"]:hover {
cursor: pointer;
}
input[type="checkbox"]:checked {
background: url("../img/icon-checked.png") no-repeat center;
background-size: 100%;
}
/* 共用标题样式 */
.todo-title {
margin-top: 10px;
word-break: normal;
width: 75%;
display: block;
white-space: pre-wrap;
word-wrap: break-word ;
overflow: hidden ;
}
/* 图标样式 */
.icon-recycle {
width: 25px;
height: 25px;
background: url("../img/icon-recycle.png") no-repeat center;
background-size: 100%;
}
.icon-delete {
width: 25px;
height: 25px;
background: url("../img/icon-delete.png") no-repeat center;
background-size: 100%;
}
.content-list-recycle-back {
display: block;
width: 20px;
height: 20px;
background: url("../img/icon-back.png") no-repeat center;
background-size: 100%;
}
/* 页面主体 */
.main-container {
width: 1200px;
height: 100%;
margin: 0 auto;
position: relative;
}
/* 头部标题 */
.header {
width: 100%;
height: 150px;
background: url("../img/title.png") no-repeat center;
}
/* 内容区 */
.content {
text-align: center;
}
/* 内容区 - 输入区 */
.content-input-todo {
height: 40px;
}
.content-input-todo input {
height: 40px;
padding-left: 20px;
padding-right: 20px;
border: none;
border-radius: 20px;
}
.content-input-todo button {
width: 100px;
padding: 5px;
border-radius: 20px;
background: #36AF9E;
color: #fff;
outline: none;
}
/* 内容区 - 列表区 */
.content-list {
display: flex;
margin-top: 30px;
}
.content-list div {
width: 380px;
margin-right: 20px;
border: 1px solid #ccc;
padding: 30px;
border: 15px solid transparent;
border-image: url("../img/border.png") 60 60 stretch;
}
.content-list div ul {
text-align: left;
}
.content-list div ul li {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #ccc;
}
.content-list div ul li:hover {
cursor: pointer;
}
.content-list div ul li input[type="checkbox"] {
margin-right: 10px;
}
.content-list div ul li input[type="text"] {
outline: none;
border: none;
background: rgba(255, 255, 255, 0);
color: #000;
border-bottom: 1px solid #ccc;
}
/* 底部区 */
.footer {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
}
.footer a {
color: deepskyblue;
}
.footer a:hover {
color: deepskyblue;
}
Готово, взгляните на наш готовый продукт:
Семь Резюме
До сих пор мы писали это простоемаленькийДемо
Кодовый адрес и адрес проекта размещены ниже, вам необходимоСсылаться надрузей для скачивания или просмотра в одиночестве.
-
кодовый адрес:Тысяча костей успеха - кодовый адрес
-
адрес проекта:Тысяча костей успеха - адрес в Интернете
Конечно, это еще не конец!
Мы также можем подбросить больше:
- использовать
ElementUIилиBootstrapМультитерминальная адаптация - использовать
localStorageдля местного развития - использовать
Nodeдля многоцелевого использования данных - использоватьВизуальная конфигурация, который извлекает CSS элементов DOM в данные, позволяя пользователям настраивать свой собственный Todolist.
- использовать
HTML5изmanifestразвиватьАвтономное хранилище - ...
Затем, если есть шанс бросить позже, давайте снова встретимся с тодолистом и создайте обновленную версию ~
постскриптум
Если вашему партнеру нужно хранитьjsliang.topЧисто статическая страница, подобная этой илиcompany.jsliang.topДля таких страниц с поддержкой бэкенда Node рекомендуется приобретать облачные серверы для хранения.
Если вы не знаете, как выбрать облачный сервер, вы можете проверитьПодробное введениеили добавитьjsliangQQ:1741020489проконсультируйтесь.
jsliangБиблиотека документацииЛян ЦзюньронгиспользоватьCreative Commons Attribution-NonCommercial-ShareAlike 4.0 Международная лицензияЛицензия.
на основеGitHub.OM/l ЯнДжун Рон…Создание работ выше.
Права на использование, отличные от разрешенных в настоящем Лицензионном соглашении, могут быть получены отCreative Commons.org/licenses/не…получено в.