🍭?Hello,我是爱吃糖的范同学?
????????秋招终于结束了(拿到了比较满意的 offer🎉🎉🎉,后续也会有“面筋”系类给大家分享),目前我终于也有足够的时间和精力来完成我 23 年遗留下的未填的“坑”。首先给大家道个歉:“对不起!”,鸽了那么久😭😭😭 这次一定!!!
? ? ? ? 对新来的同学,表示欢迎!希望这个系列能让大家有所收获🥳🥳🥳
------------------------------------------- 嘞是一个分隔线 --------------------------------------------------
????????🔴 想把自己学习技术的经历和一些总结分享给大家!
? ? ? ? 🔴 通过这样的方式记录自己成长,同时沉淀自己的技术,我会把所有额外的时间和经历投放到CSDN和公众号(💥公号名:CSBox💥,欢迎关注,为大家准备了很多有关编程学习资料)文章的撰写。
? ? ? ? 🔴 希望能通过这样的方式让大家认识我,和我一起学习编程,共同进步!😃
? ? ? ? 希望能和大家一起进步和成长!坚持热爱!🎉🎉🎉
目录
? ? ? ? 学习之旅是漫长的、苦涩的、无味的,也许只有走到旅途中的某个时刻回头望的时候,才是充满成就感的。感谢那个没有让自己半路撤退的你!
????????学习的过程会遇到很多怀疑自己的时刻:代码没问题却老报错;一个看似很简单的 bug 自己怎么也找不到解决方案。这个时候就看自己的选择是无意义的怀疑打击自己,还是在失利的低气压下,继续去想自己到底能做些什么来改变当下的困境。 就像《洛奇》里面主人公所说的那句话:
????????It's not about how hard you hit ,it's about how hard you can get hit and keep moving forward That's how winning is done .
????????愿我们都能在失利的情况下,继续坚持思考如何解决,而不是陷在消极情绪里不出来,因为这样并没有什么作用,也不会有上帝来帮你,能解决问题的只有自己的行动。😫😫😫
? ? ? ? 从这里开始我们即将开启一段新的旅程 Vue,当我们经历?HTML,CSS,JavaScript 等等旅程之后,我们即将来到这一段旅程。我们将了解到企业级前端开发框架,了解到工程化开发方式,我们将会对页面进行组件拆分等等更加高效的开发技能。做好准备,启程!😀
? ? ? ? 根据官方文档介绍:Vue 是一个用于构建用户界面的渐进式 JavaScript 框架。
Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)https://cn.vuejs.org/
? ? ? ? 😑 官方文档就是喜欢用一些这样的专有名词,拉高学习曲线,看都看不明白(菜鸡太难了......呜呜呜😫😫😫)
? ? ? ? 这里做一个简单的解释:Vue 是基于 JavaScript 编写的一套前端框架,主要用于帮助前端开发人员能够以更高效率进行页面功能的开发实现。
????????那什么是框架呢?
????????框架其实就好比工具箱,我们把一些常用的工具都提前放入工具箱中。需要使用这些工具时提前从工具箱中拿来使用即可,没必要每次都从打铁开始。
? ? ? ? 针对 Vue 来说,其中封装了很多前端开发使用的功能,避免开发人员每次都需要编写原生的 JavaScript 代码去实现功能。同时,Vue 提供了更好的拓展,基于各种插件能集成其他额外的功能。?
? ? ? ? 那什么是渐进式?
? ? ? ? 我个人的理解是学习是可以循序渐进的,可以从核心的基础功能开始,逐步由浅入深,由核心向拓展进行学习。这样也是符合我们的学习旅程的规划(当然,我认为所有的学习都应该遵循这样的方式 PS:个人见解😃)。
? ? ? ? 先学习最基础的核心功能,在掌握了基础核心之后,再向外进行拓展学习。由浅入深,由内向外。先学会使用,再学习原理。当然,必不可少的是定时的回顾和复习。学过不一定是自己的东西,只有理解了记住了,在日常使用了,才是真正成了自己的东西。
?
? ? ? ? 我们尝试使用 Vue 构建一个用户界面。体验使用 Vue 开发 与 原生 JavaScript 开发的不同。
? ? ? ? 首先,准备 HTML 容器,用于承载数据和向用户展示数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 这里定义了一个div容器进行Vue内容承接 -->
<div id="app">
</div>
</body>
</html>
? ? ? ? 使用 script 标签的方式 引入 Vue 框架:
<!-- 引入 Vue.js 框架-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
? ? ? ? 创建 Vue 实例,然后在 Vue 实例中进行配置:
<script>
<!-- 创建一个 Vue 实例 -->
const app = new Vue({
// 选择器表达式:
el: "#app",
// 数据源:
data: {
message: `<h1>Hello World !</h1>`
}
})
</script>
? ? ? ? 指定配置项,渲染数据:
? ? ? ? 完整代码示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<!-- 引入 Vue.js 框架-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
<!-- 使用 Vue 的 {{}} 插值语法 -->
<div id="app">
{{ message }}
</div>
</body>
<script>
<!-- 创建一个 Vue 实例 -->
const app = new Vue({
// 选择器表达式:
el: "#app",
// 数据源:
data: {
message: `Hello World !`
}
})
</script>
</html>
? ? ? ? 插值表达式是一种由 Vue 的模板语法。可以利用表达式将 Vue 提供的数据插入到 HTML 页面中,然后进行渲染。表达式是可以被求值的代码,JavaScript 引擎会对其进行计算然后得出一个结果。
{{ JavaScript 表达式 }}
? ? ? ? 注意点:
? ? ? ? 数据的响应式处理,响应式是指数据如果发送了变化,那么对应在视图上会进行自动更新。数据改变,视图自动更新。
?
? ? ? ? 这样的一个实现就可以使得开发人员聚焦于数据的处理,让 Vue 通过数据驱动视图进而更新页面展示。使用 Vue 进行开发,主要关注的业务的核心逻辑,根据业务修改数据即可。
????????如何访问和修改数据呢?
? ? ? ? data 中的数据最终都会添加到 Vue 实例上。访问数据可以通过 "Vue实例.属性名" 进行访问。修改数据可以使用 "Vue实例.属性名 = 值"。
? ? ? ? 安装 Vue 开发者工具,用来调试 Vue 应用。
? ? ? ? 如果使用的是 Edge 浏览器的话直接在插件市场进行搜索安装即可,如果使用的是 Google 浏览器的话就需要使用魔法才能访问插件市场😏。
? ? ? ? 开启开发者模式:
?
? ? ? ? 然后在插件市场中搜索 Vue 插件:
?
? ? ? ?进入插件的详情页面,对插件进行配置:
?
? ? ? ? 开启文件路径访问的权限:?
?
? ? ? ? Vue 会根据不同的指令,针对标签实现不同的功能。Vue 指令通常是带有 v- 的前缀的特殊标签属性。
????????Vue 指令:v-html、v-show、v-if、v-else、v-on、v-bind、v-for、v-model
? ? ? ? 官方文档:
API — Vue.js (vuejs.org)https://v2.cn.vuejs.org/v2/api/#%E6%8C%87%E4%BB%A4
? ? ? ? v-html 用于更新 innerHTML,Vue 会将 v-html 绑定的内容渲染到标签中以 HTML 的方式进行解析。
<div v-html="html"></div>
????????v-show:控制元素显示隐藏,控制的是元素的 display 样式属性进而来控制元素的显示与否。
<h1 v-show="true">Hello!</h1>
????????v-show 本质上控制元素的 CSS 属性 display,block为显示,none为隐藏。
????????v-if:控制元素显示隐藏(条件渲染),用来辅助开发者按需进行 DOM 元素的显示与隐藏。
<div v-if="show === true">TRUE</div>
<div v-if="show === false">FALSE</div>
????????v-if 的元素始终会被渲染并保留在 DOM 中。
????????我们可以使用 v-else 指令来表示 v-if 的“else 块”:
<div id="app">
<h1 v-if="Math.random() > 0.5">
使用了 if
</h1>
<h1 v-else>
使用了 else
</h1>
</div>
????????v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
????????v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用。类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button @click="random=Math.random()">点我呀</button><span>{{random}}</span>
<h1 v-if="random >= 0.75">
if
</h1>
<h1 v-else-if="random > 0.5">
if 0.5
</h1>
<h1 v-else-if="random > 0.25">
if 0.25
</h1>
<h1 v-else>
else
</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
const app = new Vue({
el: "#app",
data: {
random: 1
}
});
</script>
</html>
????????v-on指令用于给页面元素绑定事件。
v-on:事件名="js片段或函数名"
????????事件绑定是可以简写的,例如v-on:click= ‘add’ 可以简写为 @click='add’
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--事件中直接写js片段-->
<button @click="num++">增加一个</button><br/>
<!--事件指定一个回调函数,必须是Vue实例中定义的函数-->
<button @click="decrement">减少一个</button><br/>
<h1>{{num}}</h1>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
const app = new Vue({
el: "#app",
data: {
num: 100
},
methods: {
decrement() {
this.num--;
}
}
});
</script>
</body>
</html>
????????在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
????????为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。修饰符是由点开头的指令后缀来表示的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--右击事件,并阻止默认事件发生-->
<button @contextmenu.prevent="num++">增加一个</button>
<br/>
<!--右击事件,不阻止默认事件发生-->
<button @contextmenu="decrement()">减少一个</button>
<br/>
<h1>{{num}}</h1>
<!-- 缩写语法 -->
<input @keyup.enter="submit">
<!-- Ctrl + Click -->
<button @click.ctrl="clear">Clear</button>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
const app = new Vue({
el: "#app",
data: {
num: 100,
},
methods: {
decrement() {
this.num--;
},
submit(){
console.log("你已经提交了")
},
clear(){
this.num=0;
}
}
});
</script>
</html>
????????在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">
????????记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:
<!-- 缩写语法 -->
<input @keyup.enter="submit">
全部的按键别名:
????????组合按钮:可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
<!-- Alt + C -->
<input @keyup.alt.67="submit()">
<!-- Ctrl + Click -->
<button @click.ctrl="clear">Clear</button>
????????html 属性不能使用双大括号形式绑定,只能使用v-bind指令。在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--可以是数据模型,可以是具有返回值的js代码块或者函数-->
<div v-bind:title="title" style="border: 1px solid red; width: 50px; height: 50px;"></div>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
const app = new Vue({
el: "#app",
data: {
title: "title",
}
});
</script>
</html>
????????遍历数据渲染页面是非常常用的一个功能,Vue 提供了 v-for 指令来简化这个功能的实现:
v-for="item in items"
????????在遍历的过程中,如果我们需要知道数组角标,可以指定第二个参数:
v-for="(item,index) in items"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="user in users">
{{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
const app = new Vue({
el: "#app",
data: {
users: [
{name: '张三', gender: '女', age: 19},
{name: '李四', gender: '男', age: 20},
{name: '王五', gender: '女', age: 23},
{name: '马六', gender: '女', age: 19},
{name: '赵七', gender: '女', age: 22}
]
},
});
</script>
</html>
????????v-for 除了可以迭代数组,也可以迭代对象。语法基本类似:
v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
<body>
<div id="app">
<ul>
<li v-for="(user,index) in users">
{{index+1}} - {{user.name}} - {{user.gender}} - {{user.age}}
</li>
</ul>
<ul>
<li v-for="(value, key, index) in user">
{{index + 1}}. {{key}} - {{value}}
</li>
</ul>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
const app = new Vue({
el: "#app",
data: {
users: [
{name: '张三', gender: '女', age: 19},
{name: '李四', gender: '男', age: 20},
{name: '王五', gender: '女', age: 23},
{name: '马六', gender: '女', age: 19},
{name: '赵七', gender: '女', age: 22}
],
user:{name: '张三', gender: '女', age: 19}
},
});
</script>
????????当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
????????这个功能可以有效的提高渲染的效率。但是要实现这个功能,你需要给Vue一些提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。
<ul>
<li v-for="(item,index) in items" :key=index></li>
</ul>
? ? ? ? 双向数据绑定:数据双向绑定是指将数据层和视图层关联起来,当数据层发生变化时,视图层也会随之更新,反之亦然。
????????刚才的 v-text 和 v-html 可以看做是单向绑定,数据影响了视图渲染,但是反过来就不行。接下来学习的 v-model 是双向绑定,视图(View)和模型(Model)之间会互相影响。
????????既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。目前v-model的可使用元素有:
????????测试代码(checkbox):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="language" value="Java" />Java<br/>
<input type="checkbox" v-model="language" value="Python" />Python<br/>
<input type="checkbox" v-model="language" value="PHP" />PHP<br/>
<input type="checkbox" v-model="language" value="C++" />C++<br/>
<input type="checkbox" v-model="language" value="C#" />C#<br/>
<h1>
你选择了:{{language.join(',')}}
</h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
const vm = new Vue({
el: "#app",
data: {
language: []
}
});
</script>
</html>
????????在插值表达式中使用 JavaScript 表达式是非常方便的,而且也经常被用到。但是如果表达式的内容很长,就会显得不够优雅,而且后期维护起来也不方便。
????????例如下面的场景,我们有一个日期的数据,但是是毫秒值:
data:{
birthday:1529032123201 // 毫秒值
}
????????我们在页面渲染,希望得到 yyyy-MM-dd 的样式:
<h1>您的生日是:{{
new Date(birthday).getFullYear() + '-'+ new Date(birthday).getMonth()+ '-' + new Date(birthday).getDay()
}}
</h1>
????????虽然能得到结果,但是非常麻烦,在 Vue 中提供了计算属性,来替代复杂的表达式。
????????计算属性(computed):本质就是方法,但是一定要返回数据。然后页面渲染时,可以把这个方法当成一个变量来使用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--注意:使用birth时并没有加括号-->
<h1>您的生日是:{{birth}} </h1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
birthday: 999999999999 // 毫秒值
},
computed: {// 计算属性本质是一个方法,但是必须返回结果
birth() {
const d = new Date(this.birthday);
return d.getFullYear() + "-" + d.getMonth() + "-" + d.getDay();
}
}
});
</script>
</html>
????????我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是?计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 birthday 还没有发生改变,多次访问 birthday 计算属性会立即返回之前的计算结果,而不必再次执行函数。
? ? ? ? watch 监视器的作用是监视数据的变化状况,执行指定的业务逻辑和异步操作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
const vm = new Vue({
el: "#app",
data: {
message: ""
},
watch: {
message(newVal, oldVal) {
console.log(newVal, oldVal);
}
}
});
</script>
</html>
? ? ? ? 万丈高楼平地起!打好基础非常重要,目前我们已经对 Vue 有了初步的了解,后面的旅程我们会继续对 Vue 进行学习,掌握更多的开发技能,不断丰富我们的技术栈。温故而知新,在不断向后学习的过程中,也要回顾过往所学,巩固基础。
? ? ? ? 最后,纸上得来终觉浅,绝知此事要躬行!加油!!!🎉🎉🎉