Vue 四天课程学习笔记_第3天
课程内容概要:
1. 介绍browser-sync安装和配置使用 (强烈推荐!从此告别手动刷新F5)
2. 灵活运用 数组中的 every 和 some 和 filter 方法 (来实现数据的过滤)
3. Sublime的代码片段.sublime-snippet (类似于XCode里的Code Snippet)
4. 不可见元素template的使用
5. v-for 与 v-show 与 v-if 与 v-else-if 与 v-else 指令
6. v-on 与 v-bind 与 v-model 与 v-cloak 与 v-once 与 v-pre 指令
7. 使用v-text 或 v-cloak命令,解决 Mustache的闪烁问题(高频刷新时)
8. 按键捕获 (包括各种修饰符) 与 指令总结
9. 计算属性(getter/setter) 和 v-model指令 联合使用
10. 观察者 watch指令 与 数据持久化到localStorage
11. 通过计算属性,对列表进行按路由条件 (全部/已完成/未完成) 进行过滤
12. 使用 自定义指令(及5个钩子函数) 操作DOM(获取焦点,自动聚焦)
13. 使用 自定义指令(及5个钩子函数) 模拟实现v-show、v-bind指令 的效果
14. 通过上述知识点,实现一个完整的todoMVC项目
插一句:
从win10开始 出现了异常强大的 窗口分栏功能
其快捷键是 win + 上/下/左/右 (真的吗???)
再插一句:
Vue.config是一个对象,包含Vue的全局配置
可以在启动应用之前 设置以下属性:
例如:
// 取消所有日志与警告的输出
Vue.config.silent = true;
再插一句:
提到了项目管理软件 worktile trello Teambition
下面开始 安装 浏览器自动同步刷新神器 browser-sync
第1步,下载browser-sync,官网:browsersync.io
npm install browser-sync --save-dev
或者使用简写(注意大写D)
npm i browser-sync -D
注意: --save-dev 参数表示 这个browser-sync的依赖 并不是必须的! (可有可无)
有了这个-dev的参数, 最后这个browser-sync依赖 会被写到package.json文件的 devDependencies节点
(插入一句说明: npm install 命令 会同时安装 dependencies节点和devDependencies节点)
(插入一句说明: 如果不想安装package.json文件中的devDependencies节点,而只想安装dependencies节点的话,可以使用命令npm install --production)
第2步,打开package.json进行配置
// 注意,package.json中不能写注释
"scripts": {
// dev代表的就是后面的长长的命令, 后面代表的是要监视的文件路径和类型,public目录下的所有html是我手动加的
"dev": "browser-sync start --server --files \"*.html, css/*.css, public/*.html, js/*.js\"",
// 使用npm start命令时,就会执行后面的 npm run dev命令
// 一般都要写npm run start,但只有这个start比较特殊,可以省掉中间的run,从而简写写npm start
"start": "npm run dev"
},
如图所示:
配置scripts节点就是为了方便他人运行该项目(而无需输入具体的.js名字)
第3步: 启动
npm start
经过上面的配置后, 其实就等价于 npm run dev
效果如下: 以后每次改动html文件或css文件,只要一保存,页面就会同步更新了,赞喔~
注意: browser-sync 有自动同步表单的功能 (幽灵输入) ???Excuse Me???
在这儿扩展一下这个scripts节点的相关知识点
举个例子, 以前我们都是在命令行中直接使用 node node_62_index.js 运行这个js文件
这儿是写死了 node_62_index.js这个名字
如果我们配置了scripts,例如
"scripts" : {
"beyond" : "node node_62_index.js",
"start" : "npm run beyond"
}
那么我们就可以有3种方式运行node_62_index.js了
(即便别人不知道node_62_index.js这个具体的名字,也能够运行这个文件了)
第1种: 最原始的 node node_62_index.js
第2种: npm run beyond
第3种: npm start
或者: npm run start
而且 这个 start 比较特殊, 它是可以省略中间的 run的
如图所示:
可能会问 凭啥 start 就比较特殊呀, 就可以省略中间的 run呀
下面的图片给出了答案
下面是关于数组every方法 和 some方法的介绍
如图所示:
下面是数组的filter方法介绍 (特别是在用于数据过滤时,非常好用,比如清除所有已完成的item)
关于Sublime, 这儿插一句:
sublime 的快捷键 Ctrl + T 直接搜索文件 (@btnClick,如果前面加@ 还可以直接搜索方法Function)
如图所示:
下面介绍 Sublime里的.sublime-snippet
先看一张效果图:
创建.sublime-snippet片段的步骤如下:
第1步: 点击 菜单「Tools」-->「New Snippet...」
第2步, 弹出一个新的文本,如图所示:
简单说明一下:
1. tabTrigger标签里的内容 就是我们平常内容时的 触发器 (可以理解为代码片段的 快捷方式! 例如上面gif动图里面的 未闻花名)
2. ${1:beyond} ${2:面码} 代表这些两个是默认的内容,是可以被替换的,并且是能够 使用tab键 上蹿下跳的
3. 注意: 如果模板代码里面有 $ 符号, 则需要 使用 \ 进行转义 如: \$mount('#id_div_container')
再比如这个:
第3步, 编辑好内容 和 trigger触发器之后, 按 Alt + S 弹出保存对话框
注意: 1. 必须以.sublime-snippet结尾
2. 必须保存在这个Packages目录下的User路径:
/Users/beyond/Library/Application Support/Sublime Text 3/Packages/User
3. 可以通过Preference菜单-->Browser Packages菜单,快速进入到Packages目录(下的User目录)
最终效果如下:
v-if 是真正的 条件渲染
因为它会确保在切换过程中,条件块内的事件监听器 和 子组件 相应地被创建和销毁
v-if 是惰性的:
如果在初始渲染时,条件为false,则什么也不做
一直到 条件第一次为true时, 才会开始渲染 条件块
对比一下:
v-show 元素总会被渲染, 并且只是简单地进行CSS样式(display: none/block;)的切换
总结就是:
v-if 每次根据条件 创建和销毁,会有更大的开销
v-show 则每次只是初始渲染的高开销
如果,需要频繁地 切换, 推荐使用v-show
如果,运行时,条件极少变化, 推荐使用v-if
注意: 当 v-if 与 v-for 一起使用时
v-for 有更高的优先级 (见列表渲染指南)
v-for 预期: Array | Object | number | string
数组用法 :
v-for="girl in girlArr"
v-for="(girl,index) in girlArr"
对象用法 :
v-for="(value,key) in girl"
v-for=(value,key,index) in girl""
注意: v-for 默认行为 不改变整体
如果要 重新排序 , 则要提供一个key的特殊属性???Excuse Me??? 为啥没效果
<div v-for="girl in girlArr" :key="girl.girlAge" >
{
{ girl.girlAge }}
</div>
如图所示: (为啥会没有效果???)
列表渲染之条件渲染
v-for可以把一个(过滤后的)数组 对应生成 一组元素
有时候,我们想要显示一个数组的排序副本或者过滤之后的数组,
而不实际改变或重置原始的数组
在这种情况下, 我们就可以创建一个 能够返回 过滤或排序后的数组 的计算属性
例如: 过滤出 loli
<li v-for="loli in loliArr">
{
{ loli }}
</li>
computed: {
loliArr: {
get: function(){
return this.girlArr.filter(loli =>
loli.girlAge > 8 && loli.girlAge < 14
)
}
}
}
另一种情况:
在计算属性 不适用的情况下(例如 嵌套v-for时),
你可以使用一个method方法
<li v-for="loli in findLoliArrFunction(girlArr)"> {
{ loli.girlName }}
</li>
v-show: 显示不显示 (无论如何都会进行渲染)
v-if指令可以决定哪个DOM元素,是否需要进行渲染
假如有许多个DOM元素都需同时进行判断是否需要进行渲染,而且判断的条件还是同一个的话
那么, 如果每一个都写v-if的话,这样就很容易造成代码的重复和冗余
那么, 如果在外面套一层多余的div的话,又会增加不必要的层级
此时,我们可以把这些DOM元素,全部放进一个虚拟的template标签里,
该template标签 会根据v-if的值,决定其内部的所有子元素是否进行渲染,
如果需要渲染,则最终template标签 在完成任务后,会奇迹般地消失
例如:
<template v-if="isNeed">
<h1>动漫: 未闻花名</h1>
<p>女主: 面码</p>
<p>年代: 2011年</p>
</template>
data: {
isNeeded: true/false;
}
vue_18.html代码如下:
<!-- 第3步, vue最终渲染结果的容器 -->
<div id="id_div_container" style="color:#666;padding:10px 10px;border:1px solid Cadetblue;margin:4px;border-radius:8px;">
<template v-if="isNeed">
<h1>动漫: 未闻花名</h1>
<p>女主: 面码</p>
<p>年代: 2011年</p>
</template>
</div>
<!-- 第1步,导入vue.js -->
<script type="text/javascript" src="/node_modules/vue//dist/vue.js"></script>
<!-- 第2步,生成一个全新的vue对象实例 -->
<script type="text/javascript">
var appVue = new Vue({
data: {
isNeed: true
},
methods: {
}
}).$mount('#id_div_container')
</script>
效果如下:
右键,审查元素,我们可以发现, 虚拟元素<template>奇迹般地完成其历史使命后消失了,仿佛从来没有出现过一样(好神奇)
再啰嗦一下:
在虚拟元素<template>上使用v-if进行条件渲染
因为我们知道,v-if指令必须加到一个HTML元素上,才能生效
但是,如果要同时根据同一条件去判断是否渲染多个HTML元素呢?
此时最好的办法就是: 把一个虚拟元素<template>作为他们的容器(根节点)
这时候,只要在虚拟元素<template>上使用v-if指令即可
最终,渲染出来的页面上,不会存在虚拟元素<template>,但其子元素都可以正常展示
下面简单演示一下v-if与v-else-if与v-else指令的使用
vue_19.html代码如下:
<!-- 第3步, vue最终渲染结果的容器 -->
<div id="id_div_container" style="color:#666;padding:10px 10px;border:1px solid Cadetblue;margin:4px;border-radius:8px;">
<div v-if="girlAge < 8">{
{ girlAge }} is baby</div>
<div v-else-if="girlAge < 14">{
{ girlAge }} is loli</div>
<div v-else-if="girlAge >= 14">{
{ girlAge }} is girl</div>
</div>
<!-- 第1步,导入vue.js -->
<script type="text/javascript" src="/node_modules/vue//dist/vue.js"></script>
<!-- 第2步,生成一个全新的vue对象实例 -->
<script type="text/javascript">
var appVue = new Vue({
data: {
girlAge: 13
},
methods: {
}
}).$mount('#id_div_container')
</script>
<p class="sgcenter sgcontentcolor">
<b>注意: v-if、v-else-if、v-elseの演示
</p>
效果如下:
v-on 缩写 @
预期: Function | Inline Statement | Object
参数: event
修饰符:
.stop 调用event.stopPropagation()
.prevent 调用event.preventDefault()
.capture 添加事件侦听器时使用 capture模式
.self 只有事件是从侦听器绑定的元素上 触发时,才回调
.native 监听组件根元素的原生事件
.once 只触发一次回调
.passive 以passive模式 添加侦听器
.{keyCode | keyAlias} 只有事件是从特定的按键触发时,才回调
.left 只有点击鼠标左键时,才回调
.right 只有点击鼠标右键时,才回调
.middle 只有点击鼠标中键时,才回调
用法:
绑定事件监听器, 事件类型由 参数 决定, 修饰符为可选
支持 不带参数 绑定一个事件/监听器 键值对的对象 ???Excuse Me???(该情形不支持修饰符)
v-bind 缩写 :
预期: any(带参数) | Object(不带参数)
参数: attrOrProp (可选)
修饰符:
.prop 被用于 绑定DOM 属性
.camel 将kebab-case 转换成 camelCase
.sync 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器???Excuse Me???
用法:
动态地绑定一个或多个属性 或一个组件 prop 到 表达式
在绑定class或sytle属性时, 支持其他类型(如数组或对象)
在绑定prop时,prop必须在子组件中声明(可用修饰符指定不同绑定类型)
没有参数时, 可以绑定到一个 包含 键值对的对象(该情况下class和style不再支持数组和对象) ???Excuse Me???
v-model 指令
只用于表单控件(input select textarea 和 components)
修饰符:
.lazy 只会在change事件时,执行回调
.number 自动将输入的字符串转成数字
.trim 自动过滤输入的首尾空格
v-cloak 指令 (不需要表达式)
用法:
这个指令保持在元素上 直到关联的实例 结束编译时,该指令被移除
常与下面的css样式 一起使用(消除 闪烁, 因为可以隐藏未编译状态下的Mustache指令)
[v-cloak] {
display: none;
}
使用:
<div id="id_div_container" v-cloak>
{
{ girlName }}
</div>
v-once 指令 (不需要表达式)
用法: 只渲染元素一次. 随后的渲染,都将视该元素/组件及其所有子节点 为 静态内容
作用: 优化性能
<div v-once>