学习Vue这一个就够

1、淘宝镜像

 1: 解释一下 npm 为什么要配置淘宝镜像原因:因为node.js 默认使用的是国外的网站 。国内访问有一个跨国内局域网的操作。所以就会有时候很慢。这就跟为什么网站的静态资源有些会使用CDN 加速一样的淘宝镜像是什么?就是npm 很多的插件淘宝已经下载好了放在公共的网站上 我们需要的时候去淘宝网上下载 和 国外的是一样  这样使用是提升了我们的下载速度。所以淘宝镜像其实是一个国外插件的 国内版本2:安装命令npm config set registry https://registry.npm.taobao.org3:查看是否安装成功 npm info express4:使用命令 npm install -g cnpm --registry=https://registry.npm.taobao.orgcnpm install <插件名>

3、安装vue的调试工具

1、插件已经下载好,直接拖着往谷歌浏览器的扩展程序里面,记得是开发者模式(教学案例)

1、理解什么是Vue

0:官网https://cn.vuejs.org/guide/introduction.htmlhttps://cdn.jsdelivr.net/npm/vue@2  压缩版https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js  生产版
1、Vue.js是目前最火的框架,是前端的主流框架之一,和Angular。js和React.js
并称为三大主流框架
2、Vue.js是一套构建用户界面的框架,只关注图层,不仅易于上手,HIA方便与第三方库或既有项目整合(有配套的第三方类库,可以整合起来做大型项目的开发
3、使用vue往html页面中填充数据,非常的方便。框架都是现成的解决方案,按照框架的规范,去便携自己的业务功能
4、主要就是学习vue的指令、组件、路由、vuex
5、vue的特性:1、数据驱动视图2、双向数据绑定

2、如何学习Vue

1、能够使用Vue的指令完成页面结构的渲染
2、能够使用Vue的调试工具辅助Vue的开发
3、了解什么是过滤器和侦听器,能够在实际开发中解决问题
4、什么是计算属性以及计算属性的用法
5、axios的基本用法,使用axios发起ajax请求
6、vue-cli,脚手架的安装和使用,生成工程化的Vue项目
7、组件的注册与使用,掌握vue单文件组件的基本用法
8、组件的props自定义属性
9、解决组件样式冲突
10、学习组件的生命周期,掌握组件声明周期的执行顺序和应用场景
11、组件之间的通讯(数据共享),组件之间通讯的三种方式
12、学习ref应用DOM元素和组件实例,能够使用ref获取页面上的DOM、或组件的引用
13、$nxtTick的基本使用,能够知道$nxtTick的应用场景并合理的使用
14、学习动态组件的使用,能够使用keep-alive实现组件的缓存
15、自定义指令
16、学习ESLint的使用,能够了解ESLint的语法规则
17、学习使用(默认插槽、具名插槽、作用域插槽),能够使用插槽提高组件的复用性
18、学习路由的基本配置与使用,能够在项目中安装和配置路由
19、路由重定向
20、嵌套路由、动态路由
21、编程式导航、路由导航守卫,能够使用路由实现单页面程序的开发。使用导航收尾控制路由的访问权限
22、学习Vant,掌握Vant组件库的基本使用,知道如何封装axios请求模块

3、数据驱动视图

1、在vue的页面中,vue会监听数据的变化,从而自动重新渲染页面的结构页面结构<-vue(监听数据的变化,数据发生改变)<-页面发生变化好处:当页面数据发生变化时,页面会自动重新渲染,只需要管理好数据注意:数据驱动视图是单向的数据绑定总结:数据的变化会驱动视图自动更新,

3-1、数据代理

1、数据代理:通过一个对象代理另一个对象中属性的操作2、vue中采用数据代理Object.defineProperty中的setter和getter进行数据代理和数据的响应

3-2、VueComponent

1、整个项目只会有一个Vue实例对象vm,其他的都是VueComponent实例对象,2、VueComponent的实例对象,简称为vc,也称为组件实例对象,Vue的实例对象只有一个,称为vm3、VueComponent可以通过Vue.extend()方法创建个很多个vc。在项目里面的组件实例对象就是通过这种方式创建的。就是vc4、vm和vc很多东西都一样,但是vc可以有很多个,vm只能有一个,而且vm可以设置el指定渲染的容器,vc不行。

4、双向数据绑定

1、填写表单的时候,双向绑定可以在不操作DOM的前提下,自动把用户填写的内容同步到数据中。页面结构<->vue(监听数据的变化,数据发生改变)<->页面发生变化form表单负责采集数据,ajax负责提交数据用户不需要手动操作dom元素,来获取表单数据页面上表单采集的数据发生变化的时候,会被vue自动获取到,并更新到js数据中。

4-MVVM核心原理(数据驱动和双向绑定的原理)

1、MVVM是vue实现数据驱动视图和双向数据绑定的核心原理。MVVM指的   是Model、View、ViewModel,把每个页面都拆分成了这三个部分。Model表示当前页面渲染时所以来的数据源View表示当前页面所渲染的DOM解构ViewModel表示Vue的实例,是MVVM的核心。就是vue
2、ViewModel作为MVVM的核心,是把当前页面的数据源和页面的结构连接在了一起。view 《--(自动更新,监听DOM变化)--》ViewMOdel《---(监听数据变化,自动同步)--》Model当数据源发生变化是,会被ViewModel监听到,VM会根据最新的数据源自动更新页面的结构。当表单的值发生变化时,也会被VM监听到,VM会把变化过的最新的值自动同del数据源中

在这里插入图片描述

5、Vue的版本

1.0版本基本被淘汰,
2.x版本是目前企业级项目开发中的主流版本
3.x的与2020年-09发布,现在已经是默认版本了,但是还没有普遍使用
vue的作者:尤雨溪,是中国人开发的前端框架
react和angular都是外国人开发
比较简单

6、Vue的基本使用

1、导入vue.js的script脚本文件
2、在页面中声明一个将要被vue所控制的DOM区域
3、创建一个vue实例
4、实例里面选择渲染的区域,定义要渲染的数据变量,<!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><!-- 1、引入vue的js文件,有vue这个构造函数 --><script src="../lib/vue.js"></script>
</head><body><!-- div控制页面,需要被vue控制 --><!-- 数据渲染:插值语法,可以把数据渲染到页面 --><div id="app">{{username}}</div><script>// 2、创建一个vue实例对象const vm = new Vue({// 3、el属性是固定的写法,表示vm实例要控制页面上的// 哪一个区域,接收的值是一个选择器el:'#app',// data是数据,所有用到的边浪在data里面定义// 然后渲染到页面上去// 这里是对象形式data:{username:'xiaohong'}})</script></body></html>
el指向的选择器选择的div就是view视图区域,data指向的对象就是MOdel数据源,new Vue是构造函数,创造了一个vm实例对象,就是viewModel。

7、配置Chrome浏览器的vue-devtools

1、插件已经下载好。可以直接使用

8、Vue的指令和过滤器

1、指令是VUe为开发者提供的模板语法,辅助开发者渲染页面的基本结构
2、指令按照不同的用途,分为六大类1、内容渲染指令2、属性绑定指令3、事件绑定指令4、双向绑定指令5、条件渲染指令6、列表渲染指令

8-1、内容渲染指令

1、内容渲染指令用来辅助开发者渲染DOM元素的文本内容,常用的内容渲染指令有3个1、v-text:会覆盖元素内部原有的内容,实际开发用的不多2、{{}}:插值表达式,不会覆盖默认文本,解决v-text的问题,可以在括号里面加点空格,内容占位符,只能用在内容节点,不能用在元素的属性节点。还3、v-html:其他两种只能渲染纯文本内容,该指令能把包含html标签的字符串渲染为页面的html元素,
2、总结:v-html渲染html标签,v-text和{{}}渲染纯文本,但是v-text会覆盖原本的内容,用的最多的是{{}}<!-- 1、插值语法 --><!-- 纯文本 --><div>{{username}}你好</div><!-- 2、v-text --><div v-text="username"> 你好</div><!-- 3、v-html --><div v-html="username">你好</div><!-- 渲染html标签 --><div v-html="ht"></div>

8-2、属性绑定指令(v-bind)

1、插值表达式只能用在内容节点中,不能用在元素节点中
2、v-bind:  给元素的属性动态绑定属性值,可以省略v-bind,保留 :<input type="text" placeholder="{{info}}"><!-- 在这里就表示给默认值绑定info --><input type="text" v-bind:placeholder="info" ><img v-bind:src="photo" alt=""><!-- 简写方式:省略v-bind --><img :src="photo" alt="">
3、注意:如果要用v-bind进行字符拼接,记得给字符串加上''
4、v-bind里面是js语句,

使用javascript表达式

1、在vue提供的模板渲染语法中,除了支持简单的数据值之外,还可以可以进行javascript表达式的运算<!-- 内容绑定指令 --><!-- 1、加法 --><div>{{ num +6 }}</div><!-- 2、三元表达式 --><div>{{ 5 > 4 ? 6 : 10}}</div><!-- 3、字符串运算 --><div>{{str.split("").reverse().join("")}}</div><!-- 4、属性绑定指令 --><!-- 字符串拼接 --><div :id="'list-'+'h'"></div>

8-3、事件绑定指令

1、v-on事件绑定:为DOM元素绑定事件监听,语法格式 v-on:事件名称="事件函数的名字"<button v-on:click="add">按钮</button>
2、绑定事件并传参:绑定方法的时候可以加小括号,可以不加,如果要传递参数,就加小括号<div id="app"><div>{{ num }}</div><button v-on:click="add(5)">按我+5</button></div><script>const vm = new Vue({el: "#app",data:function(){return {num: 5,}},methods: {add(n){this.num+=n}},})</script>
3、v-on的简写形式:@语法格式  @事件名称="事件函数的名字"
4、其他事件把原生事件的on去掉kyeup click
5、如果没有传递参数,那么我们默认可以接收到一个事件对象:e
<!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><script src="../lib/vue.js"></script>
</head><body><div id="app"><button @click="add">按我输出事件对象</button></div><script>const vm = new Vue({el: "#app",data:function(){return {num: 5,}},methods: {add(e){console.log(e);}},})</script>
</body></html>
6、可以通过这个事件对象获取到绑定事件的元素,然后对该元素进行修改<div id="app">      <button @click="add">按我输出事件对象</button></div><script>const vm = new Vue({el: "#app",data:function(){return {num: 5,}},methods: {// 如果没有传递参数,那么我们默认可以接收到一个事件对象:e// 可以通过这个事件对象获取到绑定事件的元素,然后对该元素进行修改add(e){e.target.style.backgroundColor="red"e.target.style.fontSize="50px"}},})</script>
7、但是这样写太复杂了,所以vue给我们提供了一个内置变量:$event,就是原生的事件对象通过绑定函数的时候传递进去,函数就会接收到这个事件对象,固定写法<button @click="add(1,$event)">按我输出事件对象</button>
8、事件修饰符:阻止默认事件的发生以前:在函数里面写e.preventDefault()现在:在绑定事件的后面写 .prevent1、<a href="https://www.baidu.com" @click="run">阻止跳转</a><br>run(e){e.preventDefault();console.log("阻止成功");},2、<a href="https://www.baidu.com" @click.prevent="run">事件修饰符阻止跳转</a>jump(){console.log("阻止成功");}
9、因为调用e.preventDefault和e.stopPropagation是常见需求,所以vue提供了事件修饰符的概念,来帮助程序员更方便的对事件的触发进行控制。常见的5个事件修饰符如下:.prevent:阻止默认行为.stop:阻止事件冒泡.once:只触发一次.self:只有在触发对象是当前元素自身触发时触发事件处理函数.caputre:以捕获模式触发当前的事件处理函数
10、按键修饰符:在监听键盘事件的时候,我们经常需要判断详细的按键,可以为键盘相关的时间添加按键修饰符,例如:<!-- 在key表示是”enter的时候,调用 .--><input  type="text" @keyup.enter="ll($event)" > <!-- 在key表示是”esc"的时候,调用 .--><input  type="text" @keyup.esc="gg($event)" > 

8-4、双向绑定指令

1、vue提供了v-model双向数据绑定指令,快速获取表单的数据
2、双向绑定之后,vue的数据会随着表单的改变发生改变<input type="text" v-model="username"><div>{{username}}</div>
3、v-model指令只能和表单元素进行使用1、input输入框2、select3、textrea
4、为了方便对用户输入的内容进行处理,vue为v-model提供了3个修饰符.number:将用户的输入值转为数值类型<input type="text" v-model.number="n">+  <input type="text" v-model="s">={{n+s}}.trim:自动过滤用户的收尾空白字符<input type="text" v-model="search" @keyup.enter="ff"><input type="text" v-model.trim="search" @keyup.enter="ff">.lazy:在change时而非input时更新,在中间更新的时候不会改变,用的很少

8-5、条件渲染指令

1、条件渲染指令用来控制DOM的显示与隐藏。有两个条件渲染指令:v-ifv-show<!-- v-if控制是否显示:满足条件 --><span v-if="s==6">6</span><span v-if="s==5">5</span><br><br><!-- v-show控制是否显示 --><span v-show="s==6">6</span><span v-show="s==5">5</span>
2、v-if 是通过让元素下树,隐藏该元素。动态的添加或移除元素,而v-show是通过style样式的display来隐藏或显示元素,如果要频繁的切换元素的显示形态,用v-show更好,如果有些元素不需要被展示,那么就用v-if。
3、  在实际开发中,不用考虑性能问题,直接使用v-if
4、还有一个v-else-if、v-else指令,v-else-if必须个v-if搭配使用,不然不会被识别

插件

1、vue 3 sinppets:
2、vetur:
3、yyr

8-6、列表渲染指令

1、v-for:列表渲染指令,基于一个数组来循环渲染一个列表结构,v-for需要用到iteminitems形式的特殊语法items是循环的数组item是循环数组的每一项元素<li v-for="item in arr">{{item}}</li>arr:["xiao","hong","lan","ming"]
2、谁在循环就给谁加v-for。
3、v-for还支持一个可选的第二参数,即当前项的索引,语法格式为(item,index) in items.  <!-- 3、索引。(item,index) in items. --><ul><li v-for="(item,index) in arr2">索引{{index}}{{item.name}}</li></ul>4、官方建议,如果用到了v-for指令,那么一定要绑定一个 :key 属性,可以把index作为key值。必须是字符串或者数字类型,而且key值不允许重复,不然会报错,最好是把id值作为key值,因为key值要求具有唯一性<!-- 4、 :key属性 --><ul><li v-for="(item,index) in arr2" :key="index">索引{{index}}{{item.name}}</li></ul>
5、56-62跳过

9、过滤器

9-1、了解过滤器

1、过滤器(Filters):用于文本的格式化,可以用在两个地方,插值表达式和v-bind属性绑定,只能在vue3里面使用
2、过滤器应该被添加在javascript表达式的尾部,由管道符进行调用,管道符就是竖线 |
3、过滤器函数必须被定义在filters这个节点下面,这个节点对象和data平级,过滤器本质是一个函数,自己定义。过滤器中一定要有一个返回值。主要是为了进行文本的格式化,所以过滤器函数的传递的参数都是管道符前面那个值<span>{{ msg | capi }}</span>
<script>// 过滤器函数必须被定义在filters这个节点下面,// 这个节点对象和data平级,filters:{// 过滤器本质是一个函数,自己定义。过滤器中一定要有一个返回值capi(val){// 主要是为了进行文本的格式化//在进行文本的首字母大写return   val.charAt(0).toUpperCase()+val.slice(1);}},
</script>
4、注意点:1、要定义到filters节点下,本质是一个函数2、在过滤器函数中,一定要有return,也就是返回值

9-2、全局过滤器和私有过滤器

1、定义在vue中的filters是私有过滤器,只能在当前的vue实例中使用<body><div id="app"><span>{{ msg | capi }}</span></div><div id="app2"><span>//使用不了这个capi过滤器,因为是定义在vm里面的,属于私有过滤器{{ msg | capi }}</span></div><script>const vm = new Vue({el: '#app',data: {msg: "hello world",arr: []},// 过滤器函数必须被定义在filters这个节点下面,// 这个节点对象和data平级,filters: {// 过滤器本质是一个函数,自己定义。过滤器中一定要有一个返回值capi(val) {// 主要是为了进行文本的格式化return val.charAt(0).toUpperCase() + val.slice(1);}},methods: {add() {this}},})const vm2 = new Vue({el: "#app2",data: {msg: "hello world",arr: []},})</script></body>
2、被定义在vm实例里面的过滤器只能在当前所控制的el区域使用,如果希望在多个vue实例之间共享过滤器,则可以按照下面面的格式定义全局过滤器Vue.filter()方法接收两个参数,1):是全局过滤器的名字2):全局过滤器的处理函数<body><div id="app"><span>{{ msg | capi }}</span></div><div id="app2"><span>{{ msg | capi }}</span></div><script>// 首先,这个全局过滤器应该定义在vm实例前面,// 然后使用Vue。filter定义全局过滤器Vue.filter('capi', (val) => {return val.charAt(0).toUpperCase() + val.slice(1)})const vm = new Vue({el: "#app",data: {msg: "hello"}})const vm2 = new Vue({el: "#app2",data: {msg: "hello world",arr: []},})</script>
</body>
3、如果全局过滤器和私有过滤器名字冲突,按照就近原则,优先使用私有过滤器
4、可以连续的使用多个过滤器{{  msg | capi | capi2  }}表示递增使用,后面一个过滤器使用前面一个过滤器使用后的结果
5、因为过滤器是函数,可以接收参数,但要注意,接收参数的时候要从第二个位置开始,因为第一个是接收的管道符的文本
6、vue3是没有过滤器的7、yyr

10、侦听器

10-1、侦听器了解

1、侦听器:watch,监听数据的变化,针对数据的变化做特定的操作,侦听器本质上也是一个函数,监听谁就去watch里面定义一个和变量名字一样的函数,并做出响应。watch和data、methods是平级关系,表示监听数据的变化<body><div id="app"><div>{{num}}</div><button @click="num++">num++</button></div><script>const vm = new Vue({el: "#app",data: {num:5},// 监听器,监视数值的变化watch:{num(){console.log("num发生变化");}}})</script>
</body>
2、侦听器的函数里面可以有两个参数,分别是变量的新值和旧值watch:{num(newval,oldval){console.log("num发生变化");console.log(oldval);console.log(newval);}}
3、侦听器的格式分为:1)、方法格式的侦听器缺点:无法在刚进入页面的时候,自动触发如果侦听的是一个对象,对象的属性发生变化不会触发监听2)、对象格式的侦听器优点:可以通过immediate选项让侦听器自动触发一次可以通过deep选项深度监听<script>watch:{// 对象格式的侦听器// 有一个handler的处理函数num:{handler(){console.log("num发生变化");},// 默认值是false// ,控制监听器是否触动触发一次immediate:true},}</script>
4、最好使用方法格式的,简单一点

10-2、深度监听

1、 对象格式的监听器可以通过deep:true这个属性监听对象的属性的改变,任何一个对象的属性发生改变都会触发这个监听器。而这是方法格式的监听器是做不到的<body><div id="app"><input type="text" v-model="student.name"></div><script>const vm = new Vue({el: "#app",data: {student:{name:"小红",age:18,score:99}},watch:{//   对象格式的监听器可以通过deep:true这个属性// 监听对象的属性的改变student:{handler(){console.log("student发生变化");},deep:true},}})</script>
</body>
2、方法格式监听对象的子属性的变化,必须包裹一层单引号。'student.name'(){console.log("'student.name'发生变化");}

11、计算属性

11-1、了解计算属性

1、计算属性是指通过一系列的运算后,最终得到一个属性值。这个动态计算出来的属性值可以被模板结构或methods方法使用
2、computed和el,data都是平级,都是属于vm这个实例对象的。是以对象的形式书写的。所有的计算属性都要定义到computed节点下面,计算属性在定义的时候,要定义成”方法格式”
3、使用说明:1、这个计算属性是计算某个具体的变量,是一个函数方法,我们要把它定义在computed里面。2、这个函数方法有一个返回值,3、直接使用这个函数,把他当做一个变量来使用,它的返回值就是计算的那个变量的值<body><div id="app">{{gaibian }}</div><script>const vm = new Vue({el: "#app",data: {num: 5},// 计算属性computed: {gaibian() {return this.num * 5}}})</script>
</body>
4、声明的时候是方法格式,使用的时候是变量格式好处:1)、实现代码的复用,2)、只要计算属性中的数据源发改变,使用到的计算属性也会改变

模板字符串

模板字符串语法:es5写法:需要使用大量的“”(双引号)和 + 来拼接才能得到我们需要的模版实例:"He is <b>" + person.name + "</b> and we wish to know his" + person.age + ".That is all" es6写法:用`(反引号)标识,用${}将变量括起来实例:`He is <b> ${person.name} </b> and we wish to know his ${person.age} .that is all`就是说,用``反引号将整句话包裹进去,然后把变量用${}包裹{{`He is ${age}`}}<br><br>{{ `${name} 已经 ${age} ,她的身高 ${h}`  }}<!-- 属性渲染 --><div :style="`background:rgb(${r},${g},${b})`"></div>

12、axios

1、axios是一个专注于数据请求的库,就是简化封装了ajax和promise的一个库,vue和react都会用这个
<body><div id="app"><button @click="fn">按我获取数据</button>{{res}}</div><script>const vm = new Vue({el: "#app",data: {res:{}},methods: {async fn() {const p = await axios.get('http://182.92.193.159:5050/allcmc')this.res=p.data                   }},})</script>
</body>
2、axios请求数据时,可以通过传递的参数获取自己想要的数据,传递参数使用data:{}const res = await axios.get("http://www.zt-it.com:5000/student", {params:{}})
3、axios的方法:axios.get() ,axios.post(),axios.delete(),axios.put()

13、Vue-cli

13-1、单页面应用程序

1、单页面就是一个Web网站里面只有一个唯一的一个html页面,素有的功能与交互都在这个唯一的一个页面内完成。
2、vue-cli是vue.js开发的标准工具,简化了程序员基于webpack创建工程化的vue项目的过程
3、中文官网地址:https://cli.vuejs.org/zh/
4、vue-cli是npm上的一个全局包,可以使用npm install命令安装
5、通过 vue create  项目的名称 就可以创建项目,最后一个表示让你自己手动选择需要的环境,然后进入下一步,*表示已经选择,第一项必须选择,表示vue的版本。按下空格键选择。eslint规定格式很严格,最好别选,bavel选择在独立的配置文件中

13-2、项目文件结构

 git:    是一个为git客户端增加git工具,用于存储自己的版本库(或者叫.svn根据自己的配置会有不同名字的版本库)
|- biuld:  vue2.0的配置,项目打包时候的配置文件(现如今的vue项目,可使用vue.config.js进行打包配置)
|- node_modules: node的一些基础依赖包,可能还有拓展的安装的别的插件(npm install下载的依赖包,主要是根据package.json获取对应的依赖包)
|- public: 存放一些主要的打包文件,如index.html等等,可以放置一些需要在index.html配置的文件|- src:项目的主文件夹(vue是SPA单页面应用,可以看做是一个主页面的应用里面的内容组件详情可看vue 代码格式解析)|- assets:          资源文件,用于存放一些静态文件,如字体、图片、css样式之类的|- components: vue主要内容的公共组件,可以进行复用|- router:           设置路由,指定路由对应的组件|- route:            main.js中的router是通过router文件映射,而router下的index.js是项目链接的关键,通过设置路径将views中的vue文件关联起来|- main.js:项目的主js,全局使用的各种变量、js、插件都在此定义和引入;整个项目先加载src里的main.js,通过里面的app元素生成vue对象,再将router里面的路由加载进去,结果在app的vue中呈现|- app.vue:  项目的入口文件|- store:放置vuex需要的状态关联文件,设置公共的state等,是公共数据管理器,关联页面都可随时访问数据,是一个专为vue.js应用开发的状态管理模式,集中式存储管理应用的所有组件的状态|- test:              测试文件目录|- .editorconfig:  是用来帮助开发者定义和维护代码风格(行尾结束符、缩进风格等)editorconfig配置文件网
|- .env: 全局默认配置文件,无论什么环境都会加载合并.env.development:开发环境下的配置文件
.env.development: 开发环境下的配置文件
npm run serve(或者npm run dev 主要看 package.json) 会合并 .env 文件
.env.production: 生产环境下的配置文件
npm run build 会合并 .env 文件
|- .eslintignore:        指定忽略的文件,不需要eslint校验文件; eslint校验对不符合规范代码报错
|- .eslintrc.js:           eslintrc的配置文件,vue项目自带的文件,各个eslint配置项的作用;ESlint是一个检查代码的工具
|- .gitignore: 可以避免在提交代码时把我们不想上传的文件提交到git中; LICENSE:开源协议的说明
|- package.json:     记录作者、项目入口、项目描述、项目依赖等相关信息
|- pnpm-lock.yaml: 记录详细的依赖版本
|- postcss.config.js:插件,利用js插件对CSS进行转换
|- prettier.config.js: 配置文件,保持代码风格统一
|- README.md:     项目用的到的所有插件的json格式
|- stylelint.config.js:让CSS样式代码在编辑、保存、提交git的时候按规范进行检查及美化
|- tsconfig.json:      配置文件
13-2-1、项目外部文件
1、.gitignore:不接受git管理的文件或文件夹
2、babel.config.js:babel的控制文件。
3、package.json:配置的各种信息,依赖、各种信息。build:构建,最后一次编译,编译成html、jslint:进行语法检查
4、package-lock.json:包版本控制文件。
13-2-2、src
1、assets:存放项目的静态资源文件夹,比如:css样式表、图片资源
2、components:程序员封装的、可复用的组件。
3、main.js是项目的入口文件,整个项目的运行,要先执行main.js
4、app.vue 项目的主页,被main.js渲染到public的index.html文件里面
13-2-3、main.js构成:项目最先运行,渲染App组件
1、导入vue,得到vue构造函数import Vue from 'vue'2、导入App.vue这个根组件,要把模板解构渲染到html页面中这个组件是所有组件的父组件。受vm管理import App from './App.vue'3、关闭vue的生产提示Vue.config.productionTip = false4、创建Vue的实例对象new Vue({//把render函数指定的组件渲染到html文件中//mounet是挂载,相当于:el:“#app”render: h => h(App),}).$mount('#app')
// 引入残缺版的vue,残缺版的vue不能自己渲染页面
// 只有完整版的vue能够渲染,
// vue由两部分组成:核心(生命周期、路由)+模板解析器
// 节省空间,残缺版去掉了模板解析器,通过render函数
// 去渲染页面
import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = falsenew Vue({//render:渲染//  h是一个函数,
// h去渲染元素render: h => h(App),}).$mount('#app')
yyr
651908398
13-2-4、App.vue
1、所有组件的根组件
2、整个项目只有一个vm实例,就在app.vue创建。
3、用来编写待渲染的模板结构,index.html中预留一个el区域,让main.js把app.vue渲染到了index.html预留的区域中
13-2-5、index.html配置
<!DOCTYPE html>
<html lang=""><head><meta charset="utf-8"><!--  针对IE浏览器的一个特殊配置,让IE浏览器以最高的渲染级别渲染页面--><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 开启移动端的理想视口 --><meta name="viewport" content="width=device-width,initial-scale=1.0"><!-- 配置页签图标 ,<%= BASE_URL %>:路径的写法:相当于 ./  --><link rel="icon" href="<%= BASE_URL %>favicon.ico"><!-- 配置网页的标题。找到package.json的name属性 --><title><%= htmlWebpackPlugin.options.title %></title></head><body><!-- noscript:如果浏览器不支持js,这里面的元素就会被渲染 --><noscript><strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><!-- 容器 --><div id="app"></div><!-- built files will be auto injected --></body>
</html>
13-2-6、改变入口文件
1、 https://cli.vuejs.org/zh/config/#pages
2、 创建一个vue.config.js文件,然后再去官网的配置参考里面找到pages,选择代码
粘贴到创建的文件里面,去掉多余的module.exports = {pages: {index: {// page 的入口entry: 'src/index/peiqi.js',}}}
13-2-7、关掉语法检查
1、 https://cli.vuejs.org/zh/config/#pages
2、 创建一个vue.config.js文件,然后再去官网的配置参考里面找到lintOnSave,把配置拿过 lintOnSave:false module.exports = {pages: {index: {// page 的入口entry: 'src/index/peiqi.js',}},lintOnSave:false}
13-2-8、vue单文件
1、组件化开发:根据封装的思想,把页面上可重用的UI结构封装为组件,方便项目的开发和维    护
2、vue是一个支持组件化开发的前端框架,组件的后缀名是.vue,
3、vue文件的组成部分,组件是对UI结构的复用1、template:组件的模板结构,2、script:组件的javascript行为3、style:组件的样式
4、export  defalut:默认导出,有引入就要有导出
5、组件中的data必须定义为函数类型,返回一个对象,因为每个组件都有属于自己的数据,避免数组重复,所以每个组件的数据通过data这个函数得到自己的数据
6、可以安装Vetur可以使用快捷键<得到vue文件的模板
7、组件必须只能由一个根节点。

13-3、组件之间的关系

1、组件在被封装好以后,没有引入关系的时候,是相互独立的,不存在父子关系
2、如果在使用组件的时候,根据彼此的嵌套关系,形成了父子关系、兄弟关系
3、父组件引入子组件的步骤1:使用import语法导入需要的组件2、使用compoents节点注册组件  键值一样可以简写3、以标签的形式使用刚才注册的组件
4、通过components注册是私有子组件
5、使用 <右键可以直接生成vue组件
6、组件分为私有组件和全局祖册组件
13-3-1、使用@代替src的方法
1、下载一个插件 Path Autocomplete
2、选择 齿轮-设置-打开设置
3、复制代码到最前面//导入文件时是否携带文件的扩展名"path-autocomplete.extensionOnImport":true,//配置@的路径提示"path-autocomplete.pathMappings":{"@":"${folder}/src"}
4、然后就可以引入了
import Self from '@/components/Self.vue'
(案例:two)
13-3-2、注册全局组件
1、注册一次,全局都可以使用
2、在vue项目的main.js入口文件中,通过Vue.component()方法,可以注册全局组件// 导入需要全局注册的组件import Self from '@/components/Self.vue'// 参数1:字符串格式,表示组件的”注册名称“// 参数2:需要背全局注册的那个组件Vue.component('MySelf',Self)
3、注册完以后就可以通过注册名称直接引入这个组件了

main.js文件

// 引入残缺版的vue,残缺版的vue不能自己渲染页面
// 只有完整版的vue能够渲染,
// vue由两部分组成:核心(生命周期、路由)+模板解析器
// 节省空间,残缺版去掉了模板解析器,通过render函数
// 去渲染页面import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = false// 导入需要全局注册的组件
import Self from '@/components/Self.vue'// 参数1:字符串格式,表示组件的”注册名称“
// 参数2:需要背全局注册的那个组件
Vue.component('MySelf',Self)new Vue({render:h=> h(App)}).$mount('#app')

14、组件之间的通信(分享数据)

14-1、props(父组件给子组件传递数据->自定义属性)

1、props:是组件的自定义属性,在封装通用组件的时候,合理的使用props可以极大地提高组件的复用性(自我总结:就是说每个组件(vue文件)都有这个属性。但如果这些文件的初始值不一样,而且被映射到一个文件上面,就可以使用props)
(被引入的组件是子组件,引入组件的是父组件。在父组件里面把属性传给子组件,子组件使用   props接收)2、props的语法格式:props:["自定义属性1","自定义属性2"]是一个数组,和data等平级关系,里面的属性用字符串包裹3、子组件使用props接收父组件的步骤:(父组件是App.vue,子组件是father.vue)1、在引入组件的时候,在父组件里面使用子组件的标签对里传值   <Father :count="count"></Father>2、在子组件里面接收props:['count']3、使用这个属性   注意:子组件的这个属性改变不会影响到父组件的属性发生改变4、 props可以传递具体的值,也可以传变量,是自定义属性。在传值的时候为当前组件指定初始值。这个自定义属性是封装者自己定义的。可以极大地提高组件的复用性5、props传递变量的三种方式1、传递的是字符串<Son count="9"></Son>2、传递的是数值<Son :count="9" ></Son>3、传递的是变量<Son :count="count" ></Son>因为 :代表v-bind,里面是js语句,相当于count=96、props的数据,可以直接在模板结构中被使用,并且,子组件不要修改props接收到的值,会报错。7、vue规定,组件中封装的自定义属性是只读的,程序员不能直接修改props的值,不然会直接报错。8、可以把props值传给datanum:this.count9、props的default值,来定义属性的默认值。写成对象的形式,一般是在组件没有传递该属性时候,则默认值生效props:{count:{default:5}}10、props的type值类型,设置属性的类型,传入的值必须是该类型props:{count:{default:5type:Number}}11、props的required:必填,要求必须传递该属性的值props:{count:{default:5,required:true}}12、简答类型复制的是值,复杂类型的是引用地址。13、yyr

14-2、子组件向父组件传递数据(使用自定义事件)

1、子组件可以通过自定义时间向父组件传递数据。1、在子组件中自定义一个事件,使用 this.$emit('btn-click', item)的语法,emit指代发射事件,btn-click是我们自定义的事件名,item是子组件中的数据。 注意::vue官方推荐你始终使用 kebab-case格式的事件名。2、在父组件中使用v-on监听在子组件中我们自定义的数组,并为其在父组件中定义一个接收监听的事件3、在父组件中接收数据
    <button @click="add">点我传送数据给父组件App</button>methods: {add(){this.$emit('num',this.message)}},
    <Son @num="add"></Son>methods: {add(n){console.log(n);}},

14-3、兄弟组件之间的数据共享(EventBus:全局事件总线,可实现任意组件通信)

1、创建一个eventBus.js模块,并向外共享一个Vue的实例对象2、在数据发送方,调用bus.$emit("事件名称",要发送的数据)方法触发自定义事件3、在数据接收方,调用bus.$on("事件名称",事件处理函数)方法注册一个自定义事件
1、自定义一个eventBus.jsimport Vue from 'vue'export default new Vue()
2、在数据发送方,引入这个文件。再定义一个事件,然后通过这个事件调用bus.$emit("事件名称",要发送的数据)方法触发自定义事件<template><div><!-- 数据发送方 --><button @click="send">发送数据</button></div>
</template><script>
import bus from '@/components/eventBus.js'
export default {data() {return {msg:"好好学习,天天向上"}},methods: {send(){bus.$emit("num",this.msg)}},}
</script>
3、在数据接收方,使用create生命周期函数调用bus.$on("事件名称",事件处理函数)方法注册一个自定义事件
<template><div><div>接收方{{str}}</div></div>
</template><script>
import bus from '@/components/eventBus.js'
export default {data() {return {str:""}},created() {bus.$on("num",val=>{this.str=val})},}
</script>

14-4、vuex(状态管理)

vuex官方解释
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
14-4-1 、vuex的概念
1、概念:专门在vue中实现集中式状态(数据)管理的一个插件 Vue.use()。对vue应用中的多个组件的共享状态进行集中式状态 数据  管理(读/写)。也是一种组件间通信的方式,且适合用于任意组件间的通信
14-4-2、什么时候使用vuex(共享)
1、多个组件依赖于统一状态(多个组件需要用到同一个数据,就可以让vuex来管理这个护具)2、来自不同组件的行为需要变更同一状态(需要改变这同一个数据)
14-4-3、vuex工作原理图

在这里插入图片描述

每一个 Vuex 应用的核心就是 store,里面又包括:1. State(状态):用于数据的存储(对象类型数据),是store中唯一数据源2. Actions(行为):类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步事件3. Mutations(转变):类似函数,改变state数据的唯一途径,且不能用于处理异步事件。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方4. Getter(数据加工):如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关计算5. Module:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。

vuex工作原理说明

1、,actions、mutations,state2、actions:动作、行为3、mutations:维修,加工4、state:状态,把数据交给vuex的state对象进行保管。5、dispatch:分发,派遣。
14-4-4、vuex的搭建环境
1、安装vuexnpm i vuex@32、在main.js里面设置vue.use(Vuex)import Vuex  from 'vuex'//就可以配置store项Vue.use(Vuex)3、在src里面创建一个文件夹store,创建一个index.js用于创建vuex中最核心的store,在js文件里面创建三个对象   // 准备actions-用于响应组件中的动作const actions={}// 准备mutations-用于操作数据const mutations={}// 准备dtate-用于存储数据const  state={}然后创建一个store对象来管理这几个对象因为store是通过Vuex的Store创建的。所以我们要引入Vuex// 引入Vuex创建storeimport Vuex from 'vuex'然后创建storeconst store =new Vuex.Store({actions,mutations,state})// 向外暴露,因为主要是要的是store,所以暴露的是store
export default store4、在main.js引入这个store,所有的组件对象能看见这个 store// 引入storeimport store from './store'//配置new Vue({el:"#app",store,//render:渲染//  h是一个函数,
// h去渲染元素render:h=> h(App)})5、报错,现这样错误的原因是在创建store实例之前,没有调Vue.use(Vuex),但这个时候会有人说,已经调用了Vue.use(Vuex),还是会出现这样的错误。究其原因是因为Vue脚手架会解析文件中的所有import语句,然后把所有import语句按照编写代码的顺序全都汇总在最上方,之后才会解析文件中的其它代码,这就会使得Vue.use(Vuex)在store实例之后执行。import引入最高级,会优先执行import的js,所以先创建store实例会报错。6、解决:在store.js,引入Vue后,在使用Vue.use(Vuex)import Vue from 'vue'Vue.use(Vuex)620227月,vue3成为了默认版本, 现在npm i vue,安装的就是vue3,vue3成为默认版本,vuex也更新到了44只能在vue3中使用,现在使用npm i vuex安装的是4版本
我们项目使用的是2版本,使用vuex4就会报错。所以我们要安装3版本

store.js

// 引入Vuex创建store
import Vuex from 'vuex'// 准备actions-用于响应组件中的动作
const actions={}// 准备mutations-用于操作数据
const mutations={}// 准备dtate-用于存储数据
const  state={}// 创建store
// 因为store是管理// const store =new Vuex.Store({
//     actions,
//     mutations,
//     state// })// 向外暴露,因为主要是要的是store
// export default store// 简写,创建并暴露store
export default new Vuex.Store({actions,mutations,state})

main.js

// 引入残缺版的vue,残缺版的vue不能自己渲染页面
// 只有完整版的vue能够渲染,
// vue由两部分组成:核心(生命周期、路由)+模板解析器
// 节省空间,残缺版去掉了模板解析器,通过render函数
// 去渲染页面
import Vue from 'vue'
import App from './App.vue'
// 引入vuex
import Vuex from 'vuex'
// 引入store
import store from './store'Vue.use(Vuex)Vue.config.productionTip = falsenew Vue({store,render:h=> h(App)
}).$mount('#app')

解决报错

store.js

// 引入Vuex创建store
import Vuex from 'vuex'
// 引入vue
import Vue from 'vue'// 准备actions-用于响应组件中的动作
const actions={}// 准备mutations-用于操作数据
const mutations={}// 准备dtate-用于存储数据
const  state={}Vue.use(Vuex)// 创建store
// 因为store是管理// const store =new Vuex.Store({
//     actions,
//     mutations,
//     state// })// 向外暴露,因为主要是要的是store
// export default store// 简写,创建并暴露store
export default new Vuex.Store({actions,mutations,state})

main.js

// 引入残缺版的vue,残缺版的vue不能自己渲染页面
// 只有完整版的vue能够渲染,
// vue由两部分组成:核心(生命周期、路由)+模板解析器
// 节省空间,残缺版去掉了模板解析器,通过render函数
// 去渲染页面
import Vue from 'vue'
import App from './App.vue'
// 引入vuex
import Vuex from 'vuex'
// 引入store
import store from './store'Vue.config.productionTip = falsenew Vue({el:"#app",store,//render:渲染//  h是一个函数,
// h去渲染元素render:h=> h(App)})
// .$mount('#app')

14-4-5、vuex工作流程

1、state管理数据,所以把想让vuex管理的数据保存到state中。2、当我们想改变state保管的数据的状态的时候。就使用action保管的函数方法,使用dispatch方法将执行那个函数方法拍给action执行。this.$store.dispatch('函数方法',参与运算的数据参数)this.$store.dispatch('Jia',this.num)3、action函数里面响应这个方法,所以需要在action里面定义这个函数方法,使用对象格式,也可以简写,这个函数方法可以接收到两个参数,一个是context,这个上下文对象就包括了commit方法,可以函数方法名(context,n){函数体}4、action的这个函数方法可以接收到两个参数,一个是context,这个上下文对象就包括了commit方法,可以使用这个context对象调用commit方法,由 actions 提交一个 mutation。记住!!!这个函数方法名改为大写,为了区分mutation和action写的函数函数方法名(context,n){context.commit(‘函数方法名’,n){5、在mutation里面准备定义这个函数,也有两个参数,a是state,b是传递的参数数据就可以通过a.数据和数据进行处理mutation=大写的函数方法名(a,b){}}
6、展示state里面的数据的写法$store.state.数据名7、actions决定业务逻辑是否调用mutation的函数,包括发送异步请求8、如果函数不需要什么业务逻辑,可以直接mutation对接,直接调用commit调用mutation里面的函数this.$store.commit('大写的函数方法名',参数数据)9、组件中地区vuex的数据,$stroe.state.sum 10、组件中使用actions的数据:$store.dispatch('action中的方法名',数据)$store.commit('mutation中的方法名',数据)(如果没有网络请求或起亚业务逻辑,可以绕过actions,直接commit)

工作流程

https://blog.csdn.net/JHY97/article/details/124045131?ops_request_misc=&request_id=&biz_id=102&utm_term=vuex%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E5%9B%BE&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-124045131.142^v87^control_2,239^v2^insert_chatgpt&spm=1018.2226.3001.4187
14-4-6、vuex的getters
1、getters其实就是store的计算属性,对state里面的状态进行过滤处理,用法与组件自身的计算属性一模一样。2、使用,和actions一样定义,然后和计算属性一样在里面定义方法,方法返回一个数值const getters={}然后把getters放到store里面export default newVVuex.Store({actions,mutations,state,getters}3、当state中的数据需要经过加工后再使用时,可以使用getters加工  
14-4-7、vuex的mapState
1、mapState是什么用于帮助我们映射state中的数据为计算属性因为我们可以在组件的计算属性的方法里面,直接返回state里面的数据,而this.$store.state.数据 。如果返回state数据的函数方法太多,太麻    烦。mapState可以帮我们生成这种函数方法使用:先在需要映射的组件里面引入这个组件import  {mapState} from 'vuex'在computed里面使用mapState生成函数方法mapState({方法名:"state里面的数据"})如果方法过多,我们可以解构的形式...mapState({方法名:"state里面的数据",方法名2:"state里面的数据2"})简写,把数据名用字符串括起来放在数组里面...mapState(['数据名1''数据名2'])2、mapGetters方法:用于帮助我们映射getters中的数据为计算属性和mapstate用法一致3、mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含          $store.commit(xxx)的函数和mapstate用法一致的话,会出错。传入的是鼠标事件,因为生成的函数没有参数,而mutation定义的参数里面是有value的,而默认是有一个事件对象,所以这个事件对象会在被作为value值传给mutations的value值...mapMutations({方法名1:"mutations里面的方法1",方法名2:"mutations里面的方法12"})解决方法:在调用的时候,把这个数传过去方法名1(n)4、mapActions方法:用于帮助我们生成与actions对话的方法,即:包含                $store.dispatch(xxx)函数和mapMuatations用法一致
14-4-8、vuex模块化
1、因为会有不用的功能,比如订单模块,用户模块,可以把这些模块分成不同的对象,统一配置actions,state,mutations,const 对象1={const actions={}const state={}const mutations={}const getters={}}const 对象2={const actions={}const state={}const mutations={}const getters={}}2、暴露store的时候,去掉actions,state,mutations,使用modules放置定义的对象,这里的a,b是别名export default new Vuex.Store({modules:{a:配置对象1b:配置对象2}})3、简写,这样写的话,可以输出this.$store看一下export default new Vuex.Store({modules:{配置对象1,配置对象2}})4、计算属性使用的时候,这是将mapstate方法将a,b生成计算属性,将store的state下面的a,b作为计算属性的方法,返回这两个数据,因为它们是两个对象,所以可以使用a.属性名,b.属性名。...mapState(['a','b'])5、直接从配置对象里面拿到数据,表示从别名1里面拿去数据,但是只是这样肯定会报错,还需要给配置对象设置一个namespaced:true属性...mapState(‘别名1,['a','b'])const 对象1={namespaced:true,const actions={}const state={}const mutations={}const getters={}}6、方法也是一样...mapMutations(‘别名1’,{方法名1:"mutations里面的方法1",方法名2:"mutations里面的方法1"})就可以调用这个方法,记得传参7、如果是直接调用commit方法,要找到具体的是哪一个配置对象的方法this.$store.commit('配置别名/配置方法名',传入的参数)8、获取配置对象的getters的方法this.$store.getters['配置别名/配置方法名']9、如果是直接调用dispatch方法,要找到具体的是哪一个配置对象的方法this.$store.dispatch('配置别名/配置方法名',传入的参数)10、模块化语法减少代码耦合,更好维护代码。让各种数据分类更加明确
14-4-9、vuex的详细用法
1、开启命名空间后,组件中读取state的数据1—自己直接读取this/$store.state.配置名.数据名2-借助mapState读取...mapState('配置别名'['数据名1''数据名2'])2、开启命名空间后,组件中读取getters的数据1—自己直接读取this.$store.getters['配置别名/配置方法名']2-借助mapGetters读取...mapGetters('配置别名'['方法名1''方法名2'])3、开启命名空间后,组件中调用dispatch1—自己直接dispatchthis.$store.dispatch('配置别名/配置方法名',传入的参数)2-借助mapActions生成方法,方法调用需要传递参数...mapActions('配置别名'['方法名1''方法名2'])或者...mapActions('配置别名'{组件定义的方法名:'配置对象的方法名'})4、开启命名空间后,组件中调用commit1—自己直接committhis.$store.commit('配置别名/配置方法名',传入的参数)2-借助mapMutations生成方法,方法调用需要传递参数...mapMutations('配置别名'['方法名1''方法名2'])或者...mapMutations('配置别名'{组件定义的方法名:'配置对象的方法名'})    

14-5、消息订阅

个人省略

15、组件之间的样式冲突问题

1、默认情况下,写在.vue组件中的样式会全局生效,因此会很容易造成多个组件之间的样式冲突问题。原因是因为1、单页面应用程序,多有组件的DOM结构,都是基于唯一的index.html进行呈现2、每个组件中的样式,都会影响整个index.html中的DOM元素
2、解决样式冲突问题在style里面加上scoped,vue会自动为该组件的元素生成私有属性<style lang="less" scoped></style>
3、如果想在父组件里面改变子组件的样式,而其他引入了子组件的不会发生改变,那么,不仅要在该父组件定义scoped,还要在改变的样式前面加上一个前缀,这样的话就会变成一个后代选择器。/deep/ div{width: 200px;height: 200px;background-color: blue;}

16、生命周期

16-1、简单介绍

官网:每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。
1、生命周期:是一个vue组件从  创建 ->运行->销毁  的整个阶段,强调的是一个时间段2、生命周期函数:是vue提供的内置函数,会伴随着组件的生命周期,自动按次序执行3、生命周期强调的是时间段,生命周期函数强调的是时间点4、组件创建阶段: beforeCreate(组件还没开始创建之前)、created(内存里面创建好,还没被渲染)、beforeMount(将要渲染的时候)、mounted(渲染好的时候,刚好看到组件的时候)5、组件运行阶段:beforeupdate(组件更新前)、updated6、created最重要,因为我们异步请求数据就是在这个周期函数里面
1、创建期间的生命周期函数:1)beforeCreate:实例刚在内存中被创建出来此时还未初始化完毕data和methods2)created:实例已经在内存中创建完毕此时 data和methods已经创建完毕 但此时还未开始编译模板3)beforeMount:此时已经完成模板的编译但是还未挂载到页面中4)mounted:此时已将编译好的模板挂载到了页面指定的容器中显示
2、运行期间的生命周期函数:1)beforeUpdate:状态更新之前执行此函数此时data中的状态值是最新的 但界面上显示的数据还是旧的因为此时还未开始重新渲染DOM节点2)updated:实例更新完毕之后调用此函数此时data中的状态值和界面上显示的数据都已完成了更新 界面已被重新渲染好了
3、销毁期间的生命周期函数:1)beforeDestroy:实例销毁前调用在这 实例仍然完全可用2)destroyed:Vue实例销毁后调用调用后 Vue实例指示的所有东西都会解除绑定 所有的事件监听器会被移除 所有的子实例     也会被销毁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ISgI4l6Z-1686141820663)(C:\Users\Direct\Desktop\常用前端框架及工具\拓展学习资料\生命周期函数.png)]

组件创建阶段


<template><div id="app"><h3></h3></div>
</template><script>export default {name: "App",components: {},data() {return {count:5}},beforeCreate(){console.log(this.count);},created(){//异步请求数据使用该函数console.log(this.count);console.log(document.querySelector("h3"));// data和methods已经创建完毕 但此时还未开始编译模板,所以不能操作dom// document.querySelector("h3").innerText="Hello"},beforeMount(){//还没有渲染// document.querySelector("h3").innerText="Hello"},mounted(){//编译好已经挂载到页面上,最早操作dom元素document.querySelector("h3").innerText="Hello"}};
</script>

组件运行阶段

<template><div id="app"><h3>生命周期</h3><h4>{{ count }}</h4><button @click="count++">count++</button></div>
</template><script>export default {name: "App",components: {},data() {return {count:5}},beforeUpdate(){// data中的状态值是最新的 但界面上显示的数据还是旧的console.log(this.count);console.log( "h4的值"+document.querySelector("h4").innerHTML);},updated() {//数据和模板结构完成同步//为了操作大哦最新的dom结构,必须写到upDate声明周期函数console.log(this.count);console.log( "h4的值"+document.querySelector("h4").innerHTML);},};</script>

17、ref引用(Vue用来操作DOM元素的)

1、ref是用来辅助开发者在不依赖jquery的情况下,获取DOM元素或组件的引用2、每个vue的组件实例上,都包含一个$refs对象,里面存储着对应的DOM元素激活组件的引用。默认情况下,组件的$refs指向一个空对象3、给一个Dom元素定义一个ref属性,然后取一个名字,就可以通过$refs.名字对这个DOM元素进行操作4、如果想要使用ref引用页面上的组件实例,还可以给组件使用ref。然后通过this.$refs.组件的ref的名字.fn(),就可以运行该组件的方法
<!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><script src="../lib/vue.js"></script>
</head><body><div id="app"><span ref="s">使用ref操作dom元素</span><button @click="fn">输出this</button></div><script>const vm = new Vue({el:"#app",methods: {fn(){console.log(this.$refs.s);}},})</script>
</body></html>

根组件引用Ref组件过后,通过ref属性使用他的方法

<template><div id="app"><button @click="fn">App:按我输出组件r的方法</button><br><br><Ref ref="r"></Ref></div></template><script>
import Ref from '@/view/Ref.vue'export default {name: "App",components: {Ref},data() {return {}},methods:{fn(){this.$refs.r.fn()}}};</script>

17-1、this.$nextTick()方法

1、this.$nextTick()方法主要是用在随数据改变而改变的dom应用场景中,vue中数据和dom渲染由于是异步的,所以,要让dom结构随数据改变这样的操作都应该放进this.$nextTick()的回调函数中。2、created()中使用的方法时,dom还没有渲染,如果此时在该钩子函数中进行dom赋值数据(或者其它dom操作)时无异于徒劳,
所以,此时this.$nextTick()就会被大量使用,而与created()对应的是mounted()的钩子函数则是在dom完全渲染后才开始渲染数据,
所以在mounted()中操作dom基本不会存在渲染问题。3、就是数据发生改变了,但是页面还没有反应过来,就需要使用这个this.$nextTick(),等待数据渲染后应用在dom里面,需要dom重新渲染的时候就需要用到这个方法。把回调推迟到下一个DOM更新周期之后执行
this.$nextTick(()=>{函数体
})

18、动态组件

1、动态组件指的是动态切换组件的显示和隐藏2、vue提供了一个内置的<component>组件,专门用来实现动态组件的渲染,作用:组件的占位符,is属性的值:表示要渲染的组件的名字。而且,is属性的值,应该是组件在components节点下的注册名称。也就是必须是引入的组件,注册过后,才能使用。3、可以把这个<component>看做一个组件的占位符。但是直接使用会报错,未知的元素错误,因为这个元素还没有被定义。4、在component组件里面使用is属性选择要渲染的组件<component is="Hello"></component><component is="Hi"></component>5、对于飘红线显示错误的情况,使用v-bind绑定is属性,然后使用反引号括起来组件名字<component :is="`Hello`"></component><component :is="`Hi`"></component>6、组件的切换,会不断的创建和销毁,字符串的值用单引号括起来,is属性绑定str<div id="app"><nav>App根组件<button @click="str = 'Hello'">切换为Hello组件</button><button @click="str = 'Hi'">切换为Hi组件</button>     </nav><component :is="str"></component></div>7、使用keep-alive保持让组件隐藏的时候不会被销毁,直接使用<keep-alive></keep-alive>标签将切换的动态组件括起来<div id="app"><nav>App根组件<button @click="str = 'Hello'">切换为Hello组件</button><button @click="str = 'Hi'">切换为Hi组件</button>           </nav><keep-alive><component :is="str"></component></keep-alive></div>8、打开vue调试工具,在切换inactive表示被缓存了,没有被销毁9、如果想在组件被缓存的时候做什么,在组件被激活的时候做什么,有对应的生命周期函数当组件被缓存的时候,会自动触发组件的deactivated生命周期函数当组件被激活的时候,会自动触发组件的activated生命周期函数
created() {console.log("Hello组件已经创建");},destroyed() {console.log("Hello组件已经销毁");},deactivated() {console.log("Hello组件缓存");},activated (){console.log("Hello组件激活");}10、组件第一次被创建的时候,会激活created,也会激活activated生命周期,组件被激活的时候只会触发activated,不再触发created。11、keep-alive的include属性:在component会把component包裹的组件都缓存起来。可以使用include属性用来指定。至于名称相匹配的组件会被缓存,多个组件名之间使用,就是说用它来指定哪些组件需要被缓存,多个组件名之间用,分隔。不被包含在里面的都不会被缓存,记住这个include指定的组件名是在组件里面的定义的name属性//只有Hello组件可以被缓存<keep-alive include="Hello"><component :is="str"></component></keep-alive>12、exclude属性:默认哪些组件不会被缓存,不能和include同时使用   13、在组件提供了name属性后,组件的名称就是name属性的值。如果在“声明组件”的时候,没有为组件指定name名称,则组件的名称默认就是“注册时候的名称”,14、注册名称以标签的形式使用,把注册好的组件渲染和使用到页面结构中name名称为了在调试工具里面看到组件名称,以及结合《keep-alive》实现组件缓存功能

Hello子组件

<template><div>Hello组件</div>
</template><script>
export default {created() {console.log("Hello组件已经创建");},destroyed() {console.log("Hello组件已经销毁");},deactivated() {console.log("Hello组件缓存");},activated (){console.log("Hello组件激活");}
}
</script><style lang="less" scoped>
div{width: 100%;height: 400px;position: absolute;top:58px;background-color: rgb(248, 245, 49);
}</style>

父组件

<template><div id="app"><nav>App根组件<button @click="str = 'Hello'">切换为Hello组件</button><button @click="str = 'Hi'">切换为Hi组件</button></nav><component :is="str"></component></div></template><script>import Hello from './components/Hello.vue'
import Hi from './components/Hi.vue'export default {name: "App",components: {Hello,Hi,},data() {return {str:""}}};</script>
<style lang="less" scoped>
* {padding: 0;margin: 0;
}nav {width: 100%;height: 50px;background-color: #eee;
}
</style>

Hi子组件

<template><div>Hi组件</div>
</template><script>
export default {}
</script><style lang="less" scoped>
div {width: 100%;height: 400px;background-color: orange;
}
</style>

19、插槽

19-1、插槽的基本用法

1、插槽(slot)是vue为组件的封装这提供的能力,允许开发者在封装组件的时候,把不确定、希望由用户指定的部分定义为插槽。2、简单来说就是在使用注册过的组件时,如果要往那个标签对里面插入什么元素,但是不会显示出来,就可以往子组件里面写一个插槽,这样这个组件标签对里面写的东西就可以显示出来了3、用户使用什么,插槽就渲染什么4、vue官方规定,每一个插槽都应该有一个name名称,如果没有定义会有一个default的默认名称<slot name="p"></slot>5、如果插槽定义了name属性,那么我们要使用 v-slot:插槽的名字,去指定是哪一个插槽,而且要注意的是,这个被指定要使用插槽的元素要使用template包裹。例如:根组件引用了Hello组件,在标签对里面使用了一个p标签,然后,在hello组件里面定义了一个name属性为p的插槽,然后根组件就需要将这个p标签用template包裹起来。然后在template里面定义v-slot:pHello组件<slot name="p"></slot>App组件<Hello><template v-slot:p><p >你好,这是插槽内容</p></template></Hello>6、注意:1、如果要把内容填充到指定名称的插槽中,需要使用v-slot2、v-slot值只能用在template身上,而且渲染的页面是看不见这个template元素的,只会看见被渲染的元素3、v-slot:插槽的名字4、插槽指令v-slot的简写形式是: #,就是一个#号
1、比如,在APP根组件里面引入了Hello组件,然后声明注册后以标签对的形式使用,在里面定义了一个p标签,但不会显示内容,只有在Hello里面定义一个slot插槽,接收到这个p标签,才能显示内容
普通的定义插槽

根组件

<template><div id="app"><nav>App根组件<Hello><p>你好,这是插槽内容</p></Hello></nav></div></template><script>import Hello from './components/Hello.vue'
import Hi from './components/Hi.vue'export default {name: "App",components: {Hello,Hi,},data() {return {str:""}}};</script>
<style lang="less" scoped>
* {padding: 0;margin: 0;
}nav {width: 100%;height: 50px;background-color: #eee;
}
</style>

Hello组件

<template><div>Hello组件<slot></slot></div>
</template><script>
export default {}
</script><style lang="less" scoped>
div{width: 100%;height: 400px;position: absolute;top:58px;background-color: rgb(248, 245, 49);
}</style>

有名字的插槽

Hello组件

<template><div>Hello组件<slot name="p"></slot></div>
</template><script>
export default {}
</script><style lang="less" scoped>
div{width: 100%;height: 400px;position: absolute;top:58px;background-color: rgb(248, 245, 49);
}</style>

App组件

<template><div id="app"><nav>App根组件<Hello><template v-slot:p><p >你好,这是插槽内容</p></template></Hello></nav></div></template><script>import Hello from './components/Hello.vue'
import Hi from './components/Hi.vue'export default {name: "App",components: {Hello,Hi,},data() {return {str:""}}};</script>
<style lang="less" scoped>
* {padding: 0;margin: 0;
}nav {width: 100%;height: 50px;background-color: #eee;
}
</style>

19-2、具名插槽和作用域插槽

1、带名字的插槽就是具名插槽,2、slot插槽可以定义属性,在template里面用v-slot接收子组件:<slot name="p" msg="好好学习,天天向上"></slot>根组件<Hello><template #p="obj"><p >你好,这是插槽内容</p>{{ obj }}</template></Hello>3、在封装组件时,为预留的slot提供属性对象的值,这种用法叫做作用域插槽4、这种作用域插槽也是具名插槽,用v-slot接收,v-slot可以用#来进行简写。数据对象可以用=来接收。对象的名字用scope定义<Hello><template #p="scope"><p >你好,这是插槽内容</p>{{ obj }}</template></Hello>5、作用域插槽可以使用解构接收数据对象
写法:可以直接使用这个msg#p="{msg}"也可以通过scope直接接收所有数据#p="scope"{{scope.msg}}

20、自定义指令

1、vue官方提供了v-text、v-for、v-model等常用的指令,还允许开发者自定义指令2、vue的自定义指令分为两类:1)、私有自定义指令2)、全局自定义指令3、私有自定义指令:在每个vue组件中,可以在directives(自定义指令节点)节点下声明私有自定义指令就在组件实例里面定义,和methods、data等平级,这个指令是对象形式,定义的指令      也是对象形式// 这是自定义指令的节点directives:{// 定义一个color的指令,指向一个配置对象color:{// 当这个指令绑定到元素的时候,会马上触发bind函数// bind函数会接收一个el参数,这个el参数就是绑定的dom元素bind(el){console.log(el);}}}4、例如,定义一个color的指令,可以在绑定元素的时候,把元素的背景颜色渲染为绿色// 这是自定义指令的节点directives:{// 定义一个color的指令,指向一个配置对象color:{// 当这个指令绑定到元素的时候,会马上触发bind函数// bind函数会接收一个el参数,这个el参数就是绑定的dom元素// 可以利用这个el参数对Dom对象做操作,将背景颜色渲染为绿色bind(el){el.style.backgroundColor="green"}}}5、这种定义私有指令的时候,不用使用v-开头来定义,但是使用的时候必须使用v-开头,例如<div class="box" v-color>这是一个红色的盒子</div>6、自定义指令接收实际参数,会有一个binding对象。binding对象里面有一个value,可以接收到传入的数据,而且,,如果传入的数据时字符串格式的话,要记得给字符串加上单引号。不带引号传入的是一个变量。写法:<div class="box" v-color="'yellow'">这是带有参数的自定义指令</div>定义私有指令的写法directives:{ color:{bind(el,binding){el.style.backgroundColor=binding.value}}}7、expreion:是一个表达式,就是这个=后面的表达式。代表用户写的东西。8、bind函数的缺点,只会在第一次绑定元素的时候执行,而且只执行一次,而如果页面数据更新,是无法改变的,二update函数会在每次Dom更新的时候调用。updated() {console.log(this.str);},9、凡是使用到了这个指令的元素,都会触发这个update函数10、update只会在数据更新的时候生效,不会在第一次的时候生效11、函数简写:如果bind和update函数中的逻辑完全相同,则对象格式的自定义指令可以写成函数格式:color(el,binding){  el.style.backgroundColor=binding.value}12、私有自定义指令只能在当前定义的组件使用,不能在其他组件使用13、全局共享的自定义指令需要在main.js  通过“vue.directive()”进行声明像定义全局过滤器一样,以对象形式写两个函数方法Vue.directive('c',{binding(el,binding){el.style.color=binding.value},update(){el.style.color=binding.value}
})14、如果逻辑一样,可以以函数形式写代码Vue.directive('c',function(el,binding){el.style.color=binding.value})

main.js

// 引入残缺版的vue,残缺版的vue不能自己渲染页面
// 只有完整版的vue能够渲染,
// vue由两部分组成:核心(生命周期、路由)+模板解析器
// 节省空间,残缺版去掉了模板解析器,通过render函数
// 去渲染页面
import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = falseVue.directive('c',function(el,binding){
el.style.color=binding.value})new Vue({el:"#app",render:h=> h(App)})
// .$mount('#app')

bind对象和它的缺点

<template><div id="app"><nav>App根组件<div class="box" v-bgc>这是一个红色的盒子</div><!-- 直接传入一个颜色值 --><div class="box" v-color="'yellow'">这是带有参数的自定义指令</div><button @click="str='yellowgreen'">改变str的颜色</button><div class="box" v-color="str">这是使用变量的带参数的自定义指令,看清楚bind函数只执行一次</div><div class="box" v-color="str">这是使用变量的带参数的自定义指令,看update的更新</div></nav></div></template><script>import Hello from './components/Hello.vue'import Hi from './components/Hi.vue'export default {name: "App",components: {Hello,Hi,},data() {return {str:"pink"}},// 这是自定义指令的节点directives:{// 定义一个color的指令,指向一个配置对象bgc:{// 当这个指令绑定到元素的时候,会马上触发bind函数// bind函数会接收一个el参数,这个el参数就是绑定的dom元素// 可以利用这个el参数对Dom对象做操作bind(el){el.style.backgroundColor="green"}},color:{bind(el,binding){el.style.backgroundColor=binding.value}}},//生命周期函数,看见这个str已经改变,但是因为bind而不会更新页面updated() {console.log(this.str);},};</script><style lang="less" scoped>* {padding: 0;margin: 0;}nav {width: 100%;height: 50px;background-color: #eee;}.box{width: 200px;height: 200px;background-color: red;}</style>

update的优点

<template><div id="app"><nav>App根组件<button @click="str='yellowgreen'">改变str的颜色</button><div class="box" v-color="str">这是使用变量的带参数的自定义指令,看update的更新</div></nav></div></template><script>import Hello from './components/Hello.vue'
import Hi from './components/Hi.vue'export default {name: "App",components: {Hello,Hi,},data() {return {str:"pink"}},// 这是自定义指令的节点directives:{// 定义一个color的指令,指向一个配置对象bgc:{// 当这个指令绑定到元素的时候,会马上触发bind函数// bind函数会接收一个el参数,这个el参数就是绑定的dom元素// 可以利用这个el参数对Dom对象做操作bind(el){el.style.backgroundColor="green"},},color:{bind(el,binding){el.style.backgroundColor=binding.value},update(el,binding){el.style.backgroundColor=binding.value
}
}},updated() {console.log(this.str);},};</script>
<style lang="less" scoped>
* {padding: 0;margin: 0;
}nav {width: 100%;height: 50px;background-color: #eee;
}
.box{width: 200px;height: 200px;background-color: red;
}
</style>

21、路由

21-1、理解路由

1、路由就是对应关系,route2、路由器:router3、路由就是一组key-value的对应关系,多个路由需要经过路由器的管理4、路由就是为了实现单页面应用。5、项目由导航区和展示区组成
1、路由指的就是Hash地址与组件之间的关系2、#号代表锚链接,不会导致页面的刷新,会导致历史记录的变化3、普通的超链接:<a href="路径"></a> 是跳转到不同的页面锚点:<a href="位置"></a> 可以在同一个页面中不同的位置间跳转4、建立锚点目标,只需要给目标元素增加 id 或者 name 即可锚的名称可以是任何你喜欢的名字可以使用 id 属性来替代 name 属性,命名锚同样有效,推荐使用 id5、#往后都叫做hash地址,   

锚链接

<!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>#锚链接</title><style>div{height: 800px;}#d1{background-color:red ;}#d2{background-color:rgb(26, 224, 108) ;}#d3{background-color:rgb(22, 56, 230) ;}#d4{background-color:rgb(231, 65, 143) ;}nav{position: fixed;top: 0;left:0;}</style>
</head>
<body><nav><a href="#d1">d1</a><a href="#d2">d2</a><a href="#d3">d3</a><a href="#d4">d4</a></nav> <div id="d1"></div> <div id="d2"></div> <div id="d3"></div> <div id="d4"></div> 
</body>
</html>

21-2、路由的工作方式

1、点击页面上的路由连接后,url地址栏上的hash值发生改变,前端路由监听到了hash地址的变化,然后把当前hash地址对应的组件渲染到浏览器中2、在html页面中对应关系: a#d1  <->  div#d13、在vue中路由:path:"#/d1",compoment:#d1

21-3、简单的路由实现

1、window.onhashchange监听页面的hash值变化2、location.hash.substring(2)截取本地的hash值的字符串2位后的字符串3、使用动态组件决定显示那个页面,is属性绑定一个动态组件,切换组件
<template><div id="app"><nav><h2>App根组件</h2><a href="#/Home">首页</a> |<a href="#/Login">登录</a>  |<a href="#/Regist">注册</a>  |</nav><component :is="cname"></component></div>
</template><script>
import { nanoid } from 'nanoid'
import Hello from './components/Hello.vue'
import Home from './components/Home.vue'
import Login from './components/Login.vue'
import Regist from './components/Regist.vue'export default {name: "App",components: {Hello,Home,Login,Regist},data() {return {n: 5,id: 0,cname:'Home'}},created() {this.id = nanoid()window.οnhashchange=()=>{// console.log("hash值发生变化",location.hash);//  console.log( location.hash.substring(2));this.cname=location.hash.substring(2)}},};</script>
<style lang="less" scoped>
* {padding: 0;margin: 0;
}nav {width: 100%;height: 50px;background-color: #eee;
}.box {width: 200px;height: 200px;background-color: red;
}
</style>

21-4、vue-router的使用

1202227日以后,vue-router的默认版本,为4版本,4版本适用于vue33版本的vue-router适用2版本的vue。我们直接安装vue-router就会报错,   出现。Found:vue @2.。。。peer vue@“^3.0..所以一定要安装正确版本2、cmd安装vue--router的版本,指定3版本npm i vue-router@33、vue-router是一个插件库,需要use。import VueRouter from 'vue-router'Vue.use(VueRouter)4、创建一个router文件夹,用于创建整个应用的路由器,创建一个index.js文件。1)、引入路由vue-routerimport  VueRouter from 'vur-router'2)、创建路由器const router=new VueRouter({ }) 3)、配置路径routes,path,表示显示的url路径的hash地址,component     表示那个hash地址显示对应的组件 // 创建一个路由器const router=new VueRouter({routes: [{path:'/hello',component:Hello}]
}) 4)、因为配置的component是组件上,所以我们还需要引入组件import Login from '@/components/Login.vue'import Regist from '@/components/Regist.vue'5)、暴露这个路由器export default router6)、简写export default new VueRouter({routes: [{path:'/hello',component:Hello}]
}) 7)、在main.js里面引入路由器import  router from '@/router'8)、使用router-link标签跳转路径,这个标签实际上就是a标签<router-link to="/login">Login</router-link>9)、这个时候页面没有展示出来。需要向slot插槽一样,给要显示组件的地方需要用到 router-view占位。组件一个router-view标签,表示router显示的页面展示在这个位置<router-view></router-view>10、这些定义了hash路径的组件都叫做路由组件

router的index.html

// 用于创建整个应用的路由器
import  VueRouter from 'vue-router'
// 引入组件
import Login from '@/components/Login.vue'
import Regist from '@/components/Regist.vue'// 创建一个路由器
export default new VueRouter({routes: [{path:'/login',component:Login},{path:'/regist',component:Regist}]}) 

main.js

// 引入残缺版的vue,残缺版的vue不能自己渲染页面
// 只有完整版的vue能够渲染,
// vue由两部分组成:核心(生命周期、路由)+模板解析器
// 节省空间,残缺版去掉了模板解析器,通过render函数
// 去渲染页面
import Vue from 'vue'
import App from './App.vue'import VueRouter from 'vue-router'
import  router from '@/router'Vue.use(VueRouter)Vue.config.productionTip = falsenew Vue({el:"#app",router:router,render:h=> h(App)})
// .$mount('#app')

App引入router

<template><div id="app"><nav><h2>App根组件</h2></nav><div class="box"><router-link to="/login" >Login</router-link></div><div class="txt"><router-link to="/regist" >Regist</router-link></div><div class="tt"><router-view></router-view></div></div>
</template><script>export default {name: "App",components: {},data() {return {}},};</script>
<style lang="less" scoped>
* {padding: 0;margin: 0;
}nav {width: 100%;height: 50px;background-color: #eee;
}.box {width: 100px;height: 30px;text-align: center;border: 1px solid #a1a0a0;}
.txt{width: 100px;height: 30px;text-align: center;border: 1px solid #a1a0a0;border-top: 0;
}</style>

21-5、路由注意点

1、配置了hash路径的组件都叫做路由组件2、这些路由组件一般放在pages文件夹下面。3、$route:这个组件的路由信息,每个路由组件都有。 route是单个路由,存放           当前路径信息,携带的参数4、$router:整个应用的路由器。只有一个路由器。 管理整个路由系统,里面保            存所有的路径信息,能够实现路由的跳转5、通过切换。“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载

21-6、嵌套路由

1、一级路由,定义在routes对象中,是routes对象的属性,被定义为一级路      由。2、多级路由是一级路由的孩子。使用routes的children属性定义,children是一个数组,里面可以配置多个对象,对象的写法和以及路由是一样的。是被定义在一级路由为代表的路由组件里面的路由组件。children里面不用添加 /{path:'/regist',component:Regist,children:[{path:'home',component:Home}]},3、使用的时候,记得to属性加上完整路由。<router-link to="/regist/home">Home组件</router-link>

21-7、路由传参

1、路由跳转的时候可以传递参数,而跳转到的那个路由组件可以接收到值传递的这个参数值。<router-link to="/regist/home/hello?id=01"> {{ item.name }}</router-link>2、每个路由组件都有一个this.$route对象,有关于这个路由组件的很多多信息。<li>学生学号{{ $route.query.id}}</li>3、动态展示传递过去的参数,使用属性绑定v-bind绑定to属性,让字符串变成动态表达式,然后使用模板语法用 ` `括起来,把name属性=对象的id属性,使用${}。让这句话变成模板字符串。这是跳转路由携带query参数的to的字符串写法<router-link:to="`/regist/home/hello?id=${item.id}&name=${item.name}`"
> {{ item.name }}</router-link>4、跳转路由并携带query参数to的对象写法,path代表路径,表示你跳转的路由组件的地址,还有query参数,query是一个对象,里面装的就是要携带的参数,这样写的好处是简单明了<router-link :to="{path:'/regist/home/hello',query:{id:item.id,name:item.name}}">{{ item.name  }}</router-link>

21-8、命名路由

1、name是什么呢?name 是配置路由时给 path 取的别名,方便使用。但要注意的是 “地址栏显示的路径始终是 path 的值”.可以简化代码,就在routes设置里面添加一个name属性。{name:'login',path:'/login',component:Login,},2、这个name属性可以简化代码。比如说路径跳转的时候我们使用path进行路径跳转。//在routes设置跳转的 路由的name属性{name:'login',path:'/login',component:Login,},//路由跳转:通过name属性跳转<router-link :to="{name:'hello',query:{id:item.id,name:item.name}}">{{ item.name  }}</router-link>

21-9、params参数

字符串写法
1、在跳转前的组件通过to属性使用/传递参数,但是要在路径的path属性里面去声明这是接收参数。通过占位符来声明,跳转到的路由组件接收参数的写法也不一样。//传递固定格式的数据的写法<router-link :to="`/regist/home/hello/007/王老五`">{{ item.name}}</router-link>//传递动态数据的写法<router-link :to="`/regist/home/hello/${item.id}/${item.name}`">{{ item.name}}</router-link>2、在路由组件的路由设置里面通过占位符声明接收的参数。这些数据就会放在params对象里面。path:'hello/:id/:name',3、路由组件接收的参数的方式,通过params对象去接收:<li>学生学号{{ $route.params.id}}</li>  对象写法必须把path换成name就可以了。不能使用path,然后query对象的参数换成params对象设置传递的数据参数4、解决路由组件接收参数写死的情况,路由的props配置:,在路由里面设置,使用rpops参数去接收,1//第一种写法,值为对象,{name:'hello',path:'hello/:id/:name',component:Hello,//    props的第一种写法,值为对象,该对象// 所有key-value都以props形式传递给这个hello组件props:{a:1,str:"小红"}}路由组件通过props接收这个两个变量的值props:['a','str'],组件可以直接使用这两个数据,但是,这是写死的数据,不推荐使用<li>{{ a}}</li><li>{{ str }}</li>2//第二种写法,值为布尔值,// props的第二种写法,值为布尔值,若布尔值为真// 就会把该路由收到的所有的params参数以props// 的形式转给该路由组件{name:'hello',path:'hello/:id/:name',component:Hello,              // props的第二种写法,值为布尔值,若布尔值为真// 就会把该路由收到的所有的params参数以props/ 的形式转给该路由组件props:true}  引用路由组件的字符串写法<router-link :to="`/regist/home/hello/${item.id}/${item.name}`">{{ item.name}}</router-link> 路由组件通过props接收这个两个变量的值props:['id','name'],组件可以直接使用这两个数据,但是,这是写死的数据,不推荐使用<li>学生学号{{ id}}</li><li>学生姓名{{ name}}</li>对象写法<!-- 6、路由跳转携带params 参数,引用路由的组件对象写法写法--><router-link :to="{name:'hello',params:{id:item.id,name:item.name}}">{{ item.name}}</router-link>4)如果把路径删了,想转成query参数。通过props接收,不能使用props接收的数据,会告诉你属性未定义,只能通过query对象使用数据引用路由的组件设置跳转路由<!-- 7、跳转路由由query 接收props传递的数据 --><router-link :to="{name:'hello',query:{id:item.id,name:item.name}}"> {{ item.name }}</router-link>路由组件接收传递的参数的写法<li>学生学号{{ $route.query.id}}</li><li>学生姓名{{ $route.query.name}}</li>路由设置{name:'hello',// path:'hello/:id/:name',path:'hello',component:Hello,// 如果把路径删了,想转成query参数。通过props接收。props:true}5)props的第三种方法:值为函数。// props的第三种写法:值为函数,//值为函数的第一种写法// props(){//  这是写死的用法。这个props传递的数据既不在params//里面,也不在query里面//   return {id:11,name:"小兰"}/  }//值为函数的第二种写法:// 传入route对象,就可以使用query里面的参数传递数据 props($route){// 这是写死的用法。这个props传递的数据既不在params//    里面,也不再query里面return {id:$route.query.id,name:$route.query.name}}//值为函数的第三种写法:// 解构query对象,使用里面的数据props({query}){return {id:query.id,name:query.name}}//值为函数的第四种写法:// 再解构赋值props({query:{id,name}}){return {id,name}}5、props的作用:让路由组件更方便的收到参数,既适用于params也适用于  query

21-10、params和query的不同

  在Vue路由中,query和params都是用于向路由添加附加信息的方式。query通常用于传递查询字符串,而params则用于传递路由参数。query通过URL中的“?”传递附加信息,而params则在路由路径中传递,例如“/users/:id”。params可以使用$router.push()来更改,而query则使用$router.replace()。查询参数和路由参数在Vue的$route对象中都可以使用,但是路由参数更适用于表示唯一标识符,例如用户ID,而查询参数更适合用于分页或搜索过滤器等用途

21-11、路由跳转的两种导航方式

1、声明式导航,在浏览器中,点击链接实现导航的方式,叫做声明式导航。例如:普通网页中点击a链接,vue项目中点击<router-link>都属于声明式导航2、 编程式导航在浏览器中,调用API方法实现导航的方式,叫做编程式导航。例如:普通网页中调用location.href 跳转到新页面的方式,都属于编程式导航作用:不借助<router-link>实现路由跳转,让路由跳转更加灵活      

21-12、router-link的replace属性

1、路径以push模式增加为历史记录,一条条路径重叠,不破坏任何一条路径。最新的页面在最上面2、replace属性直接替换当前路径页面,不会生成页面记录,写法,直接添加replace属性,在router-link里面。<router-link replaceto="/regist/home">Home组件</router-link>3、总结:replace属性的作用1)、作用:控制路由跳转时操作浏览器历史记录的模式2)、浏览器的历史记录有两种写入方式,分别为push和replace,push是追加历史记录,replace是替换当前记录,路由默认为push3)、开启replace模式的方法:在router-link里面添加replace属性。

21-13、编程式导航

1、在浏览器中,调用API方法实现导航的方式,叫做编程式导航。例如:普通网页中调用location.href 跳转到新页面的方式,都属于编程式导航2、使用路由器:$router的api方法跳转pushShow(m){this.$router.push({name:'hello',query:{id:m.id,name:m.name}})},replaceShow(m){this.$router.replace({name:'hello',query:{id:m.id,name:m.name}})}
3、使用路由器方法的前进后退:this.$router.backthis.$router.forward4、编程式导航的作用:不借助router-link实现路由跳转,让路由跳转更灵活

21-14、缓存路由组件

1、通过keep-alive:让不展示的组件保持挂载,不被销毁2、是在路由router-link里面指定,include属性指定哪个组件被挂载3、缓存多个组件的写法:include="['组件1','组件2']"

21-15、路由组件相关的生命周期

1、activated:激活时触发2、deactivated:失活时触发3、路由组件所独有的两个钩子,用于捕获路由组件的激活状态

21-16、全局路由守卫

1、路由守卫的作用:对路由进行权限控制,分类:全局守卫、独享守卫、组件内守卫。如果想实现登录注册后才能看见网站首页,就需要添加路由守卫2、第一步就是在路由组件里面选择不直接暴露router。而是直接定义一个router对象,const router=new VueRouter({
routes:[
{}
]
})//全局前置路由守卫,路由切换之前会调用
//初始化的时候调用
router.BeforeEach((to,from.next)=>{})3、to和from是去的路由组件和前一个路由组件,里面是路由组件的相关信息。next()表示放行,如果不放行,是不会执行到下一步,4、所以前置路由守卫一般是用来判断,是否登录注册过,才可以跳转页面,然后可以路由跳转到其他页面,to.name也可以if(to.path=='/login' || to.path =='/regist'){if(这里和数据库的会员数据做比对,一致的话就可以放行){next()}else{console.log("不能成功登录")}}5、meta:提供容器配置特殊的数据。称作路由原信息,配置程序员自己想配置的信息,可以用来作为验证路由守卫的信息。也可以用来做网页的title信息。const router=new VueRouter({
routes:[
{name:'hello',path:'/hello',component:Hello,meta:{isNext:true}}
]
})6、使用meta信息判定权限:
//判断是否需要鉴权if(to.meta.isNext){if(这里和数据库的会员数据做比对,一致的话就可以放行){next()}else{console.log("不能成功登录")}}7、全局后置路由守卫:初始化之后调用,每次切换之后调用,没有next,不需要放行。router.afterEach((to,from)=>{document.title=to.meta.title  || '网站'})

21-17、独享路由守卫

1、某一个路由单独想用的守卫。2、想设置独享路由守卫,在设置路由里面设置beforeEnter。表示进入这个路由之前。进行规则的对比,只对该路由组件做测试。routes:[
{name:'hello',path:'/hello',component:Hello,meta:{isNext:true},beforeEnter((to,from,next)=>{})}
]3、独享守卫只有前置没有后置,可以喝全局后置守卫搭配使用。

21-18、组件内路由守卫

1、beforeRouteEnter,路由组件使用的函数,通过路由规则,进入该组件时被调用。beforeRouteEnter(to,from.next){}2、beforeRouteleave,路由组件使用的函数,通过路由规则,离开该组件时被调用。beforeRouteleave(to,from.next){}

21-19、history模式与hash模式

1、hash值最大的特点:hash值不会因为http请求作为路径数据发给服务器,是程序员自己设置的路径2、可以通过在路由器里面设置mode属性,选择路由是history模式还是hash模式,默认是hash模式const router=new VueRouter({mode:'history',routes:[]})3、开启history模式后不会再有hash值。需要新开页签4、hash兼容性好,history兼容性较差。5、npm的中间件:connect-history-api-fallback专门解决history模式404的问题。6、总结;hash模式:1、地址中带着#号,不美观2、如果以后将地址通过第三方手机app分享,如果app校验严格,则地址会被标记不合法3、兼容性较好history模式:1、地址干净、美观2、兼容性和hash模式相比略差3、应用部署上线时需要后端人员支持,解决刷新页面服务器404问题

21-20、路由重定向

暂时省略

21-21、路由懒加载

暂时省略

22、minxin:混入

22-1-1、什么是混入

1、mixins(混入),官方的描述是一种分发 Vue 组件中可复用功能的非常灵活的方式 mixins 是一个 js 对象,它可以包含我们组件中 script 项中的任意功能选项,如:data、components、methods、created、computed 等等。我们只要将公用的功能以对象的方式传入 mixins 选项中,当组件使用 mixins 对象时所有 mixins 对象的选项都将被混入该组件本身的选项中来,这样就可以提高代码的重用性,并易于后期的代码维护

22-1-2、怎么使用mixin

1、当我们存在多个组件中的数据或者功能很相近时,我们就可以利用 mixins 将公共部分提取出来,通过 mixins 封装函数,组件调用他们是不会改变函数作用域外部的。
2、一样的方法我们把它提取出来放在一个公共的地方

22-1-3、如何创建mixin

1、在 src 目录下创建一个 mixins 文件夹,在文件夹下新建一个myMixins,js 文件。 因为 mixins 是一个 js 对象,所以应该以对象的形式  来定义 myMixins,在对象中可以和vue 组件一样来定义 data、components、methods、created、computed   等属性,  并通过 export 导出该对象。export表示分别暴露,如果需要在组件里面使用该混合,需要在该组件引入,因为是分别暴露,所以,需要以对象的形式暴露:import {mixin} from '../mixin'然后,所以我们使用mixins配置项去接收,因为有多个的mixin,所以数组形式接收,只有一个混合也这样写mixins:[mixin]
2、组件有的东西以组件为主,组件没有的以混合为主
3、生命周期mountend都会实现
4、功能:就是可以把多个组件共用的配置提取成一个混入对象

22-2、案例

export  const mixin={methods:{fn(){this.n++}}
}
<template><div>{{ n }}
<button @click="fn">按我+1</button></div>
</template><script>
import {mixin} from '../mixin'
export default {data(){return{n:2}},mixins:[mixin]}
</script>

22-3、定义全局混合

1、在main.js里面引入混合,然后使用Vue.mixin()就可以使用该混合里面的方法了import {mix}  from './mixin'Vue.mixin(mix)

23、过渡与动画

1、过渡与动画的作用:在插入或移除DOM元素的时候,在核实的时候给元素添加样式类名2、有进入的样式和离开的样式3、进入v-enter:进入的起点v-enter-active:进入过程中v-enter-to:进入的终点4、离开v-leave:离开的起点v-leave-active:离开过程中v-leve-to:离开的终点5、进入的终点就是离开的起点6、使用transtion包裹想要过渡的元素,

23-1、动画

23-2-1、Vue动画的理解
1、设置来回切换的效果,vue用transtion包裹有动画效果的元素,设置进入的时候的的类名:v-enter-active,设置离开的时候的类名:v-leave-active。2、这个transtion还可以起名字,<transition name="tr"><nav v-show="flag">动画效果</nav></transition>3、如果给transtion起了名字,那么,v-enter-active就改成 transtion的名字-enter-active4、设置一开始就是动画效果,就给transtion设置一个appear属性,设置属性值为true,但是要通过v-bind进行绑定。不然的话是一个布尔值<transition name="tr" :appear="true"><nav v-show="flag">动画效果</nav></transition>5、transtion在vue解析的时候没有被解析,是给vue 设置动画的,动态给元素添加样式的动画效果
<template><div><button @click="flag=!flag">显示/隐藏</button><transition><nav v-show="flag">动画效果</nav></transition></div>
</template><script>
export default {data(){return {flag:1}}}
</script><style lang="less" scoped>
nav{width: 1000px;height: 100px;background-color: aquamarine;}
.v-enter-active{animation: trans 1s linear reverse;
}
.v-leave-active{animation: trans 1s linear ;
}@keyframes trans {from{transform: translateX(0%);}to{transform: translateX(-100%);}
}
</style>

23-2、过渡

1、vue提供了transtion的封装插件,在下列情形中,可以给任何元素和组件添加enter/leave过渡1、v-if2、v-show3、动态组件4、组件根节点过渡的类名
1、v-enter:进入的起点,在外边的盒子以左边坐标为开始,向右从-100%的位置开始2、v-enter-to:进入的终点,在里边的盒子以左边的坐标未开始,向左从0%的位置转3、v-leave:离开的起点,0%的位置开始转移4、v-leave-to:离开的终点,转移到-100%的位置5、给元素设置transtion。同样位置的一样的类名设置可以放在一起
<template><div><button @click="flag=!flag">显示/隐藏</button><transition ><nav v-show="flag">动画效果</nav></transition></div></template><script>export default {data(){return {flag:1}}}</script><style lang="less" scoped>nav{width: 1000px;height: 100px;transition: 2s linear;background-color: aquamarine;}.v-enter{transform: translateX(-100%);}.v-enter-to{transform: translateX(0%);}.v-leave{transform: translateX(0%);}.v-leave-to{transform: translateX(-100%);}</style>
22-2-1、多个元素过渡
1、 can only be used on a single element. Use <transition-group> for lists.transtion只能有一个元素,多个元素可以使用transtio-group2、transtion-group的元素必须有唯一的key值<transition-group name="tr" appear><nav v-if="flag" key="one">1</nav><nav v-if="flag" key="two">2</nav></transition-group>

22-3、动画库(使用第三方库写动画样式)

1、搜素npm.js官网,https://www.npmjs.com/2、在官网里面搜索animate.css,点击第一个https://www.npmjs.com/package/animate.css3、选择animate.stylehttps://animate.style/4、根据animate上面的步骤进行使用:1、安装,停止该项目,安装animate2、引入样式库import 'animate.css'3、复制粘贴类名,放在name属性上animate__animated animate__bounce4、给这个transtion指定进入和离开的类名,复制类名 字符串里面是自己喜欢的动画效果进入的类名:enter-active-class=””离开的类名:leave-active-class=””<transition-groupname="animate__animated animate__bounce" appearenter-active-class="animate__wobble"leave-active-class="animate__zoomOutDown"><nav v-if="flag" key="one">1</nav><nav v-if="flag" key="two">2</nav></transition-group>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1nGHkSMl-1686141820666)(C:\Users\Direct\Desktop\常用前端框架及工具\拓展学习资料\7-animate使用.PNG)]

23、Vue原理

23-1、MVVM

1、Vue坐着参考mvvm模型,m(model)代表模型,v(view)代表视图,模板,vm,视图模型,vue实例对象

23-2、数据代理

1、是否被枚举指的是是否可以被遍历出来2、数据代理:通过一个对象代理对另一个对象中属性的操作3、重点:Object.defineProperty,

24、配置代理

1、跨域,也就是违背了同源策略:主机名、协议名、端口号必须一致2、解决跨域的方法1.cors,后端人员添加特殊的响应头,2、jsonp,通过script标签,前端后端一起设置,只能设置get方法3、代理服务器,服务器和服务器之间传递数据不用ajax请求,使用的是http协议,而代理服务器的端口号和客户端的端口号这些是一致的,满足同源策略
服务器之间不受同源策略的影响3、代理服务器的几种方式:1、nginx2、借助vue-cli4、vue脚手架设置代理服务器的方式,在vue.config.js里面设置1、打开vuejs的官网,选择vue2文档,点击配置参考,选择devServer。procy,2、按照参考文档设置3、lintOnSave:false  //关闭语法检查//举例module.exports = {devServer: {//这里是告诉代理服务器等会在哪个服务器请求数据,在这里就开启了一个//代理服务器,所以设置的是请求数据的服务器端口proxy: 'http://localhost:4000'}}4、在axios请求数据的时候改变端口号,只改变自己的端口号,不改变请求路径。然后重启项目,比如服务器端口号是4000,但我们设置了代理服务器,axios请求的路径本来是4000,但我们改成本机端口号80880axios.get('http://localhost:4000')改:axios.get('http://localhost:8080')5、两个小问题:1、只能配置一个代理服务器2、没办法控制走不走代理,因为如果文件的public有路径文件,会优先获取public里面的。6、解决以上两个问题的方法,看官网第二种方法module.exports = {devServer: {proxy: {//第一个代理///api叫做请求前缀,如果请求前缀是api就走代理服务器'/api': {//target是服务器的路径target: '<url>',//用于支持websocket:ws: true,//true表示隐瞒自己的端口号,//用于控制请求头中的host值changeOrigin: true},//第二个代理'/foo': {target: '<other_url>'}}}
}注意:在这里因为设置了请求前缀,我们的axios也要作出相应改变,在端口号的后面添加请求前缀,其他的不会改变axios.get('http://localhost:8080/api')但是因为axios请求的路径会完整的带给服务器去请求数据,所以我们要去设置一个配置。//重写路径,它是一个对象格式,里面是key、value形式,表示所有以api开头的路径将被替换为空字符串pathRewrite:{'/api':''}7、第二种方法的优点:可以配置多个代理,且可以灵活的控制请求是否走代理缺点:配置稍微繁琐,请求资源时必须添加前缀

25、axios

25-1、项目中使用

1、在vue里面使用axios需要先安装axios,npm   i axios  -S2、在组件中引入import  axios from  'axios'3、调用方法​     axios.get()

25-2、axios拦截器

暂时省略

26、nanoid

1、使用nanoid可以给数据生成id,2、先引入import {nanoid} from 'nanoid'后使用,直接使用this.id=nanoid()

27、Vue UI组件库

27-1、移动端组件库

1、Vant
2、Cube  UI
3、Mint  UI

27-2、PC端常用UI组件库

1、element  UI
2、IView  UI

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/6907.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【coderwhy前端笔记 - 阶段六 VUE 】(整理版)(更新中2023.7.16)

coderwhy前端系统课 - 阶段六VUE (整理版)&#xff08;更新中2023.7.16&#xff09; 1. 前言 本文以coderwhy前端系统课 - 阶段六VUE为主。 一刷版本的笔记有些乱&#xff0c;目前还在二刷整理&#xff0c;同时参考了一部分其他的资料&#xff0c;并加上个人使用总结 建议使…

小红书内容传播之品牌推广,干货分析

对于一个品牌来说&#xff0c;想要做好信息传播&#xff0c;迅速抢占市场&#xff0c;找准战场非常重要。而小红书&#xff0c;很显然就是时下众多品牌&#xff0c;竞相进驻的平台。那么如何在小红书平台做好品牌推广呢&#xff0c;今天为大家解读下。 一、做好品牌推广的三大步…

小程序 分享卡片 禁止个人及群聊二次转发

遇到开发需求说&#xff0c;分享消息给好友及群聊&#xff0c;但不允许二次转发 查了好多资料 最后很简单的解决了 就是在onShareAppMessage方法中 加uni.showShareMenu和 wx.updateShareMenu这两个方法 就可以实现需求 onShareAppMessage(){var that this;uni.showShareM…

小红书APP群控实战

设备清单 魅蓝Note5 4台 sim卡 4张 USB连接线TypeC 4根 优越者(UNITEK)USB分线器带独立电源 1台 PC i5 8g内存 1台 无线路由器 1台 硬件环境 实景 软件环境 魅蓝NOTE5 Xposed Installer 3.1.5 Xposed Version 89 Just Trust Me 0.2 小红书APP 6.8 使用手机号注册小红书账号…

小红书数据平台:笔记爆文率提升的三大秘诀公式!

导语 对于小红书商家 / 博主来说&#xff0c;写出爆文就像买彩票&#xff0c;根本不能预知哪一篇会爆。2023年&#xff0c;小红书哪些内容会脱颖而出呢&#xff1f;我们又该如何把握热点趋势&#xff0c;实现优质内容转化出爆文~ 美妆作为小红书的长红赛道&#xff0c;本文我…

详解小红书引流小技巧和矩阵玩法

众所周知&#xff0c;在各大公共领域平台中&#xff0c;小红书这个平台可以说是最受品牌商家关注的战场之一。而且作为一个种草平台&#xff0c;相比其他平台&#xff0c;小红书用户搜索的目的性更加精准&#xff0c;那么我们如何才能将公域流量引导到个人领域并获得准确的流量…

3.27 分享两个在PC上浏览小红书内容的方法【玩赚小红书】

第一个&#xff1a;微信小程序 可以通过登录电脑端的微信&#xff0c;在微信里面搜索小红书小程序使用&#xff0c;同时也可以添加到桌面。 ​ ​ ​ 方法二&#xff1a;通过搜索引擎跳转 给大家分享一下如何在浏览器中搜索&#xff0c;&#xff08;以bing搜索引擎为例&…

小红书运营方案:从0到1的引流微信私域指南

前全国午和小伙伴在沟通,她做的是小红书旅游类项目,目的是用户流量,转微信私域。她面临的疑问,不止是小红书营销传播,还要打磨服务产物。 她自己做过几年运营,思路相对清晰,我也给她罗列了7个框架;后面在复盘时,我又增加了3个点。 她这个项目属于旅游类,偏向亲子旅…

抖音卡片/快手/小红书/h5浏览器/微博跳转微信/qq/微信公众号/指定链接

首先说明&#xff0c;本文内容及教程均转载自&#xff1a;抖音私信卡片系统源码搭建【图文教程】已经本人允许 功能说明&#xff1a; 抖音卡片跳转 微信 抖音卡片跳转 qq 抖音卡片跳转 微信公众号 抖音卡片跳转 指定网页链接 快手跳转 微信 快手跳转 qq 快手跳转 微信公众号 …

投放指南|小红书投放被限流,品牌该如何是好

前言 每当双十一来临&#xff0c;很多品牌就已经开始在九、十月加大小红书平台的投放笔记量&#xff0c;为双十一收割做准备。当然也有不少品牌和博主反应&#xff0c;这段时间有不少笔记出现了限流情况&#xff1a;互动量上不去&#xff0c;小眼睛数量也比之前少了非常多&…

小红书 程序员七夕礼物 - 微信每日早安推送 简单部署一键启动

更新&#xff1a;仓库wechat-push中介绍一种无需服务器的部署方式&#xff0c;注册使用码云流水线自动发送消息。没有服务器不会编程的小伙伴&#xff0c;推荐大家使用这种方式。 本文来自 小红书大佬七夕节的礼物 原版大佬的代码&#xff0c;配置有些分散&#xff0c;我将其统…

群发猫——外贸全社媒平台官方接口群发不封号

当你还没有开始的的时候别人已经开始了&#xff0c;当你在犹豫的时候别人已经走在成功的路上了&#xff0c;当你在决策的时候别人已经上岸了&#xff0c;当你还在考虑的时候 别人已经成功&#xff0c;走在时代前言的人&#xff0c;慢一步 &#xff0c;步步就慢&#xff0c;跟不…

基于vite4+pinia2模仿chatgpt移动端聊天模板Vue3MobileGPT

运用vite4.x构建mobile端仿chatgpt聊天实例Vue3-mobileGPT vue3-mobilegpt 基于 vite4vue3pinia2vue-routervant 等技术开发移动端仿ChatGPT智能聊天项目模板。支持lightdark两种主题&#xff0c;搭配vue3组件库Vant&#xff0c;界面简洁美观。 就前几天OpenAI就推出了IOS版Cha…

ChatGPT模板设计领取

含登录系统&#xff0c;数据库系统&#xff0c;后端系统&#xff0c;卡密系统&#xff0c;宣传系统。对接GPT3.5模型&#xff0c;API接口&#xff0c;服务器对接&#xff0c;标准UI设计&#xff0c;标准前端设计。 模板&#xff1a;chat.stellar.hk

让我们一起看看chatGPT的CSS代码水平

近日&#xff0c;chatGPT火爆了&#xff0c;我也看到了许多人说 人工智能 对前端的影响&#xff0c;在GPT-4发布时&#xff0c;也展示了GPT的代码能力–10秒钟根据图片上网页布局生成前端网页&#xff0c;也是非常强大了。在好奇心驱使下&#xff0c;我试了试chatGPT写前端CSS代…

作为一名前端开发,我们可以让chatGPT帮我们做什么?

您可以利用 ChatGPT 来帮助您完成以下任务&#xff1a; 自动生成代码注释&#xff1a; ChatGPT 可以根据您提供的代码片段生成对应的注释&#xff0c;帮助您解释代码的功能和实现细节。 /*** 计算两个数字的和* param {number} a 第一个数字* param {number} b 第二个数字* re…

6月城市之星领跑活动获奖名单已出炉

经过一个月的角逐&#xff0c;6月城市之星领跑活动上榜名单终于出炉啦&#xff0c;本次城市赛道是根据最后登陆且6月份有入围博客之星用户的城市一共368个城市&#xff0c;城市人数划分区间具体情况如下&#xff1a; 200以上城市2个&#xff0c;其中有一些博主的城市由于未获取…

刘慈欣谈 ChatGPT:我的看法,跟大家有些不一样...

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) 著名科幻作家刘慈欣在近日联合国大会上做演讲&#xff0c;他谈到了以 ChatGPT 为代表的人工智能可能会给人们带来的影响。 以下是大刘的主要观点&#xff1a; 首先&#xff0c;最明显的一点是人工智能…

雷军首谈ChatGPT:要么成为AI的主人,要么被AI淘汰!

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) 小米创始人雷军&#xff0c;最近在谈到ChatGPT时表示&#xff1a;“AI给人类带来的影响&#xff0c;远超以往任何一次技术革命。许多行业将被颠覆&#xff0c;一大批旧的岗位被AI取代&#xff0c;同时…

(大集合)AI工具和用法汇总—集合的集合

AI 工具和用法汇总 汇集整理 by Staok/瞰百&#xff0c;源于相关资料在我这慢慢越积累越多&#xff0c;到了不得不梳理的程度。 文中有许多内容作者还没有亲自尝试&#xff0c;所以很多内容只是罗列&#xff0c;但信息大源都已给出&#xff0c;授人以渔&#xff0c;欢迎 PR 补…