无论学习什么东西,你想记住它,就得赋予意义!
对于前后端来说,就是找到此知识点运用在何种需求,思考为什么要这样做,学了它有什么用?
学IT就得自己去敲代码,用的多了就记住了,反复去看去记是没用的,过两天就忘。
问题:
vue代码块在hexo生成的网页中因为highlight插件的原因,无法正确高亮,我将用html代替
如下图,实际上这是一段vue代码,但为了在网页中实现代码高亮,便于阅读,我将用html代替
tips:
1-编辑文件文字的时候,突然点一个地方,如果写入必须删了那个字,而不能插入。是因为进入了“覆盖(Overwrite)”模式。切换“插入/覆盖”的默认快捷键是Insert。
2-f5是刷新网页,但是会走缓存,ctrl+f5是强制刷新重新获取资源。
3-在最新的vscode中,!已经无法自动生成html模板了(可以在设置的use inline completions中打开),我们可以输入doc生成
认识Vue
渐进式表示你这个项目不止可以使用vue,也可以使用原生代码,或者其他js库开发,也可以全部用vue开发(在实际开发中一般整个项目全用vue)。
vue在前端的位置
1-Angular编写门槛高,写它必须会TypeScript,在国内使用较少,可以不学。
2-React是必学的,但是和Vue相比,得先学Vue,如果时间紧迫react可以等找到工作了再学也没有问题(一般工资18k以上必须会react)
3-Vue框架是当前中国市场开发项目使用最多的前端框架,必须学习。
2022学vue2还是vue3?
vue3是向下兼容的,基础和概念都一模一样的,而且现在的新项目都是vue3和ty结合
Vue3相比Vue2,性能更好,包体积更小,支持typescript,有更好的API设计
Vue的使用
1-在初学VUE基础语法的使用,我们通过cdn引入或者下载源码js文件手动引入
2-在后续我们会通过npm引入,或者Vuecli脚手架直接创建Vue项目
cnd引入
记住你引入vue的时候,必须放在其他script的上面,因为是从上到下执行的,你不先引入vue的代码,后面的script根本没法执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>我是原生的html</h2>
<div id="app"></div>
<script src="https://unpkg.com/vue@next"></script>
<script>
//创造app
const app = Vue.createApp({
template: '<h2>vue初体验</h2>'
})
//挂载
app.mount("#app")
</script>
</body>
</html>
template模板,mount挂载嵌入
1-我们写入原生的html
2-通过script引入vue的cdn文件,https://unpkg.com/vue@next是最新的vue源码cdn
3-Vue是一个全局对象,里面有一个createApp函数方法,注意Vue.createApp()必须大写V
4-在方法内传入一个对象,对象中有一个template属性,里面反引号加入原生的html代码
5-createApp会返回一个对象,我们需要定义一个变量接收
6-接收的对象会有一个mount函数,把它的内容挂载到html的标签上,通过id选中识别(只要是选择器都可以)。
注意:这个mount函数是挂载,不是后加,比如上面是挂载到div中,如果div起初就有内容,会被覆盖掉。
遇到问题,或者样式没按预期发展,我们第一时间得去看控制台输出了什么提示,不要逮着代码去找原因,也许就是一个字母写错了,你看一年也找不出来。
本地引入
本地引入就把远程的cdn里面的代码复制下来,然后创造lib/vue.js粘贴进去就好了,然后引入。
本地引入速度是比cdn快的,cdn毕竟要请求网络,然后下载源码。
动态展示数据
插值语法
<body>
<h2>测试</h2>
<div class="demo">我这里写再多内容都没用,会被下面的app挂载覆盖</div>
<script src="https://unpkg.com/vue@next"> </script>
<script>
const app =Vue.createApp({
template:`
<a>{{title}}</a>
<h2>{{message}}</h2>`,
data:function(){
return{
title:"插值语法",
message:"你好VUE"
}
}
})
app.mount('.demo')
</script>
</body>
我们通过写一个data属性(这个template和data不能随便命名的,这是vue底层规定的,必须这样写)
然后data属性规定是一个函数,函数内return一个对象,包含了需要使用的变量等
然后通过两个大括号写入数据。
动态的列表数据
<body>
<h2>测试</h2>
<div class="demo">我这里写再多内容都没用,会被下面的app挂载覆盖</div>
<script src="https://unpkg.com/vue@next"> </script>
<script>
const app = Vue.createApp({
template: `
<h2>{{title}}</h2>
<ul>
<li v-for="item in movies"> {{item}}</li>
</ul>`,
data: function () {
return {
title: "插值语法",
message: "你好VUE",
movies: ['超体', "盗梦空间", '了不起的盖茨比']
}
}
})
app.mount('.demo')
</script>
</body>
我们可以有多少数据就写多少个li标签,然后,……..写入进去,当前这是不可能的太麻烦了
我们可以通过v-for=“item in movies”来遍历数据,然后插入列表。
计数器功能实现
<body>
<div id="jishuqi" app></div>
<script src="https://unpkg.com/vue@next"> </script>
<script>
const app = Vue.createApp({
template: `
<h2>当前计数:{{counter}}</h2>
<button @click="jia" >+1</button>
<button @click="jian" >-1</button>
`,
data: function () {
return {
counter: 0
}
},
methods: {
jia: function () {
this.counter++
},
jian: function () {
this.counter--
}
}
})
app.mount("#jishuqi")
</script>
</body>
1-通过template把样式写好
2-学习新的一个属性,methods,里面写一个对象,包含不同的方法函数。
3-在标签里面通过@click=”方法名”来实现调用,而不是以前的原生dom截取监听事件。
问题:上面代码你这个jian里面的this怎么能控制我data里面的counter?
因为这些vue底层通过proxy和bind方法这些,重定向了this的指向,这里的this可以代理data里面函数返回的那个对象,我们知道就好了,深入源码底层的时候就全明白了。
代码重构
我们template也可以直接删,然后把样式标签直接写在要挂载的那个标签内
如果我们写了template默认是会覆盖掉挂载标签的内容的,不写template就默认挂载标签内容为模板
<body>
<div id="jishuqi" app>
<h2>当前计数:{{counter}}</h2>
<button @click="jia">+1</button>
<button @click="jian">-1</button>
</div>
<script src="https://unpkg.com/vue@next"> </script>
<script>
const app = Vue.createApp({
data: function () {
return {
counter: 0
}
},
methods: {
jia: function () {
this.counter++
},
jian: function () {
this.counter--
}
}
})
app.mount("#jishuqi")
</script>
</body>
声明式编程和命令式编程
1-我们原生的js就是命令式编程,一步一步的写入命令,操作dom
2-vue和小程序和react都是声明式编程,你声明了一些东西,互相绑定好数据关系即可
3-声明式编程底层也是去操作dom,但是不需要我们本人去写了。
MVVM模型
modol模型通俗来说就是数据
view就是html这些视图
controller就是js,是来控制东西的,让视图和数据结合绑定起来
在vue中,vue框架就担任了view-modol的角色,它即会底层操作dom也会把view视图和model数据结合起来。
简单的说,Controller所要担任的任务更加全面,包括了很多的业务逻辑。而ViewModel则简化甚至剔除了业务逻辑,主要的工作就只是把Model中的数据组装成适合View使用的数据。
相对于Vue来说,Angular确实算得上MVC框架。其实吧,对于前端来说,只需要很少甚至不需要业务逻辑,所以MVC这种后端设计结构其实并不适合。所以随着MVP、MVVM这种弱化业务逻辑的结构在前端领域变得越来越流行。
MVC
路由至控制器内,需要在控制器自己处理model(data), 然后进行重新渲染生成view(UI)MVVM
数据驱动式,一旦model有变化, 其view(UI)就会改变.
data属性
data数据是如何被展示的
首先在html渲染中,发现了两个大括号这种插入语法,就说明需要用到了data里面返回的数据对象,然后vue底层会对这个对象进行监听劫持,在vue2中是通过defineproperty,在vue3是通过proxy,一旦发现data内返回的数据对象发生改变,马上在view视图也就是html中也改变。
<body>
<div class="demo">
<h2>{{message}}</h2>
<button @click="changeMessage">改变message内容</button>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data(){
return{
message:'你好世界'
}
},
methods:{
changeMessage:function(){
this.message='你好瑾年'
}
//这种写法也可以,但是不能写箭头函数
// changeMessage(){
// this.message='你好瑾年'
// }
}
})
app.mount('.demo')
</script>
</body>
上面为什么可以data(){}这样写?不是应该data:function(){}吗?
https://www.cnblogs.com/zsh-blogs/p/12963108.html
methods属性
methods属性中的对象是不能写成箭头函数的,在js高级我们知道箭头函数的this是沿用与上一层的this(一般结构下会指向全局window),那么就无法调用到data里面的数据了。
vscode生成代码片段
代码片段就是按几个键,直接生成一个html或者js或者c等等文件的模板
选择html.json,然后进入网站snippet-generator.app,复制以后每次要一键生成的代码,然后生成json代码复制到html.json中
下图中的vueapp就是模板快捷字符,我们只需要在编辑器输入vueapp就能生成这个代码
create vue app是这段json的描述,随便写什么无伤大雅。
模板template语法
插值语法
1-查找语法也叫大胡子语法,因为两个大括号很想一个大胡子
2-{ { } }中不仅可以写简单的变量,还可以写成表达式,甚至是三元运算符和有返回值的函数
为什么可以呢?因为表达式和运算符和函数调用后,最终都会返回一个值的,显示就显示那个值。
3-但是它里面不能定义语句,如{ {const i =1 } },很简单因为它没有返回值出来。
注意: 使用插值语法必须让它和vue有联系,你如果直接写html写一个p标签,里面就写插值语法是没用的,必须有挂载。
其次是template后是反引号``,不是双引号。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 1.基本使用 -->
<h2>{{ message }}</h2>
<h2>当前计数: {{ counter }} </h2>
<!-- 2.表达式 -->
<h2>计数双倍: {{ counter * 2 }}</h2>
<h2>展示的信息: {{ info.split(" ") }}</h2>
<!-- 3.三元运算符 -->
<h2>{{ age >= 18? "成年人": "未成年人" }}</h2>
<!-- 4.调用methods中函数 -->
<h2>{{ formatDate(time) }}</h2>
<!-- 5.注意: 这里不能定义语句 -->
<!-- <h2>{{ const name = "why" }}</h2> -->
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
message: "Hello Vue",
counter: 100,
info: "my name is why",
age: 22,
time: 123
}
},
methods: {
formatDate: function(date) {
return "2022-10-10-" + date
}
}
})
// 2.挂载app
app.mount("#app")
</script>
</body>
</html>
v-once了解
v-once,v-for,v-text等等都是写在标签内的,它算是标签的一个属性。
v-once表示此标签内的内容(包括此标签包含的后代标签),只渲染一次,后续你怎么操作让它改变,都改不了的。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 指令: v-once -->
<h2 v-once>
{{ message }}
<span>数字: {{counter}}</span>
</h2>
<h1>{{message}}</h1>
<button @click="changeMessage">改变message</button>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
message: "Hello Vue",
counter: 100
}
},
methods: {
changeMessage: function() {
this.message = "你好啊, 李银河"
this.counter += 100
console.log(this.message, this.counter)
}
}
})
// 2.挂载app
app.mount("#app")
</script>
</body>
</html>
v-text了解
它是用于改变元素的contenttext的,和大胡子语法{ { } }差不多,而且没那么灵活。
<body>
<div id="app">
<h2> aa {{message}} bbb</h2>
<h2 v-text="message">aaa</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
message: "Hello Vue"
}
},
})
// 2.挂载app
app.mount("#app")
</script>
</body>
如上代码, < h 2 v-text=”message”>aaa < /h 2>
我们可以把data里面的返回值写入h2元素标签,但是它是指定的一个值,即使h2里面有‘’aaa‘,也会被message变量的值覆盖。 所以没有{ { } }灵活
v-html
它可以给一个标签插入html代码并解析
<body>
<div id="app">
<h2>{{ content }}</h2>
<h2 v-html="content"></h2>
</div>
<script src="../lib/vue.js"></script>
<script>
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
content: `<span style="color: red; font-size: 30px;">哈哈哈</span>`
}
},
})
// 2.挂载app
app.mount("#app")
</script>
</body>
如上把content变量写入h2中,在浏览器中会把content中的代码变成h2的子元素,也就是< h 2>
哈哈哈< / h 2 >
但是如果起初h2里面就有内容,会被v-html的内容覆盖。
v-pre
也就是说,加了v-pre会让插值语法{ { } }失效,而在用户浏览器页面显示出两个大括号
应用场景:我们 就需要显示两个大括号,不需要插值语法
v-cloak了解
cloak遮盖,斗篷。它需要配合css一起使用。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<h2 v-cloak>{{message}}</h2>
</div>
<script src="../lib/vue.js"></script>
<script>
setTimeout(() => {
// 1.创建app
const app = Vue.createApp({
// data: option api
data: function() {
return {
message: "Hello Vue"
}
},
})
// 2.挂载app
app.mount("#app")
}, 3000)
</script>
</body>
</html>
如上,我们给vue的代码设置一个定时器,模拟js文件没加载完的情况
1-当我们没有加载完vue源码和代码的话,那么 <h 2 v-cloak></h 2>就会在页面直接显示出,用户看到就会非常突兀。
2-我们可以加一个v-cloak,然后通过属性选择器[v-cloak]设置一个css样式,就会生效到被加cloak的标签,通常加 display: none;让原来的消失。
3-当和vue相关的代码加载完毕,v-cloak的样式会自动清除,显示出Hello Vue
在实际.vue开发中不常用,初期学vue的基础代码会用到。
v-memo了解
memo备忘录的意思
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-memo="[name, age]">
<h2>姓名: {{ name }}</h2>
<h2>年龄: {{ age }}</h2>
<h2>身高: {{ height }}</h2>
</div>
<button @click="updateInfo