目录:
- 三个小时vue3.x从零到实战(前)(vue3.x基础)
- 三个小时vue3.x从零到实战(中)(vue3.x高级语法)
- 三个小时vue3.x从零到实战(后)(vue3.x配套工具及项目化构建)
- 三个小时vue3.x从零到实战(typescript的搭建、使用及资料)
- 三个小时vue3.x从零到实战(vue3.x经典案例46个)
- 三个小时vue3.x从零到实战(vue3.x面试总结)
一. 学前了解
1.1 前置知识
- HTML: 超文本传输语言,主要用来编写网页的结构。
- CSS: 层叠样式表,包括颜色,大小,字体等,实现漂亮,布局合理的效果。
- JavaScript: 前端样式语言,实现页面逻辑,行为,动作等,用来动态操作元素的属性,主要是为页面提供交互效果,实现更好的用户体验。
- node, npm, webpack等
1.2 学习vue3.x的相关网站
- 官网:https://vuejs.org/
- 中文官网:https://cn.vuejs.org/
- 中文官网vue3:https://v3.cn.vuejs.org/
- 菜鸟教程:https://www.runoob.com/vue3/vue3-tutorial.html
- W3CSchool: https://www.w3cschool.cn/vuejs3/
1.3 vue3.x介绍
Vue (读音 /vju?/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
传统的网站开发一般采用HTML+CSS+JS作为技术架构,而vue立足于其上,以模板语法为基础,以数据绑定和组件化开发为核心,极大的简化了开发流程。 使用vue技术栈,可以在几分钟内搭建出一个完整的前端项目。
现在,很多项目采用这样的架构,后台只负责数据的存储和组装,而前端负责业务逻辑层和视图层的全部工作。
-
Vue 是利用模版语法来渲染页面的,这也称做声明式渲染。Vue 好上手的重要原因也是因为这个,因为它符合了前端开发者的习惯。 -
Vue 将 HTML、CSS、JS 全部整合在同一个文件 .vue 中,以组件化应用构建的方式来组织代码,从语法特性上鼓励 “高内聚、低耦合” 的设计理念,让代码组织变得更加合理,提升了可读性与逻辑性。 1). 一位华裔前Google工程师(尤雨溪)开发的前端js库 2). 作用: 动态构建用户界面 3). 特点: * 遵循MVVM模式 * 编码简洁, 体积小, 运行效率高, 移动/PC端开发 * 它本身只关注UI, 可以轻松引入vue插件和其它第三库开发项目 4). 与其它框架的关联: * 借鉴angular的模板和数据绑定技术 * 借鉴react的组件化和虚拟DOM技术 5). vue包含一系列的扩展插件(库): * vue-cli: vue脚手架-(帮我们下载依赖) * vue-resource(axios): ajax请求 * vue-router: 路由 * vuex: 状态管理 * vue-lazyload: 图片懒加载 * vue-scroller: 页面滑动相关 * mint-ui: 基于vue的组件库(移动端) * element-ui: 基于vue的组件库(PC端)
1.4 vue3.x相对于vue2.x的最新特性
- 更多的API特性:CompositionAPI
- 体积更小,速度更快;
- 解决遗留问题,更加强壮
1.5 MVVM框架
- vue是MVVM框架;
- M: Model数据层;
- V: View视图层;
- VM: 视图数据连接层;
二. 创建应用基本介绍
基本使用:
- 引入vue.js;
- 创建Vue实例对象, 指定选项(配置)对象
- 在页面模板中使用{{}}或vue指令
2.1 第一个案例如下:
将下面代码复制到html文件中,用谷歌浏览器打开即可执行。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="hello-vue" class="demo-st">
{{ message }}
</div>
<script>
const HelloVueApp = {
data() {
return {
message: 'Hello Vue!!!'
}
}
}
Vue.createApp(HelloVueApp).mount('#hello-vue')
</script>
</body>
</html>
2.2 应用介绍
Vue.createApp() :创建一个应用,每个 Vue 应用都是通过用 createApp 函数创建一个新的应用实例开始的:;const vm = app.mount() : vm是获取应用的根组件,通过vm可以获取vue里的任何数据,属性和方法;vm.$data : 获取数据对应内容;data(){} : data方法,用于在vue中声明数据,对象或函数类型,页面中可以直接访问使用;methods:{} : methods属性,用于编写vue中的方法,所有的方法由vue对象来调用, 访问data中的属性直接使用this.xxx;computed:{} 计算属性:根据数据,自动进行计算,经常用于数值计算;watch:{} :属性说明:监听属性,属性变化时,制动执行里面的函数,可以根据变量的改变,作异步操作和页面样式的改变;
注意:
- computed和method都能实现的功能,建议使用computed, 因为有缓存;
- computed和watcher都能实现的工呢,建议使用computed, 因为更加简洁;
2.3 vue生命周期函数(也叫钩子函数)
生命周期函数是指:在某一时刻会自动执行的函数。
beforeCreate() : 在初始化/创建实例之前执行的函数;Created() :在初始化/创建实例之后执行的函数;beforeMount() : 在组件内容被渲染到页面之前自动执行的函数;(注意:此时无法找到任何模板DOM节点)Mounted() : 在组件内容被渲染到页面之后自动执行的函数;beforeUpdate() : 在数据将要变化之前自动执行的函数;updated() : 在数据将要变化之后自动执行的函数;beforeUnmount() : 在vue实例销毁之前自动执行的函数;unmounted() : 在vue实例销毁之后自动执行的函数;
三. vue常用模板语法
Vue 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。Vue 的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统。结合响应系统,在应用状态改变时, Vue 能够智能地计算出重新渲染组件的最小代价并应用到 DOM 操作上。
插值:在模板中输出变量,在插值表达式中是可以写JavaScript表达式的,例如:{{ 2+3 }} , 但是不能写语句。
3.1 文本插值 {{}} 和指令v-once
数据绑定最常见的形式就是使用 {{…}}(双大括号)的文本插值:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="hello-vue"> {{ message }} <br>
<span v-once>这个将不会改变: {{ message }}</span>
</div>
<script>
const HelloVueApp = {
data() {
return {
message: 'Hello Vue!!!'
}
}
}
Vue.createApp(HelloVueApp).mount('#hello-vue')
</script>
</body>
</html>
3.2 基础指令: v-html
v-html: 转义输出变量的html变量标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<style>
.demo { color: blue; font-size: 15px; font-style: italic; }
</style>
<body>
<div id="example1" class="demo">
<p>使用双大括号的文本插值: {{ rawHtml }}</p>
<p>使用 v-html 指令: <span v-html="rawHtml"></span></p>
</div>
<script>
const RenderHtmlApp = {
data() {
return {
rawHtml: '<span style="color: red">这里会显示红色!</span>'
}
}
}
Vue.createApp(RenderHtmlApp).mount('#example1')
</script>
</body>
</html>
3.3 基础指令: v-bind
v-bind: 绑定html标签中的属性值 原写法:<div v-bind:title="message"> , 可简写为:<div :title="message"> 动态事件绑定:<div :[xxx]="message"> , xxx是在data里定义的变量
3.4 基础指令: v-on
v-on: 在模板中绑定事件 原写法:<div v-on:clink="handleClick"> 简写为:<div v-@click="handleClick"> 动态事件绑定:<div @[xxx]="handleClick"> , xxx是在data里定义的变量
3.5 基础指令: v-if
v-if: 在模板中进行判断;
3.6 基础指令: v-show
v-show 根据变量负责DOM的展示与否
3.7 基础指令: ref
ref: 是获取dom节点/组件引用的一个语法 模板语法:<div ref="count"> 程序写法:this.$refs.count
3.8 基础指令: v-for
v-for可以直接在模板中循环打印数组和对象, vue要求循环时在模板中增加key值 :key="index" ,避免重复渲染。 数组循环案例:v-for="(item, index) in list" 对象循环案例:v-for="(value, key, index) in list"
案例:遍历数组
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<div>
<ol>
<todo-item v-for="todo in todos" :key="todo.id" :todo="todo">
</todo-item>
</ol>
</div>
</div>
<script>
const App = {
data() {
return {
todos: [
{ id: 1, description: "eat吃饭" },
{ id: 2, description: "drink" },
{ id: 3, description: "sleep" }
]
};
}
};
const app = Vue.createApp(App);
app.component("todo-item", {
props: ["todo"],
template: `<li>{{todo.description}}</li>`
});
app.mount("#app");
</script>
</body>
</html>
注意:循环和判断不能写在一个标签上,否则是没办法进行判断的。
3.9 变更数组的方法
push() : 从数组尾部添加内容 unshift() : 从数组头部添加内容 pop() : 从数组末尾删除内容 shift() : 从数组头部删除内容 sort() : 对数组进行排序 reverse() : 对数组进行取反 split() : 从数组中筛选具体的内容
案例:翻转字符串
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<p>原字符串:{{message}}</p>
<p>翻转字符串:{{reversedMessage}}</p>
<p>翻转结果用-连接{{reversedMessageJoin}}</p>
</div>
<script>
const App = {
data() {
return {
message: "hello world"
};
},
computed: {
reversedMessage() {
return this.message.split("").reverse().join("");
},
reversedMessageJoin() {
return this.message.split("").reverse().join(" - ");
}
}
};
const app = Vue.createApp(App);
app.mount("#app");
</script>
</body>
</html>
四. 样式绑定语法
4.1 用字符串绑定动态样式
在data() 方法里定义一个变量,然后用v-bind在模板中绑定属性;
4.2 用对象绑定动态样式
在data() 方法里声明一个对象
4.3 用数组绑定动态样式
在data() 方法里定义一个数组
4.4 行内样式动态绑定
-
字符串形式:直接在data()方法里,声明一个CSS样式的字符串,然后在模板中进行绑定:
data()中编写:styleString :'coler: yellow' 模板绑定中编写:<div :style="StyleString">
-
对象形式:在data方法里,声明一个变量,变量是一个对象,然后在模板中进行绑定:
data()中编写:styleObject :'coler: yellow' 模板绑定中编写:<div :style="StyleObject">
建议:建议在工作中使用对象的形式来编写模板中的行内样式动态绑定,因为这样更加直观,字符串拼接也不容易出错。
五. 事件绑定
5.1 事件绑定修饰符
@click.stop :停止事件冒泡@click.self :停止向下传递@click.prevent :阻止默认行为@click.capture :捕获模式修饰符@click.once :事件只绑定一次@click.passive :提升滚动性能
@click案例:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<button @click="count++">increment</button>
count: {{ count }}
</div>
<script>
const Counter = {
data() {
return {
count: 0
};
}
};
Vue.createApp(Counter).mount("#app");
</script>
</body>
</html>
5.2 按键绑定修饰符
keydown : 按键就可以触发事件keydown.enter : 按回车键就可以触发事件keydown.tab : 按tab键就可以触发keydown.delete : 按删除键可以触发keydown.esc : 按esc键时触发keydown.up : 按上键时触发keydown.down : 按下键时触发
5.3 鼠标绑定修饰符
click.left : 点击鼠标左键时触发click.right : 点击鼠标右键时触发click.middle : 点击鼠标中键触发
5.4 精确修饰符
click.ctrl.exact : 按ctrl和鼠标键才会触发
5.5 双向绑定
v-model:双向绑定的最基本用法
- 双向数据绑定是建立在单向数据绑定(model==>View)的基础之上的
- 双向数据绑定的实现流程:
- 在解析v-model指令时, 给当前元素添加input监听
- 当input的value发生改变时, 将最新的值赋值给当前表达式所对应的data属性
修饰符:
v-model.lazy : 当失去焦点时才会触发双向绑定;v-model.number : 自动转变为number类型v-model.trim : 去掉字符串前后的空格
六. 组件
概念:就是把一个大功能,拆分成一个个子组件,组件是页面中的一部分。
6.1 全局组件
注册全局组件并使用:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<zidingyi></zidingyi><br>
<button-counter></button-counter>
</div>
<script>
const app = Vue.createApp({})
app.component('zidingyi', {
template: `<h1>自定义组件!</h1>`
})
app.component('button-counter', {
data() {
return {
count: 0
}
},
template: `<button @click="count++">点了 {{ count }} 次!</button>`
})
app.mount('#app')
</script>
</body>
</html>
6.2 局部组件
局部组件案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 </title>
<script src="../js/vue.global.js"></script>
</head>
<body>
<div id="app">
<comp_a></comp_a>
<comp_b></comp_b>
</div>
<script>
var componentsA = {
template: '<h1>自定义组件-A!</h1>'
}
var componentB = {
template: '<h1>自定义组件-B!</h1>'
}
const app = Vue.createApp({
components: {
'comp_a': componentsA,
'comp_b': componentB
}
})
app.mount('#app')
</script>
</body>
</html>
6.3 组件传值
组件传值案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 </title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<site-info
v-for="site in sites"
:id="site.id"
:title="site.title"
></site-info>
</div>
<script>
const Site = {
data() {
return {
sites: [
{ id: 1, title: 'Google' },
{ id: 2, title: 'Douyin' },
{ id: 3, title: 'Taobao' }
]
}
}
}
const app = Vue.createApp(Site)
app.component('site-info', {
props: ['id','title'],
template: `<h4>{{ id }} - {{ title }}</h4>`
})
app.mount('#app')
</script>
</body>
</html>
七. 过渡和动画
利用vue去操控css的transition/animation动画
模板: 使用<transition name='xxx'>包含带动画的标签
css样式
.fade-enter-active: 进入过程, 指定进入的transition
.fade-leave-active: 离开过程, 指定离开的transition
.xxx-enter, .xxx-leave-to: 指定隐藏的样式
编码例子
.xxx-enter-active, .xxx-leave-active {
transition: opacity .5s
}
.xxx-enter, .xxx-leave-to {
opacity: 0
}
<transition name="xxx">
<p v-if="show">hello</p>
</transition>
八. 路由vue-router
vue用来实现SPA的插件
使用vue-router
1. 创建路由器: router/index.js
new VueRouter({
routes: [
{ // 一般路由
path: '/about',
component: about
},
{ // 自动跳转路由
path: '/',
redirect: '/about'
}
]
})
2. 注册路由器: main.js
import router from './router'
new Vue({
router
})
3. 使用路由组件标签:
<router-link to="/xxx">Go to XXX</router-link>
<router-view></router-view>
编写路由的3步
1. 定义路由组件
2. 映射路由
3. 编写路由2个标签
嵌套路由
children: [
{
path: '/home/news',
component: news
},
{
path: 'message',
component: message
}
]
向路由组件传递数据
params: <router-link to="/home/news/abc/123">
props: <router-view msg='abc'>
缓存路由组件
<keep-alive>
<router-view></router-view>
</keep-alive>
路由的编程式导航
this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)
this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)
this.$router.back(): 请求(返回)上一个记录路由
|