vuejs入门:简单的ToDoList
一、工具具备html、css、js的基础知识chrome浏览器vscode文本编辑器vuejs的官方文档二、我理解的vuejsvue(读/vju:/,与view同音)是一套用于构建用户界面的js框架,它是轻量级的,易上手(作为一个前端小白本人用事实证明确实易上手)官方提供了webpack等脚手架工具,提供了一整套前端集成框架,所有依赖都已经包办,只需要下载好然后根据要求在...
一、工具
- 具备html、css、js的基础知识
- chrome浏览器
- vscode文本编辑器
- vuejs的官方文档
二、我理解的vuejs
vue(读/vju:/,与view同音)是一套用于构建用户界面的js框架,它是轻量级的,易上手(作为一个前端小白本人用事实证明确实易上手)
官方提供了webpack等脚手架工具,提供了一整套前端集成框架,所有依赖都已经包办,只需要下载好然后根据要求在指定目录下开发自己的项目内容即可(但本博文没有使用此方法)
另一种引入vue的方法是,直接在.html静态文件中通过
<script>
标签的方式引入(本文采取的方式),可以根据需要选择版本,这仅适用小小型应用:<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
我理解的vue是一个写好的js类,我们需要先new一个vue的实例并绑定标签,才能使用它
vue能够动态地将html中的元素与vue中定义的data双向绑定起来,动态更新,能够方便地将数据操作与页面渲染展示的工作分割开来,能更专注于展示,屏蔽底部细节。下面的介绍也会体现这一点,这里仅概括一下我的理解
三、编写一个简单的todolist
3.1 引入vuejs
html部分的静态文件非常简单,如下所示:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>TodoList</title> <link href="index.css" rel="stylesheet" type="text/css" /> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> </head> <body> <div id="app"> <todo-body></todo-body> </div> <script src="../src/main.js"></script> </body> </html>
注意到
<body>
部分有一个<todo-body>
的标签,这是一个vue组件(component),正确定义和注册就可以直接在html文件中以标签的形式使用引入vuejs之后,在chrome浏览器中可以观察到文件目录结构如下所示:
3.2 注册一个vue的实例,并绑定id
// main.js
new Vue({
el: '#app',
})
- 这里的
el
是element
的意思 #app
表示id="app"
的元素是一个vue实例- 缺少这一句注册,是无法正确渲染的
- 曾尝试过将
el
设为'body'
,会报错说不要将vue挂载在<html>
或<body>
元素上,让我使用一般的元素:
[Vue warn]: Do not mount Vue to <html> or <body> - mount to normal elements instead.
3.3 注册一个vue组件
(1)什么是vue组件
任何应用界面都可以抽象为一个组件树(图源自vuejs官方文档):
在vue中,组件的本质是一个拥有预定义选项的vue实例,因此组件也拥有vue的四大选项:
data
数据、methods
方法/函数、watch
监听事件、props
组件自定义属性
(2)注册一个名叫todo-body的vue组件
//main.js
Vue.component('todo-body', {
data: function() {
return {
title: 'This is a ToDoList'
}
},
template: '<h2>{{ title }}</h2>',
methods: {},
watch: {}
})
- 意思是注册一个名叫
todo-body
的vue组件,其拥有一个数据变量title
(一个拥有初始值的字符串) - 这样注册以后,在静态html中使用
<todo-body>
标签就会套入组件中定义好的template
部分(如3.1所述),而template
中的双花括号会显示组件中的title
变量的值 - 需要注意的是,注册组件用到的
data
必须是以函数返回值的形式,避免复用组件时因数据共享导致的意想不到的错误
3.4 完善todo-body的vue组件
//main.js
Vue.component('todo-body', {
data: function() {
return {
title: 'This is a ToDoList',
newLabel: '',
items: []
}
},
template: '<div>\
<h2>{{ title }}</h2> \
<input v-model="newLabel" v-on:keyup.enter="addNewLabel"> \
<ul> \
<li v-for="item in items" \
v-bind:class="{finished: item.isFinished}" \
v-on:click="finishState(item)" \
style="cursor:pointer"> \
{{ item.label }} \
</li> \
</ul> \
</div>',
methods: {
addNewLabel: function() {
this.items.push({
label: this.newLabel,
isFinished: false
});
this.newLabel = '';
},
finishState: function(item) {
item.isFinished = !item.isFinished;
}
},
watch: {}
})
(1)首先,一个组件的template
只能包含一个根标签,本例是<div>
(2)template
的根标签中包含三个子标签:<h2>
、<input>
、<ul>
,分别表示标题、输入待办事项的输入框、待办事项列表
(3)data
部分新增两个变量:newLabel
用于接收输入的新的待办事项,初始值为空字符串;items
用于存储当前已经输入的所有待办事项,初始值是一个空数组,数组的每一个元素都是一个json格式的数据,包括label
和isFinished
两个字段
(4)下面重点解释一下template
中的vue指令(可以参考官方文档)
v-model="newLabel"
:表示<input>
输入框中输入的内容在回车后直接赋值给newLabel
v-on:keyup.enter="addNewLabel"
:表示当触发回车键时,将会调用组件的methods
中定义好的addNewLabel
函数v-for="item in items"
:表示循环取出items
数组中的每一个元素item
,以列表的方式渲染item.label
的内容,如果数组为空则不渲染<li>
标签v-bind:class="{finished: item.isFinished}"
:根据双引号中的表达式的布尔值决定是否使用class=finished
属性(配合css使用)v-on:click="finishState(item)
:表示当触发click事件时,将会调用组件的finishState(item)
函数
3.5 使用localStorage存储待办事项
window
对象表示浏览器的一个实例,它既是通过js访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象localStorage
是浏览器提供的一个本地存储,其文件存放在浏览器目录下的某个文件夹中,只要不去手动删除它,每次刷新浏览器页面这个文件都还是存在的,那么我们就可以通过它存储我们刚输入的待办事项localStorage
有两个方法:setItem(文件名, 存储内容)
用于设置保存内容到本地存储,getItem(文件名)
用于提取本地存储的内容//main.js const STORAGE_KEY = 'todo-list'; function initalItems() { return JSON.parse(window.localStorage.getItem(STORAGE_KEY) || '[]') } function saveItems(items) { window.localStorage.setItem(STORAGE_KEY, JSON.stringify(items)) } Vue.component('todo-body', { data: function() { return { title: 'This is a ToDoList', newLabel: '', items: initalItems() } }, template: '...', methods: {...}, watch: { items: { handler: function(items) { saveItems(items); }, deep: true } } })
这里的代码增加了两个函数用于设置和提取本地存储内容,并修改了vue组件中的两个地方:
- 数据变量中的
items
的初始值不再是空数组,而是从本地浏览器中提取到的内容,如果提取不到则设为空 watch
监听items
变量的变化,只要items
发生变化,就会调用handler函数,将变化后的items
存储到localStorage
,并且是深复制(类似于python的深复制机制)localStorage的内容可以在chrome浏览器中查看,如下图所示:
这样一来即使关掉浏览器本地存储的内容也还会存在,再次打开使用浏览器打开该html时,依然能正确加载先前存储好的待办事项。如果想要清空,只需要选中localStorage下对应的html文件目录,右键,
clear
即可
四、未解决问题记录
main.js调用store.js中定义的函数:
//main.js
new_element = document.createElement("script");
new_element.setAttribute("type", "text/javascript");
new_element.setAttribute("src", "../src/store.js"); //引入store.js
document.body.appendChild(new_element);
然后出现了store.js中的函数能在main.js的vue组件中的watch
中调用,但不能在data
中调用的情况,报错为initialItems
未定义。
疑似与vue的生命周期有关,查阅一些资料可以使用created
或mounted
,似乎无法解决上述调用问题,因此直接将store.js的函数写在main.js中了,仍未能解决js相互调用函数的vue渲染问题。
更多推荐
所有评论(0)