• Vue超详宝典(第二部)--万字长文硬核发布


    都2022年了不会还有人不会vue吧

    快跟着js同学 学学vue吧

    本文章是Vue超详宝典的续集

    Vue生命周期

    1. 生命周期回调函数,生命周期函数,生命周期钩子
    2. Vue在关键的时候帮我们调用一些特殊名称的函数
    3. 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的
    4. 生命周期函数中的this指向的是vm或组件的实例对象

    小案例–>div 透明度渐变

    <div id="root">
    	{{name}}
    	<div :style={opacity}>
    		hello
    	div>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    new Vue({
    	el:'#root',
    	data:{
    		name:'小明',
    		opacity:1
    	},
    	// vue完成模板的解析并把初始值的真实dom元素放入页面后,挂在完毕调用mounted
    	mounted(){
    		setInterval(()=>{
    			this.opacity-=0.01
    			if(this.opacity<=0) this.opacity=1
    		},30)
    	}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    增加需求,现在想让渐渐消失的消失的效果能够随时停止

    <button @click="stop">点我停止button>
    <button  @click="opacity=1">点我恢复button>
    
    • 1
    • 2
    methods:{
    	stop(){
    		this.$destroy()
    	}
    },
    mounted(){
    	this.timer=setInterval(()=>{
    		this.opacity-=0.01
    		if(this.opacity<=0) this.opacity=1
    	},30)
    },
    beforeDestroy(){
    	console.log('vm即将跑路')
    	clearInterval(this.timer)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    生命周期示意图

    在这里插入图片描述

    beforeCreate(){
    	console.log("beforeCreate")
    },
    created(){
    	console.log("created")
    },
    beforeMount(){
    	console.log("beforeMount")
    },
    mounted(){
    	console.log("mounted")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    常用的生命周期钩子

    1. mounted 发送ajax请求,启动定时器,绑定自定义事件,订阅消息等【初始化操作】
    2. beforeDestroy :清除定时器,解除自定义事件,取消消息订阅等【收尾工作】

    销毁Vue实例

    1. 销毁后借助Vue开发者工具看不到任何信息
    2. 销毁后自定义事件会失效,但原生DOM事件依然有效
    3. 一般不会再beforeDestroy操作数据,因为即使操作数据,也不会再触发更新流程了

    Vue组件化编程

    传统方式带来的问题代码复用率低,且不好维护

    在这里插入图片描述

    组件方式

    在这里插入图片描述

    非单文件组件

    我们首先简要的说一下Vue中使用组件的三大步骤

    1. 定义或者叫做创建组件
    2. 注册组件(全局注册或者局部注册)
    3. 使用组件 (写组件标签)

    如何定义一个组件

    1. 使用Vue.extend(options) 创建,其中options和new Vue(options)时传入的那个options几乎一样,但是区别如下:
    2. el不要写 ,因为最终所有的组件都要被一个vm管理,由vm决定服务,由vm中的el决定服务哪个容器,.
    3. data必须要写成函数–避免组件被重复使用时,数据存在引用关系
    4. 使用template 可以配置组件结构

    如何注册组件

    1. 局部注册:靠new Vue的时候传入components选项
    2. 全局注册:靠Vue.component(‘组件名’,组件)

    编写组件标签

    <组件名></组将名>
    
    • 1

    案例演示

    <div id="root">
    	<!-- 3编写组件标签 -->
    	<school></school>
    	<hello></hello>
    	<hr>
    	<student></student>
    </div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    	Vue.config.productionTip=false
    	// 1创建school 组件
    	const school=Vue.extend({
    		// 	el:'#root' 一定不要写el配置项,
    		template:`
    		<div>
    			<h3>学校{{schoolName}}</h3>
    			<h3>地址{{address}}</h3>
    		</div>
    		`,
    		data(){
    			return{
    				schoolName:'Vue学院',
    				address:'B站'
    			}
    		}
    	})
    	// 创建student 组件
    	const student=Vue.extend({
    		// 	el:'#root' 一定不要写el配置项理,
    		template:`
    		<div>
    			<h3>学生{{studentName}}</h3>
    			<h3>年龄{{age}}</h3>
    		</div>
    		`,
    		data(){
    			return{
    			   studentName:'小明',
    			   age:12
    			}
    		}
    	})
    	// 1创建全局组件
    	const hello=Vue.extend({
    		template:`
    		<div>
    		<h2>{{name}}</h2>
    		</div>
    		`,
    		data(){
    			return{
    				name:'全局组件'
    			}
    		}
    	})
    	// 注册全局组件
    	Vue.component('hello',hello)
    	new Vue({
    		el:'#root',
    		// 2注册组件 (局部注册)
    		components:{
    			school:school,
    			student:student
    		}
    	})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    在这里插入图片描述

    组件的注意点

    关于组件名的注意事项

    1. 一个单词组组成:第一种写法(首字母小写) :school 第二种写法:首字母大写:School
    2. 多个单词组成:第一种写法kebab-case命名 my-school 第二种写法:CamelCase命名 MySchool (但是需要脚手架)
    3. 组件名尽量回避HTML中已有元素的名称,例如 h2,H2都不行,可以使用name配置项指定组件在开发者工具中呈现的名字

    组件标签的使用和注意事项

    1. 第一种写法:
    2. 第二种写法:
    3. 不使用脚手架时,会导致后续组件不能渲染
    4. 一个简写方式const school= Vue.extend(options) 可以简写为const school=options

    组建的嵌套

    组件可以像这幅图一样进行嵌套
    在这里插入图片描述

    <div id="root">
    	
    	<app>app>
    div>
    
    • 1
    • 2
    • 3
    • 4
    Vue.config.productionTip=false
    // 创建student组件作为school的子组件
    // 子组件一定要在调用之前也就是父组件之前初始化完毕
    const student=Vue.extend({
    	name:'student',
    	template:`
    	

    学生{{studentName}}

    年龄{{age}}

    `
    , data(){ return{ studentName:'小明', age:12 } } }) // 1创建school组件student的父组件 const school=Vue.extend({ template:`

    学校{{schoolName}}

    地址{{address}}

    `
    , data(){ return{ schoolName:'Vue学院', address:'B站' } }, // 注册子组件 components:{ student:student } }) // 创建hell组件 const hello=Vue.extend({ name:'hello', template:`

    {{name}}

    `
    , data(){ return{ name:'hello组件' } } }) // 创建一个app组件作为管理组件 const app=Vue.extend({ name:'app', template:`
    `
    , components:{ hello, school } }) new Vue({ el:'#root', // 2注册组件 (局部注册) components:{ app } })
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    在这里插入图片描述

    VueComponent

    1. school 组件本质是一个为VueComponent的构造函数,是Vue.extend生成的
    2. 我们只需要写 或者 Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)
    3. 每次调用Vue.extend返回的都是一个全新的VueComponent

    关于this的指向

    1. 组件配置中:data函数,methods中的函数,watch中的函数,computed中的函数,它们的this均是【VueComponents实例对象】
    2. .new Vue(options)配置中data函数,methods中的函数,watch中的函数,computed中的函数,它们的this均是【Vue实例对象】
    3. VueComponent 的实例对象,以后简称vc也可以简称为组件实例对象

    重要的内置关系

    1. 一个重要的内置关系,VueComponent.prototype.__proto__===Vue.prototype
    2. 为什么要有这个关系,让组件实例对象vc可以访问到Vue原型上的属性,方法。
      在这里插入图片描述
    // 定义一个构造
    function Demo(){
    	this.a=1
    	this.b=2
    }
    // 创建一个Demo的实例对象
    const d=new Demo()
    // 显示原型属性
    console.log(Demo.prototype)
    // 隐式原型属性
    console.log(d.__proto__)
    // 显示原型属性操作原型对象,追加一个x属性
    Demo.prototype.x=99
    console.log('@'+d.__proto__.x)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    单文件组件

    首先我们应该先知道单文件组件是个啥?

    据我所了解这个单文件组件就是一个个后缀名为 .vue的文件原本的代码都放在html,css ,js 中但是现在可以放在.vue文件中我们将之前写的非单文件组件写成单文件组件。

    学校模块

    <template>
    	<div>
    		<h3>学校{{schoolName}}</h3>
    		<h3>地址{{address}}</h3>
    	</div>
    </template>
    
    <script>
    	export default{
    	   name:'School',
    	   data(){
    			return{
    				schoolName:'Vue学院',
    				address:'B站'
    			}
    		}
    	}
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    学生模块

    <template>
    	<div id="abc">
    		<h3>学生{{studentName}}</h3>
    		<h3>年龄{{age}}</h3>
    	</div>
    </template>
    
    <script>
    	export default{
    	 name:'Student',
    	 data(){
    		return{
    		   studentName:'小明',
    		   age:12
    		}
    	}
    }
    </script>
    
    <style>
    	#abc{
    		background-color: aqua;
    	}
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    App.vue

    <template>
    	<div>
    		<School></School>
    		<Student></Student>
    	</div>
    </template>
    
    <script>
    	import School from './School.vue'
    	import Student from './Student.vue'
    	export default{
    		name:'App',
    		components:{
    			School,
    			Student
    		}
    	}
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    import App from './App.vue'
    new Vue({
    	el:'root',
    	template:``
    	components:{App},
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    但是现在运行并不能运行成功因为浏览器不认识我们写的东西,所以我们需要对我们写的.vue文件进行解析,这里我用到的是vue-cli脚手架,然后在脚手架里写的东西才可以被解析。

    vue脚手架以及目录结构简介

    vue create 脚手架名称
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

    现在将我们的组件放进脚手架中

    1. 将我们写的组件进行替换
    2. 运行npm run serve

    第一次运行说我的组件名不合乎规范?干

    在这里插入图片描述
    然后我直接修改配置将提示关掉

    找到vue.config.js修改配置

    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({
      transpileDependencies: true,
      //关闭eslint校验
        lintOnSave: false
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    render函数

    我们先把rander给注了用我们自己的方式写 template:, components:{App},
    在这里插入图片描述
    然后我们看一下报了一个错,大致的意思就是这个模板的编译不可用,如果说我们用的是vue.js怎么可能会出现这样的情况,所以我们Vue的导入模块发现了问题
    在这里插入图片描述
    从这里可以看出引入的是一个runtime版的js。

    关于vue的两个不同的版本

    1. vue.js是完整的Vue,包含着核心功能+模板解析器
    2. vue.runtime.xxx.js是运行版的Vue,只包含着核心功能
    3. vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容

    ref属性

    1. 被用来给元素或子组件注册引用信息(id的代替者)
    2. 应用在html标签上获取的是真实地DOM元素,应用在组件的标签上是组件的实例对象(vc)
    3. 使用方式:
    <template>
    	<div>
    		<h1 v-text="msg" ref="title"></h1>
    		<button ref="btn" @click="showDOM()">点我输出上方DOM元素</button>
    		<School ref="sch"></School>
    		<Student></Student>
    	</div>
    </template>
    
    <script>
    import School from './components/School.vue'
    import Student from './components/Student.vue'
    
    	export default{
    		name:'App',
    		components:{
    			School,
    			Student
    		},
    		data:{
    			return{
    				mas:'同学你好'
    			}
    		},
    		methods:{
    			showDOM(){
    				// 真实DOM元素
    				console.log(this.$refs.title)
    				console.log(this.$refs.btn)
    				// School组件的实例对象
    				console.log(this.$refs.sch)
    			}
    		}
    	}
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    props配置

    让组件接收外部传过来的数据

    1. 传递数据:
    2. 接收数据:第一种方式(只接受)props:['name'] ,
    3. 第二种方式(限制类型)props:{ name :String }
    4. 第三种方式(限制类型,限制必要性,指定默认值)
    props:{
     name:{
       type:String,//类型
       required:true.//必要性
       default:'老王' // 默认值
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    备注props是只读的,Vue底层会监视你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要进行修改,那么请复制props的内容到data中一份,然后去修改data中的数据

    
    
    <Student :age="19" name="张三">Student>
    
    • 1
    • 2
    • 3
    		<h3>学生{{name}}</h3>
    		<h3>年龄{{myAge}}</h3>
    		<button @click="updataAge">点击修改年龄</button>
    	</div>
    </template>
    
    <script>
    	export default{
    	 name:'Student',
    	 data(){
    		return{
    			msg:'我是个学生',
    			// 找了个中间变量来负责承上启下
    			myAge:this.age
    		}
    	},
    	methods:{
    		updataAge(){
    			this.myAge++
    		}
    	},
    	// 接收的同时对参数进行限制
    	props:{
    		name:String,
    		age:Number
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    mixin(混入)

    可以把多个组件共用的配置提取成一个混入对象

    使用方式:

    1. 定义混入:{ data() {....}, methods:{....} ...}
    2. 使用混入:全局使用 :Vue.mixin(xxx),局部使用:mixins:['xxx']

    现在假设在多个组件中都有一个相同的方法,我们想把这方法在外部抽取成一个

    在这里插入图片描述

    首先做一个混入

    export const hunhe={
    	methods:{
    		showName(){
    			alert(this.name)
    		}
    	},
    	mounted(){
    		console.log('你好啊')
    	}
    }
    export const hunhe2={
    	data(){
    		return {
    			x:100,
    			y:200
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    // 引入混入
    import {hunhe,hunhe2} from '../mixin.js'
    //使用混入
    mixins:[hunhe,hunhe2]
    ==============================================
    <!-- 正常引入方法即可 -->
    <button @click="showName">点我展示名字</button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    全局使用

    // 全局使用mixin 
    import {hunhe} from './mixin'
    Vue.mixin(hunhe)
    
    • 1
    • 2
    • 3

    Vue插件

    插件 (Plugins) 是一种能为 Vue 添加全局功能的工具代码。一个插件可以是一个拥有 install() 方法的对象,也可以直接是一个安装函数本身。安装函数会接收到安装它的应用实例和传递给 app.use() 的额外选项作为参数:

    const myPlugin = {
      install(app, options) {
        // 配置此应用
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    编写一个插件

    // plugins/i18n.js
    export default {
      install: (app, options) => {
        // 在这里编写插件代码
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    引入插件

    import plugins from './plugins'
    // 使用插件
    Vue.use(plugins)
    
    • 1
    • 2
    • 3
    export default{
    	install(Vue){
    		// 全局过滤器
    		Vue.filter('mySlice',function(value){
    			return value.slice(0,4)
    		}),
    		// 定义全局指令
    		Vue.directive('fbind',{
    			// 指令与元素绑定时 (一上来)
    			bind(element,binding){
    				element.value=binding.value
    			},
    			// 指令所在元素被插入页面时
    			inserted(element,binding){
    				element.focus()
    			},
    			// 指令所在的模板被重新解析时
    			update(element,binding){
    				element.value=binding.value
    			}
    		}),
    		// 全局混入
    		Vue.mixin({
    			data(){
    					return {
    						x:100,
    						y:200
    					}
    				}
    		})
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    scoped样式

    scoped有什么用

    scoped 属性是 style 标签上的一个特殊属性(布尔值)。表示当前style 里的样式只属于当前模块。(作用域、私有化的思想),关于css的作用域问题,即使是模块化编程下,在对应的模块的js中import css进来,这个css仍然是全局的。导致在css中需要加上对应模块的html的id/class 使用css选择器 保证css的作用域不会变成全局 而被其它模块的css污染。

    本文创作时间 一周
    创作不易,你们的点赞和关注便是对我的最大的支持
    连更中…

  • 相关阅读:
    python中not的用法
    Spark Rdd之mapToPair,flatMapToPair
    【MM32F5270开发板试用】基于MindSDK测试MM32F5270开发板IIC
    介绍rabbitMQ
    Nacos注册中心
    Kubernetes — 网络流量模型
    day01-ES6新特性以及ReactJS入门
    泰安ITSS认证流程,认证条件
    d玩转不变
    【笑小枫的SpringBoot系列】【十六】SpringBoot生成PDF
  • 原文地址:https://blog.csdn.net/weixin_51787261/article/details/126056754