愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:零基础到项目实战课程简介
适合人群
前端工程师
后端工程师
测开工程师
岗位需求
课程大纲速览
学后水平
项目实战演示
学习形式
Vue
定义
官方:是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。
即:从使用轻量小巧核心库构建的简单应用 ==>> 引入各式各样的Vue插件的复杂应用
作者
尤雨溪
特点
组件化,代码维护更加方便,大大提高了代码的复用率

声明式,开发者无需操作DOM,提高开发的效率
通过操作原生DOM
<ul></ul><script> var person = [ { name: '张三', sex: '男', age: 18 }, { name: '李四', sex: '女', age: 19 }, { name: '王五', sex: '男', age: 20 }, ]; var str = ''; person.forEach((i) => { str += `<li>${i.name}-${i.sex}-${i.age}</li>`; }); var ul = document.getElementsByTagName('ul')[0]; ul.innerHTML = str;</script>通过vue声明式
xxxxxxxxxx<ul id="app"> <li v-for="p in person">{{p.name}}-{{p.sex}}-{{p.age}}</li></ul><script> var app = new Vue({ el: '#app', data: { person: [ { name: '张三', sex: '男', age: 18 }, { name: '李四', sex: '女', age: 19 }, { name: '王五', sex: '男', age: 20 }, ], }, });</script>
虚拟DOM+Diff算法,只更新变化的DOM节点,复用不变的DOM节点
原生操作DOM
当节点发生改变时,将全部节点直接替换
虚拟DOM+Diff算法
当节点发生改变时,只改变增加或者删除的节点,不变的节点直接复用
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:详解Vue开发环境的搭建
下载开发版本通过script标签引入
安装Vue-devtools
克隆gitee项目 https://gitee.com/wen_zhao/devtools
xxxxxxxxxxgit clone https://gitee.com/wen_zhao/devtools.git切换到add-remote-devtools分支
xxxxxxxxxxgit checkout -b add-remote-devtools origin/add-remote-devtools安装依赖
xxxxxxxxxxcnpm i打包
xxxxxxxxxxnpm run build在chrome浏览器中添加扩展程序
解决警告提醒
全局配置设置关闭
xxxxxxxxxxVue.config.productionTip = false
简介:用Vue写第一个hello word
在网页输出hello world
准备好一个装载数据的容器
xxxxxxxxxx<div id="app">{{message}}</div>创建Vue实例
xvar app = new Vue({ el: '#app', // 用于指定当前vue实例为哪个容器使用,值为css选择器字符串 data: { // 用于储存数据,数据供el指定的容器使用 message: 'Hello world!', },});可以自己定义快捷输出实例模板注意

简介:玩转Vue中模板语法
插值语法
特点:用在标签体内容
写法
xxxxxxxxxx{{xxx}} // xxx是js表达式,可以拿到data里所有的属性指令语法
特点:用在标签的解析(标签属性,标签体内容,绑定事件等)
举例(vue的指令语法形式写法:v-xxx)
xxxxxxxxxx// 解析标签属性:v-bindv-bind:href='url':href='url' // 简写模式
简介:详解vue中的双向数据绑定
单项数据绑定
特点:只能从data流向页面
实现
xxxxxxxxxx// 通过v-bind实现单项数据绑定<input type="text" :value="name" />
双向数据绑定
特点:不仅可以从data流向页面,也能从页面表单元素(输入元素)流向data
实现
xxxxxxxxxx// 通过v-model实现双项数据绑定<input type="text" v-model:value="name" /><input type="text" v-model="name" /> // 简写
简介:详解MVVM模型在Vue中的使用

简介:详解Vue中的数据代理
原理( Object.defineProperty() )
通过一个对象代理另一个对象属性的读写
xxxxxxxxxxObject.defineProperty('目标对象', '代理属性', { get() { // getter 当读取’目标对象‘的’代理属性‘时,get函数/getter就会被调用,且返回代理属性的值 return xxx; }, set(value) { // setter 当修改’目标对象‘的’代理属性‘时,set函数/setter就会被调用,且收到修改的值 xxx; },});xxxxxxxxxxlet obj1 = { a: 111,};let obj2 = { b: 222,};Object.defineProperty(obj2, 'a', { get() { console.log('obj2被读取了'); return obj1.a; }, set(value) { console.log('obj2被修改了'); obj1.a = value; },});Vue中应用的数据代理

Object.defineProperty()把 data 中的属性添加到vm对象上,每个属性都有setter/getter
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:详解Vue中的事件处理和常用的事件修饰符
事件绑定指令:v-on
xxxxxxxxxx<button v-on:click="showMessge">点击</button>// 简写<button @click="showMessge">点击</button>事件传参
xxxxxxxxxx<button @click="showMessge('小滴课堂')">点击</button>methods: { showMessge(text) { console.log(text); },},注意
常用事件修饰符
阻止默认事件
xxxxxxxxxx// js中的阻止默认事件e.preventDefault()// vue@click.prevent="showMessge"阻止事件冒泡
xxxxxxxxxx// js中的阻止事件冒泡e.stopPropagation()// vue@click.stop="showMessge"// 阻止冒泡、默认事件连用@click.stop.prevent="showMessge"只触发一次事件
xxxxxxxxxx@click.once="showMessge"键盘事件
xxxxxxxxxx@keyup.enter="showMessge"
简介:详解Vue中的计算属性
计算属性
定义
通过已有的属性计算而来
写法
读取/更改
xxxxxxxxxxfullName: { get() { return this.firstName + '-' + this.lastName; }, set(value) { this.firstName = value.split('-')[0]; this.lastName = value.split('-')[1]; },},读取简写
xxxxxxxxxxcomputed: { fullName() { return this.firstName + '-' + this.lastName; },}// 注意:只有当只读时可以简写,有修改需求时不能使用简写原理
通过Object.defineProperty实现
插值语法使用computed里的属性不加()
通过methods实现
xxxxxxxxxxmethods: { fullName() { return this.firstName + '-' + this.lastName; },}计算属性优点
简介:详解Vue中的监视属性
监视属性
xxxxxxxxxxwatch: { isSunny: { immediate:true, // 开启初始化调用 deep:true, // 开启深度监视 handler() { this.plan = this.isSunny ? '打蓝球' : '敲代码'; }, },}被监视的属性发生改变时,调用回调函数,执行相关操作
配置immediate:true实现初始化调用
监视的属性须存在才能进行监视
深度监视
deep:true可以监测多维数据,根据具体数据结构决定是否采用深度监视
简写
xxxxxxxxxxwatch: { isSunny() { this.plan = this.isSunny ? '打球' : '敲代码'; },}// 注意vue所管理的函数都应写成普通函数,不被vue管理的(定时器,ajax回调函数,promise回调函数)最好写成箭头函数
简介:详解计算属性和监视属性异同
通过监视属性实现姓名拼接
xxxxxxxxxx watch: { firstName: function (val) { this.fullName = val + '-' + this.lastName; }, lastName: function (val) { this.fullName = this.frstName + '-' + val; },}异同

简介:Vue中class样式的绑定
字符串写法
使用场景
写法
xxxxxxxxxx<div :class="xd_bg">小滴课堂</div>手动触发样式改变
注意
字符串使用的是vue实例data中的已有属性
对象写法
使用场景
对象写在内联样式
xxxxxxxxxx<div :class="{bg_red:bg_red,border:border}">小滴课堂</div>对象写在data中
xxxxxxxxxx<div :class="list">小滴课堂</div>data: { list: { bg_red: 'bg_red', border: 'border', },}
数组写法
使用场景
内联写法
xxxxxxxxxx <div :class="[xd_border,xd_bg]">小滴课堂</div>数组里加三元表达式
xxxxxxxxxx<div :class="[isActive?xd_border:'',xd_bg]">小滴课堂</div> 写在data中
xxxxxxxxxx <div :class="list">小滴课堂</div>data:{ list:['border', 'bg_red']}

简介:Vue中style样式的动态绑定
style写法
xxxxxxxxxx <div :style="{fontSize:'30px',color:aa}">小滴课堂</div>
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:详解Vue中的条件渲染
v-if
xxxxxxxxxx<p v-if="dice===1">打篮球</p><p v-else-if="dice===2">敲代码</p><p v-else-if="dice===3">游泳</p><p v-else>约会</p>data: { dice: '',},methods: { throwFun() { this.dice = Math.floor(Math.random() * 4); console.log(this.dice); },},特点
语法和原生js的if...else if...else一样
不展示时直接移除DOM元素,适合切换频率低的场景
v-if、v-else-if、v-else要连用
v-show
写法
xxxxxxxxxx<p v-show="dice===1">约会</p>特点
不展示时使用样式隐藏,适合切换频率高的场景
v-if vs v-show
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
简介:详解Vue中的列表渲染
v-for
定义
v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名遍历数组
写法
xxxxxxxxxx<li v-for="(item,index) in list">{{item.name}}-{{index}}</li>xxxxxxxxxxnew Vue({ el: '#app', data: { list: [{ name: '张三' }, { name: '李四' }, { name: '王五' }], },});
第二个参数
xxxxxxxxxx<li v-for="(item,index) in list">{{item.name}}-{{index}}</li>也可以用 of 替代 in
xxxxxxxxxx<li v-for="(item,index) of list">{{item.name}}-{{index}}</li>
遍历对象
写法
xxxxxxxxxx<li v-for="value in obj">{{value}}</li>xxxxxxxxxxnew Vue({ el: '#app', data: { obj: { name: '张三', age: '18', sex: '男' }, },});第二个参数(键名)
xxxxxxxxxx<li v-for="(name,value) in obj">{{name}}:{{value}}</li>第三个参数(索引)
xxxxxxxxxx<li v-for="(name,value,index) in obj">{{index}}:{{name}}:{{value}}</li>
简介:维护状态key的作用和原理
节点
xxxxxxxxxx<div> <h1>小滴课堂</h1> xdclass.net <!-- 有很多的it教程 --></div>当浏览器读到这些代码时,它会建立一个 DOM 节点树来保持追踪所有内容,如同你会画一张家谱图来追踪家庭成员的发展一样
上述 HTML 对应的 DOM 节点树如下图所示:

旧:
新: 
旧:
新:
key定义
key写法
xxxxxxxxxx<li v-for="(item,index) in obj" :key="item.id">{{item.name}}</li>xxxxxxxxxxnew Vue({ el: '#app', data: { obj: [ { name: '张三', id: '1' }, { name: '李四', id: '2' }, { name: '王五', id: '3' }, ], },});作用
key值使用数组的索引index,或者不加,在数组元素顺序打乱时,会产生不必要的DOM更新以及界面效果出问题
key主要用在 Vue 虚拟 DOM(类似 js 对象格式的数据) 的 Diff 算法,新旧虚拟 DOM 对比,复用不变的旧节点,渲染改变的节点,提高渲染速度

简介:详解Vue中列表过滤
列表过滤

xxxxxxxxxx<input type="text" v-model="inputValue" /><ul> <li v-for="item in newList">{{item.name}}-{{item.price}}</li></ul>xxxxxxxxxxnew Vue({ el: '#app', data: { inputValue: '', list: [ { name: '牛仔裤', price: '88元' }, { name: '运动裤', price: '67元' }, { name: '羽绒服', price: '128元' }, { name: '运动服', price: '100元' }, ], }, computed: { newList() { return this.list.filter((i) => { return i.name.indexOf(this.inputValue) !== -1; }); }, },});
简介:Vue中列表排序
列表排序
对商品列表进行排序

xxxxxxxxxx<input type="text" v-model="inputValue" /><button @click="keyWord=1">降序</button><button @click="keyWord=2">升序</button><button @click="keyWord=0">原顺序</button><ul> <li v-for="item in newList">{{item.name}}-{{item.price}}</li></ul>xxxxxxxxxxnew Vue({ el: '#app', data: { keyWord: 0, inputValue: '', list: [ { name: '牛仔裤', price: 88 }, { name: '运动裤', price: 67 }, { name: '羽绒服', price: 128 }, { name: '运动服', price: 100 }, ], }, computed: { newList() { const arr1 = this.list.filter((i) => { return i.name.indexOf(this.inputValue) !== -1; }); if (this.keyWord) { arr1.sort((a1, a2) => { return this.keyWord === 1 ? a1.price - a2.price : a2.price - a1.price; }); } return arr1; }, },});
简介:详解Vue中数组数据的更新问题

对象新增数据更新问题
描述
通过普通对象添加属性方法,Vue不能监测到且不是响应式
xxxxxxxxxxthis.obj.name= '小滴课堂'解决
Vue.set() / this.$set
xxxxxxxxxxthis.$set(this.obj,'name','小滴课堂')注意
this.$set不能给vue实例的根数据对象添加属性
简介:详解Vue中数组数据的更新问题
数组数据更新问题
描述
直接通过数组索引值改变数组的数据,Vue监测不到改变
实际在 js 内存已经把数据的第一项数据修改了
xxxxxxxxxxthis.list[0] = { name: '李四',age: 20 };原因
解决
Vue在数组的原始操作方法上包裹了重新解析模板的方法,
也就是说我们在data里面的数组操作方法不是原生的,是vue封装过的
哪些数组操作方法经过了封装?
xxxxxxxxxxpush() pop()shift()unshift()splice()sort()reverse()
简介:详解表单数据的绑定
表单形式

代码
xxxxxxxxxx<form @submit.prevent="submit"> 账号:<input type="text" v-model="userInfo.userName" /> <br /><br /> 密码:<input type="password" v-model="userInfo.password" /> <br /><br /> 手机号码:<input type="number" v-model.number="userInfo.phone" /> <br /><br /> 性别: 男 <input type="radio" v-model="userInfo.sex" name="sex" value="male" /> 女 <input type="radio" v-model="userInfo.sex" name="sex" value="female" /> <br /><br /> 方向: 前端 <input type="checkbox" value="front" v-model="userInfo.direction" /> 后端<input type="checkbox" value="back" v-model="userInfo.direction" /> 测试 <input type="checkbox" value="test" v-model="userInfo.direction" /> <br /><br /> 地区: <select v-model="userInfo.city"> <option value="">请选择地区</option> <option value="beijing">北京</option> <option value="shanghai">上海</option> <option value="guangzhou">广州</option> <option value="shenzhen">深圳</option> </select> <br /><br /> 备注: <textarea v-model="userInfo.remarks"></textarea> <br /><br /> <input type="checkbox" v-model="userInfo.agree" />请阅读接受 <a href="https://xdclass.net">《用户协议》</a> <br /><br /> <button>提交</button></form>xxxxxxxxxxnew Vue({ el: '#app', data: { userInfo: { username: '', password: '', phone: '', sex: 'male', direction: [], city: '', remarks: '', agree: true, }, }, methods: { submit() { console.log(this.userInfo); }, },});
简介:详解Vue指令v-text/v-html
已学过的指令
xxxxxxxxxxv-bind // 单向数据绑定v-model // 双向数据绑定v-on // 事件监听绑定v-show // 条件渲染v-if // 条件渲染v-else // 条件渲染v-for // 遍历数组、对象、字符串v-text
写法
xxxxxxxxxx<p v-text="name"></p>xxxxxxxxxxnew Vue({ el: '#app', data: { name: '小滴课堂', },});特点
v-html
写法
xxxxxxxxxx<p v-html="str"></p>xxxxxxxxxxnew Vue({ el: '#app', data: { str: '<h1>小滴课堂</h1>', },});特点
注意
v-html,不要在用户提交的内容上。
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:认识vue中的生命周期函数
透明度自动变化的小案例
xxxxxxxxxx<div id="app"> <div :style="{opacity }">小滴课堂</div></div>xxxxxxxxxxconst vm = new Vue({ el: '#app', data: { opacity: 1, },});setInterval(() => { vm.opacity -= 0.05; if (vm.opacity <= 0) { vm.opacity = 1; }}, 60);Mounted
生命周期
this指向为vue实例,名字不能更改
简介:详解vue中的生命周期流程
Vue的初始化流程

beforeCreate阶段
vue中data的数据和methods的方法还不能使用
created阶段
beforeMount阶段
mounted
简介:详解vue中的生命周期更新流程
Vue的更新流程

beforeUpdate
Updated
简介:详解vue中的生命周期销毁流程
Vue的销毁流程

beforeDestroy
destroy
一切都结束了
简介:回顾总结Vue的生命周期流程
生命周期函数
常用的生命周期函数
mounted
beforeDestroy
vue实例销毁

愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:详解初始化创建Vue脚手架
定义
起步
使用淘宝镜像源安装
xxxxxxxxxxnpm install -g cnpm --registry=https://registry.npm.taobao.org全局安装Vue CLI(仅第一次安装需要执行)
xxxxxxxxxxcnpm install -g @vue/cli进入到要创建项目的文件夹
xxxxxxxxxxvue create xxx
启动项目
xxxxxxxxxxnpm run serve
简介:详解Vue脚手架结构信息

node_modules
public
src
.gitignore
babel.config.js
package-lock.json
package.json
README.md
简介:详解vue初始项目文件
vue初始项目文件
执行启动命令后的文件执行
main.js
App.vue
简介:详解Vue的配置文件修改
配置文件
查看vue脚手架的默认配置(修改不奏效)
xxxxxxxxxxvue inspect > output.js
对脚手架进行设置
新建 vue.config.js 文件设置
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:详解Vue组件化编程
图解
在使用 js 框架之前的代码管理

在使用 vue 框架之后的代码管理

没使用组件思想构建项目的缺点
代码关系混乱,不好维护
代码复用率不高
模块
定义
js 文件,提取公共或逻辑复杂的 js 代码作用
js 代码、提高代码的复用率 模块化
js 都用模块来编写,那这个项目就是模块化的组件
定义
组件化

简介:详解组件的全局注册与局部注册
全局注册
Vue.component
xxxxxxxxxxVue.component('button-counter', { data() { return { count: 0, }; }, template: '<button v-on:click="count++">点击了 {{ count }} 次</button>',});组件名的两中写法
xxxxxxxxxxbutton-counter xxxxxxxxxxButtonCounter //此写法直接在DOM引用时,只有button-counter才能生效组件的复用
data必须是个函数
不写el选项(实现组件可复用,一个项目中所有的组件最终都由一个vm实例管理)

局部注册
Vue.extend
xxxxxxxxxxconst xd = Vue.extend({ data() { return { count: 0, }; }, template: '<button v-on:click="count++">点击了 {{ count }} 次</button>',});xxxxxxxxxxnew Vue({ el: '#app', data: { name: '小滴课堂', }, components: { xd, },});
组件的嵌套
简介:深入理解单文件组件
单文件组件
结构
xxxxxxxxxx<template> <div></div></template>
交互
xxxxxxxxxx<script>export default { data() { return { name: '你好,小滴课堂' }; },};</script>
样式
xxxxxxxxxx<style>div { color: red;}</style>
简介:深入理解父子组件的传值
父向子传值
props
只接收
xxxxxxxxxxprops: ["xd"]限制类型
xxxxxxxxxxprops: { xd: String } 限制类型,限制必要性,限制默认值d
xxxxxxxxxxprops: { xd: { type: String, required: true, default:'你好', },},
注意
简介:深入理解父子组件的传值
子向父传值
props 传给子组件事件回调传值
自定义事件(@绑定)
xxxxxxxxxx// 父组件<xd-home @myXd="dianji" />xxxxxxxxxx// 子组件dianji_xd() { this.$emit("myXd", this.name);},
自定义事件(ref绑定:灵活,延时效果)
xxxxxxxxxx// 父组件<xd-home ref="child" /> mounted() { this.$refs.child.$on("myXd", this.dianji); //this.dianji在methods声明或者用箭头函数},xxxxxxxxxx// 子组件methods: { dianji_xd() { this.$emit("myXd", this.name); },},自定义事件的解绑
xxxxxxxxxxthis.$off()
简介:详解非父子组件间的通讯
兄弟组件的数据操作
任意组件的事件
安装全局事件总线
xxxxxxxxxxnew Vue({ beforeCreate(){ Vue.prototype.$bus = this } })在需要接收数据的组件绑定自定义事件
xxxxxxxxxxmethods:{ xd(i){ console.log(i) }}mounted(){ this.$bus.$on('xx',this.xd)}提供数据的组件
xxxxxxxxxxthis.$bus.$emit('xx',数据)
解绑
xxxxxxxxxxbeforeDestroy() { this.$bus.$off();},

简介:详解Vue中的插槽
默认插槽
定义
写法
父组件
xxxxxxxxxx<soltComponent> <span>小滴课堂</span></soltComponent>子组件
xxxxxxxxxx<template> <div> <h1></h1> <p> <slot></slot> </p> </div></template>
具名插槽
定义
写法
父组件
xxxxxxxxxx<soltComponent> <template v-slot:title> <span>小滴课堂</span> </template> <template v-slot:website> <span>xdclass.net</span> </template></soltComponent>子组件
xxxxxxxxxx<template> <div> <h1> <slot name="title"></slot> </h1> <p> <slot name="website"></slot> </p> </div></template>注意
v-slot:title只能写在 template 标签以及组件上,
可以写成 slot='title' 但是此用法在vue3被弃用
作用域插槽
定义
写法
父组件
xxxxxxxxxx<soltComponent> <template v-slot="{ list }"> <li v-for="(i, index) in list" :key="index"></li> </template></soltComponent>子组件
xxxxxxxxxx<template> <div> <slot :list="list"></slot> </div></template>
简介:详解混入实现复用功能
混入
定义
写法
局部混入
定义个混入对象
xxxxxxxxxx// mixin.jsexport const myMixin = { data() { return { xd: '小滴课堂', }; }, mounted() { console.log('hello from xdclass.net'); },};
引用使用
xxxxxxxxxx// 需要混入的组件import { myMixin } from "../mixin";mixins: [myMixin],全局混入
定义个混入对象
引入使用
xxxxxxxxxx// main.jsimport { myMixin } from "./mixin";Vue.mixin(myMixin);
注意
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:深入理解路由的概念

定义
路由(route)就是一组映射关系: key-value ,key 为路径,value 为 component 组件 ,由 router 管理
结合生活中的路由
LAN 代表 路径,通过网线与LAN连接的 电脑 代表 组件
工作流程
当 router 检测到路径发生改变时,就会将当前页面替换成对应的组件
简介:玩转路由的基本使用
效果展示
路由的使用
安装
xxxxxxxxxxnpm i vue-router创建路由器文件
xxxxxxxxxx// router/index.jsimport VueRouter from 'vue-router';import Home from '../components/Home';import Course from '../components/Course';export default new VueRouter({ routes: [ { path: '/home', component: Home, }, { path: '/course', component: Course, }, ],});引入应用
xxxxxxxxxx// main.js// 引入import VueRouter from 'vue-router';import router from './router/index';Vue.use(VueRouter)new Vue({ el: '#app', render: (h) => h(App), router: router,});切换
xxxxxxxxxx<router-link active-class='active' to='/home'>首页<router-link>展示
xxxxxxxxxx<router-view></router-view>
简介:深度剖析路由的嵌套
路由的嵌套
配置
xxxxxxxxxx{ path: '/course', component: Course, children: [ { path: '/front', component: Front, }, { path: '/back', component: Back, }, ],},跳转
xxxxxxxxxx<router-link active-class='active' to='/course/front'>前端<router-link>
路由组件
由路由控制的组件
新建 pages 文件夹存放路由组件
切换之后的组件去哪了
简介:实现路由的传参上
query 传参
字符串
xxxxxxxxxx<router-link :to="`/course/front?text=${text}`" active-class="active"> 前端</router-link>对象
xxxxxxxxxx<router-link :to="{ path: '/course/front', query: { text: text } }" active-class="active"> 前端</router-link>获取
xxxxxxxxxxthis.$route.query.text
简介:实现路由的传参下
params 传参
路由器声明 params 传参
xxxxxxxxxx{ name: 'qianduan', path: 'front/:text', //字符串形式传参时需加占位符告知路由器,此时是参数 component: Front,},字符串
xxxxxxxxxx<router-link :to="`/course/front/${text}`" active-class="active"> 前端</router-link>对象
xxxxxxxxxx<router-link :to="{ name: 'qianduan', params: { text: text } }" active-class="active"> 前端</router-link>获取
xxxxxxxxxxthis.$route.params.text
注意
path 对应的是 query 属性,name 对应的是 params 属性
replace
删除路由之前的历史记录
xxxxxxxxxx<router-link replace to="/course/back" active-class="active"> 后端</router-link>
简介:深度剖析编程式路由导航
为什么要用编程式导航
编程式导航
push 写法
xxxxxxxxxxtoFront() { this.$router.push({ name: "qianduan", params: { text: this.text, }, });},replace 写法
xxxxxxxxxxtoFront() { this.$router.replace({ name: "qianduan", params: { text: this.text, }, });},路由的前进后退
xxxxxxxxxxthis.$router.forward() //前进this.$router.back() //后退this.$router.go() //前进:正数1、2 或者后退:负数-1、-2
简介:深度剖析路由缓存和全局前置路由
路由缓存
效果展示
定义
让不展示的路由组件保持挂载在页面,不被销毁
写法
xxxxxxxxxx//注意 Front 是组件的名字<keep-alive include="Front"> <router-view></router-view></keep-alive>
全局前置路由
作用
对路由组件进行权限控制
配置
xxxxxxxxxx{ path: 'front', component: Front, meta: { isAuth: true },},{ path: 'back', component: Back, meta: { isAuth: true },},xxxxxxxxxxrouter.beforeEach((to, from, next) => { if (to.meta.isAuth) { if (localStorage.getItem('isShow' === '1')) { next(); } else { alert('暂无权限观看'); } } else { next(); }});
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:状态管理模式Vuex的简介
Vuex
定义
作用
特点
<<<<<<==========>>>>>> 
简介:上手搭建Vuex运行环境
配置
安装
xxxxxxxxxxcnpm install vuex创建 /store/index.js 文件
xxxxxxxxxx// 创建 /store/index.js 文件import Vue from 'vue' //引入Vueimport Vuex from 'vuex' //引入VuexVue.use(Vuex) //应用export default new Vuex.Store({ actions:{}, //接受用户的事件 mutations:{}, //操作state中的数据 state:{}, //存放共享的数据})xxxxxxxxxx// main.jsimport store from './store/index.js'new Vue({ el:"#app", render: h => h(App), store:store})
简介:Vuex实现一个小案例
实现对 store 数据的 count 累加和累减
读取 store 的state
xxxxxxxxxx<h1>当前的计数:{{ $store.state.count }}</h1>操作 store 的state
xxxxxxxxxxmethods: {// 累加 add() { this.$store.commit("ADD", this.sum); //同步操作 // this.$store.dispatch("add", this.sum); //异步操作 },// 累减 reduce() { this.$store.commit("REDUCE", this.sum); //同步操作 // this.$store.dispatch("reduce", this.sum); //异步操作 },},store 配置 actions 和 mutations
xxxxxxxxxx//接受用户的事件actions: { add(context, value) { context.commit('ADD', value); }, reduce(context, value) { setTimeout(() => { context.commit('REDUCE', value); }, 1000); },},//操作state中的数据mutations: { ADD(state, value) { state.count += value; }, REDUCE(state, value) { state.count -= value; },},注意
actions 能够提供 dispatch 方法实现异步操作mutations 必须是同步函数state 只能通过 mutations 配置的方法去修改
简介:Vuex实现多组件的数据通讯
增加课程列表组件
读取 store 的state中 count 和 list
xxxxxxxxxx<ul> <li v-for="(i, index) in list" :key="index">{{ i.name }}</li></ul><button @click="xiajia">下架</button><h1> 当前计数为:<span>{{ count }}</span></h1>xxxxxxxxxxcomputed: { count() { return this.$store.state.count; }, list() { return this.$store.state.list; },},
操作 store 的state
xxxxxxxxxxmethods: { xiajia() { this.$store.commit("XIAJIA"); },},
简介: 详解store 的计算属性—getters
getters
定义
store 中 state 数据进行加工配置
xxxxxxxxxxgetters: { changeCount(state) { return state.count * 2; },},读取
xxxxxxxxxxthis.$store.getters.changeCount;
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:认识Vue3和项目搭建
Vue3优点
TypeScriptComposition API 和内置组件
搭建Vue3项目
vue-cli创建
保持跟课程脚手架版本一致4.5.17,防止引用插件出现兼容问题
xxxxxxxxxxnpm install -g @vue/cli@4.5.17查看版本,不一致时重新安装
xxxxxxxxxxvue -V //查看版本全局卸载重装npm uninstall -g vue-clinpm install -g @vue/cli@4.5.17创建项目
xxxxxxxxxxvue create vue_project进入项目目录启动
xxxxxxxxxxnpm run serve
简介:项目工程文件介绍与Devtools安装
项目文件
入口文件 main.js
使用 createApp 解析模板,更加小巧
xxxxxxxxxximport { createApp } from 'vue'import App from './App.vue'createApp(App).mount('#app')
组件 <template> 标签里可以插入多个根标签
Devtools 安装
Devtools 在Vue3项目中不生效
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net

简介:走进Vue3的世界—setup
setup
setup 函数是Vue3新的配置项
是使用组合API的前提,数据、方法都要放到setup 函数里声明
写法
xxxxxxxxxxsetup() { const name = "张三"; const age = 18; function sayHello() { alert("你好,我是${name},今年${age}岁了"); } return { name, age, sayHello, };},
简介:实现数据的响应式—ref函数
定义
基本类型数据
引入 ref 函数
xxxxxxxxxximport { ref } from "vue";创建一个包含响应式数据的引用对象( ref 对象)
xxxxxxxxxxlet name = ref("张三");let age = ref(18);操作数据
xxxxxxxxxxfunction changePerson() { name.value = "李四"; age.value = "19";}
对象类型数据
创建一个包含响应式数据的引用对象( ref 对象)
xxxxxxxxxxlet obj = ref({ xd: "小滴课堂", course: "vue3",});操作数据
xxxxxxxxxxfunction changeCourse() { obj.value.course = "react";}注意
Object.defineProperty() 实现Proxy 实现
简介:实现数据的响应式—reactive函数
定义
对象类型的响应式数据(不能处理基本类型数据)写法
对象
xxxxxxxxxx// 定义let obj = reactive({ xd: "小滴课堂", course: "vue3",});// 修改obj.course = "node";数组
xxxxxxxxxx// 定义let list = reactive(["吃饭", "睡觉", "敲代码"]);// 修改list[3] = "打游戏"
reactive 和 ref 不同点
ref 可以处理基本类型和对象(数组)类型数据,reactive 只能处理对象(数组)类型数据ref 处理基本类型数据通过 Object.defineProperty() 实现,reactive 通过 Proxy 实现ref 操作数据需要加 .value
组件数据多时更加趋向使用 reactive
简介:详解setup函数的两个参数
执行时机
beforeCreate 之前执行一次,而且 setup 函数没有 this
两个参数
props
第一个参数接收父组件的值,是一个对象
xxxxxxxxxxexport default { props: ["mess"], //需要props声明才能在setup收到参数 setup(props) { console.log(props.mess); },};
context
上下文对象
触发自定义事件
xxxxxxxxxxexport default { emits: ["xd"], //需要emits声明才能在setup中使用 setup(props, context) { function clickMe() { context.emit("xd", "子组件的值"); } return { clickMe, }; },};
简介:详解computed函数
定义
使用
计算 ref 定义的响应式数据
xxxxxxxxxxconst fullName = computed({ get() { return firstName.value + "-" + lastName.value; }, set(value) { const arr = value.split("-"); firstName.value = arr[0]; lastName.value = arr[1]; },});
计算 定义的响应式数据
xxxxxxxxxxperson.fullName = computed({ get() { return person.firstName + "-" + person.lastName; }, set(value) { const arr = value.split("-"); person.firstName = arr[0]; person.lastName = arr[1]; },});
简介:详解watch函数
定义
监听 ref 定义的数据
基本类型
xxxxxxxxxx// 监听一个ref定义的数据watch(num, (newValue, oldValue) => { console.log("num增加了", newValue, oldValue);},{ immediate: true, deep: true });// 监听多个ref定义的数据watch([num, num1], (newValue, oldValue) => { console.log("num增加了", newValue, oldValue);});
简介:详解watch函数
监听 reactive 定义的数据
使用
监听对象类型
xxxxxxxxxxwatch(numObj, (newValue, oldValue) => { console.log("numObj变化了", newValue, oldValue);});
监听对象中的一个基本类型属性
xxxxxxxxxxwatch( () => numObj.a, (newValue, oldValue) => { console.log("numObj变化了", newValue, oldValue); });
监听对象中的一些基本类型属性
xxxxxxxxxxwatch([() => numObj.a, () => numObj.b], (newValue, oldValue) => { console.log("numObj变化了", newValue, oldValue);});
监听对象中的对象类型属性
xxxxxxxxxxwatch( numObj.c, (newValue, oldValue) => { console.log("numObj.c变化了", newValue, oldValue); });
总结
实现监听生效
ref 定义的数据
.value(用的少)reactive 定义的数据
注意
如果监听 reactive 定义的对象,则无法正确输出 oldValue ,且深度监听是强制开启的,无法关闭 (vue3配置)
简介:详解watchEffect函数
定义
写法
xxxxxxxxxxwatchEffect(() => { let xd = numa.value; let xd1 = numb.value; console.log("watchEffect函数执行了");});与 watch 的区别
属性监听区别:
watch 手动添加定向的监听属性watchEffect 自动监听使用到的属性初始化执行:
watchEffect 会初始化执行一次建议开发中使用 watch 监听,逻辑简单、依赖属性少的场景可以使用 watchEffect
简介:详解Vue3中的生命周期函数
创建
xxxxxxxxxx创建前、后:beforeCreate、created
xxxxxxxxxx创建:setup
挂载
xxxxxxxxxx挂载前、后:beforeMount、mounted
xxxxxxxxxx挂载:onBeforeMount、onMounted
更新
xxxxxxxxxx更新前、后(beforeUpdate、updated)
xxxxxxxxxx更新:onBeforeUpdate、onUpdated
卸载
xxxxxxxxxx销毁前、后:beforeDestroy、destroyed
xxxxxxxxxx卸载:onBeforeUnmount、onUnmounted
简介:详解Vue3中的toRef和toRefs
toRef
定义
ref 对象,其 value 值指向另一个对象中指定的属性写法
xxxxxxxxxxconst name = toRef(person, "name");作用
toRefs
定义
ref 对象,其 value 值指向另一个对象中指定的属性写法
xxxxxxxxxxsetup() { let person = reactive({ name: "张三", age: 19, }); return { toRefs(person), };},作用
简介:详解provide和inject
作用
写法
祖组件使用 provide 提供数据
xxxxxxxxxxlet name = ref("小滴课堂");provide("xd", name);
后代组件使用 inject 使用数据
xxxxxxxxxxconst message = inject("xd");
愿景:"让编程不再难学,让技术与生活更加有趣"
更多课程请访问 xdclass.net
简介:详解需求分析
需要开发的页面
主要功能点
简介:项目搭建初始化配置
rem 适配
安装
xxxxxxxxxxcnpm install postcss-pxtorem@5.1.1 amfe-flexible -S文件配置
xxxxxxxxxx// vue.config.jsmodule.exports = { css: { loaderOptions: { postcss: { plugins: [ require('postcss-pxtorem')({ rootValue: 16 , propList: ['*']}), ], }, }, },};引入
xxxxxxxxxx// main.jsimport 'amfe-flexible';
less 预处理器
安装
xxxxxxxxxxcnpm i less less-loader@7 -S
vant 组件库的引入
安装
xxxxxxxxxxcnpm i vant@next -Scnpm i babel-plugin-import -S引入
xxxxxxxxxx// main.jsimport { Button } from 'vant';app.use(Button)样式按需引入
xxxxxxxxxx// babel.config.jsplugins: [ [ 'import', { libraryName: 'vant', libraryDirectory: 'es', style: true, }, 'vant', ],],使用
xxxxxxxxxx<van-button type="primary">主要按钮</van-button>
阿里巴巴矢量库引入
引入
xxxxxxxxxx// index.html<script src="http://at.alicdn.com/t/font_2701887_5roykhspg1e.js"></script>使用
xxxxxxxxxx<svg class="icon" aria-hidden="true"> <use xlink:href="#icon-xxx"></use></svg>
报错
错误
xxxxxxxxxxsockjs.js:1609 GET http://192.168.0.120:8080/sockjs-node/info?t=164267043253
解决
xxxxxxxxxxcnpm install -g webpack webpack-cli webpack-dev-server
简介:详解路由配置
代码提交远程仓库
连接
xxxxxxxxxxgit remote add origin https://gitee.com/wen_zhao/xdclass.git将本地仓库push远程仓库
xxxxxxxxxxgit pull origin master --allow-unrelated-histories覆盖远程仓库
xxxxxxxxxxgit push -f origin master
项目路由配置
安装
xxxxxxxxxxcnpm i vue-router@4 -S新建路由配置文件
xxxxxxxxxx// router/index.jsimport { createRouter, createWebHashHistory } from 'vue-router';const router = createRouter({ history: createWebHashHistory(), routes: [ { path: '/', redirect: '/home', }, { path: '/home', component: () => import('../pages/MyHome'), }, { path: '/cart', component: () => import('../pages/MyCart'), }, { path: '/me', component: () => import('../pages/MyMessage'), }, { path: '/order', component: () => import('../pages/MyOrder'), }, ],});export default router;引入
xxxxxxxxxx// main.jsimport router from './router/index';const app = createApp(App);app.use(router);app.mount('#app');
简介:详解路由配置
使用
xxxxxxxxxx// App.vue<router-view></router-view>xxxxxxxxxx// Footer.vue<div><router-link to="/home">首页</router-link></div><div><router-link to="/cart">购物车</router-link></div><div><router-link to="/order">订单</router-link></div><div><router-link to="/mine">我的</router-link></div>
简介:详解首页开发

简介:详解首页开发

简介:详解店铺开发

tabs 切换
简介:详解店铺开发

简介:详解店铺开发

简介:详解店铺开发

简介:详解购物车开发

简介:详解购物车开发

简介:详解购物车开发

简介:详解购物车开发

简介:详解生成订单开发

简介:详解生成订单开发

简介:详解订单页面开发

简介:详解地址管理开发

简介:详解地址管理开发

简介:详解个人中心页面开发

简介:详解注册登录开发

简介:详解注册登录开发

简介:详解账号管理开发

简介:axios请求数据动态展示
安装
xxxxxxxxxxcnpm i axios -S定义接口
xxxxxxxxxx// api.js;import axios from './request';export const getHomeData = () => axios.get('/mock/home.json');