• Vue进阶:组件化编程(脚手架) - 万字总结精华整理(持续更新)


    Vue基础:Vue基础
    TodoList案例:Vue:实现TodoList案例
    cd /d 目标文件夹

    一、Vue组件化编程 components

    1.1 传统方式编写应用的弊端

    • 引用导致依赖关系混乱,难以维护
    • html中的代码复用率不高
      在这里插入图片描述

    1.2 组件式编写应用

    • 组件的概念:实现应用中局部功能代码和资源的集合

    • 组件不仅可以放css,html,js,还可以放mp4,mp3,文字格式等等

    • 组件的作用:复用编码,简化项目编码,提高运行效率
      在这里插入图片描述

    在这里插入图片描述

    二、非单文件组件

    2.1 使用组件的步骤

    • 一个文件中包含n个组件
    • 缺点 : 样式不能跟着组件走

    Vue中使用组件的三大步骤:

    1. 定义组件(创建组件)
    2. 注册组件
    3. 使用组件(写组件标签)

    1.如何定义一个组件?
    使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别
    区别如下

    • el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器
    • data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系
      备注:使用template可以配置组件结构

    2.如何注册组件?

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

    3.编写组件标签:

    ① 局部注册组件

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>一个重要的内置关系</title>
            <!-- 引入Vue -->
            <script type="text/javascript" src="../js/vue.js"></script>
       </head>
        <body>
    
            <div id="root">
    			<hr>
    			<!-- 第三步:编写组件标签 -->
    			<school></school>
    			<hr>
    			<!-- 第三步:编写组件标签 -->
    			<student></student>
               <student></student>
            </div>
        </body>
    
        <script type="text/javascript">
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
           //第一步:创建school组件
            const school = Vue.extend({ // 传入配置对象
                template:`
                   

    学校名称:{{schoolName}}

    学校地址:{{address}}

    `
    , // el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。 data(){ // data 函数式(普通函数),不能书写成对象时,使用对象式时,有引用关系 return { schoolName:'Tom', address:'北京昌平' } }, }) //第一步:创建student组件 const student = Vue.extend({ template:`

    学生姓名:{{studentName}}

    学生年龄:{{age}}

    `
    , //data一定要写成return的形式,因为return能返回一个新的对象 //而之前写的对象形式,如果组件被使用两次,那么两个组件实例使用的同一个data //a的data数据被修改时,因为数据代理,b中的data数据也被修改 data(){ return { studentName:'张三', age:18 } } }) new Vue({ el: "#root", //第二步:注册组件(局部注册) components:{ school, // 组件名 或者 组件名 school:创建组件时的名字 student } }) </script> </html>
    • 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

    在这里插入图片描述
    ② 全局注册组件
    Vue.component(‘hello’,hello) // 组件的名字 组件的位置

    <!DOCTYPE html>
    <html>
       <head>
       	<meta charset="UTF-8" />
       	<title>基本使用</title>
       	<script type="text/javascript" src="../js/vue.js"></script>
       </head>
       <body>
       	<div id="root">
       		<!-- 第三步:编写组件标签 -->
       		<school></school>
       		<!-- 第三步:编写组件标签 -->
       		<student></student>
       	</div>
    
       	<div id="root2">
       		<!-- 第三步:编写组件标签 -->
       		<hello></hello>
       	</div>
       </body>
    
       <script type="text/javascript">
       	Vue.config.productionTip = false
          
       	//第一步:创建hello组件
       	const hello = Vue.extend({
       		template:`
       			

    你好啊!{{name}}

    `
    , data(){ return { name:'Tom' } } }) //第二步:全局注册组件 Vue.component('hello',hello) // 组件的名字 组件的位置 //创建vm new Vue({ el:'#root2', }) </script> </html>
    • 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

    2.2 组件的注意事项

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

    2. 关于组件标签:
    第一种写法:
    第二种写法:
    备注: 不用使用脚手架时,会导致后续组件不能渲染

    3. 一个简写方式:
    const school = Vue.extend(options) 可简写为:const school = options

    2.3 创建组件简写形式*推荐

    单文件组件时,常用

    const hello = {
    	template:`
    		

    你好啊!{{name}}

    `
    , data(){ return { name:'Tom' } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.4 组件的嵌套

    • 子组件(student 组件)应该写在 父组件(school组件)的上面
    • 父组件(school组件)中使用 子组件(student 组件)

    ① school 父组件嵌套 student 子组件

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>一个重要的内置关系</title>
            <!-- 引入Vue -->
            <script type="text/javascript" src="../js/vue.js"></script>
       </head>
        <body>
    
            <div id="root">
            	//子组件不再页面引用,而在父组件中引用
    			<school></school>
            </div>
        </body>
    
        <script type="text/javascript">
            Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
           //创建 student 组件
    		const student = Vue.extend({
    			template:`
    				

    学生姓名:{{studentName}}

    学生年龄:{{age}}

    `
    , data(){ return { studentName:'张三', age:18 } }, }) //创建 school组件 const school = Vue.extend({ // 传入配置对象 //使用子组件 template:`

    学校名称:{{schoolName}}

    学校地址:{{address}}

    `
    , data(){ return { schoolName:'Tom学校', address:'北京昌平' } }, components:{ student, } }) new Vue({ el: "#root", components:{ school, } }) </script> </html>
    • 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

    在这里插入图片描述

    ②定义hello 组件,其与school平级

    <div id="root">
    	<school></school>
    	<hello></hello>
    </div>
    
    //定义hello组件
    const hello = Vue.extend({
    	template:`

    {{msg}}

    `
    , data(){ return { msg:'欢迎来和Tom一起学习!' } } }) new Vue({ el: "#root", components:{ school, hello, } })
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    开发中常用技巧 app组件

    作用: 用于管理应用里面所有的组件(vm之下,所有组件之上)

    <div id="root">
    	<app></app>
    </div>		
    
    //定义app组件
    const app = Vue.extend({
    	template:`
    		
    `
    , components:{ school, // 引入 school 组件, 不用在引用student 引用父组件即可 hello } }) //创建vm new Vue({ el:'#root', //注册组件(局部) 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

    在这里插入图片描述

    补充: 容器中也可什么都不写

    //创建vm
    new Vue({
    	template:'',
    	el:'#root',
    	//注册组件(局部)
    	components:{app}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.5 VueComponent构造函数

    关于VueComponent

    1. school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的

    2. 我们只需要写,Vue解析时会帮我们创建school组件的实例对象,
      即Vue帮我们执行的:new VueComponent(options)

    3. 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent

    4. 关于 this 指向:
      (1) 组件配置中:
      data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】
      (2) new Vue(options)配置中:
      data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】

    5. VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)
      Vue的实例对象,以后简称vm

    //不用看,只是怕后面复习不知道在说什么才粘贴进来的
    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>VueComponent</title>
    		<script type="text/javascript" src="../js/vue.js"></script>
    	</head>
    	<body>
    
    		<div id="root">
    			<school></school>
    			<hello></hello>
    			school	
    		</div>
    	</body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false
    		
    		//定义school组件
    		const school = Vue.extend({
    			name:'school',
    			template:`
    				

    学校名称:{{name}}

    学校地址:{{address}}

    `
    , data(){ return { name:'Tom', address:'北京' } }, methods: { showName(){ console.log('showName',this) } }, }) const test = Vue.extend({ template:`atguigu` }) //定义hello组件 const hello = Vue.extend({ template:`

    {{msg}}

    `
    , data(){ return { msg:'你好啊!' } }, components:{test} }) console.log('@',school) // Vue 的 VueComponent的构造函数 console.log('#',hello) // 每次调用都会 创建一个新的 构造函数对象 // 每次调用Vue.extend,返回的都是一个全新的VueComponent!!!! //创建vm const vm = new Vue({ el:'#root', components:{school,hello} }) </script> </html>
    • 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

    在这里插入图片描述

    vm 管理 一个一个的vc
    在这里插入图片描述

    2.6 Vue实例与组件实例

    vc有的功能vm都有,vm有一个功能vc就没有,vm可以通过el决定来为哪个容器服务,vc不可以
    在这里插入图片描述

    2.7 重要的内置关系

    1. 一个重要的内置关系:VueComponent.prototype.proto === Vue.prototype
    2. 为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法

    ① 原型相关知识

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>一个重要的内置关系</title>
    		<!-- 引入Vue -->
    		<script type="text/javascript" src="../js/vue.js"></script>
    	</head>
    	<body>
    
    		<div id="root">
    
    		</div>
    	</body>
    
    	<script type="text/javascript">
    		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    		
    		//定义一个构造函数
    	     function Demo(){
    			this.a = 1
    			this.b = 2
    		}
    		//创建一个Demo的实例对象
    		const d = new Demo()
    
    		console.log(Demo.prototype) // 函数身上的 显示原型属性 
    
    		console.log(d.__proto__) // 实例身上的 隐式原型属性  统统都指向的了一个对象 原型对象
    
    		console.log(Demo.prototype === d.__proto__)
    
    		//程序员通过显示原型属性操作原型对象,追加一个x属性,值为99
    		Demo.prototype.x = 99
    
           console.log('@',d.__proto__.x) // 在顺着这条线去找 或者 console.log('@',d.x) 
    		console.log('@',d) 
    
    	</script>
    </html>
    
    • 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

    在这里插入图片描述
    ② 内置关系 prototype.proto === Vue.prototype
    解释: 按照原型链的指向,实例的隐式原型属性,应该指向其缔造者的原型对象。故VC的隐式原型属性指向VC的原型对象,且VC的隐式原型属性本应该指向Object的原型对象,但这里VC的隐式原型属性却指向Vue的原型对象
    目的: 让组件实例对象(vc)可以访问到 Vue原型上的属性、方法

    在这里插入图片描述

    在Vue上的x能被组件school访问到

    <div id="root">
    	<school></school>
    </div>
    <script type="text/javascript">
    	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示
    	//在Vue上的x能被组件school访问到
    	Vue.prototype.x = 99
    
    	//定义school组件    本质 是VueComponent
    	const school = Vue.extend({
    		name:'school',
    		template:`
    			

    学校名称:{{name}}

    `
    , data(){ return { name:'Tom', } }, methods: { showX(){ //这里可以输出Vue上的x console.log(this) console.log(this.x) } }, }) //创建一个vm const vm = new Vue({ el:'#root', data:{ msg:'你好' }, components:{school} }) </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
    • 36
    • 37
    • 38
    • 39
    • 40

    三、单文件组件

    安装提示插件:vetur

    在这里插入图片描述
    ① Vue文件的基本结构

    安装插件后快捷键:

    <template>
    	 // 组件的结构 
    </template>
    
    <script>
    	// 组件交互相关的代码(数据、方法等等)
    </script>
    
    <style>
    	// 组件的样式
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ② 组件的定义 基本使用(简单使用)

    • school 组件
    <template>
    	<div class="demo">
    		<h2>学校名称:{{name}}</h2>
    		<h2>学校地址:{{address}}</h2>
    		<button @click="showName">点我提示学校名</button>	
    	</div>
    </template>
    
    <script>
    	 export default { // 默认暴露
    		name:'School', // 组件的名字
    		data(){
    			return {
    				name:'Tom', // 数据
    				address:'北京昌平'
    			}
    		},
    		methods: {
    			showName(){
    				alert(this.name)
    			}
    		},
    	}
    </script>
    
    <style>
    	.demo{
    		background-color: orange;
    	}
    </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
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • student 组件
    <template>
    	<div>
    		<h2>学生姓名:{{name}}</h2>
    		<h2>学生年龄:{{age}}</h2>
    	</div>
    </template>
    
    <script>
    	 export default {
    		name:'Student',
    		data(){
    			return {
    				name:'张三',
    				age:18
    			}
    		}
    	}
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • App组件
    <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
    • 19
    • 20
    • 21
    • 22

    ③ 创建vm:main.js

    import Vue from 'vue'
    import App from './App.vue'
    
    Vue.config.productionTip = false
    
    new Vue({
    	el:'#app',
    	//后续有介绍render函数
     	render: h => h(App)
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ④ 容器 index.html

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="UTF-8" />
    		<title>练习一下单文件组件的语法</title>
    	</head>
    	<body>
    		<!-- 准备一个容器 -->
    		<div id="root">
           	<App></App>
           </div>
    		<!-- Vue -->
    		<script type="text/javascript" src="../js/vue.js"></script>
           <!-- 先让模板出来在 引入main.js 入口文件-->
    		<script type="text/javascript" src="./main.js"></script>
    	</body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    逻辑:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    四、Vue脚手架cli

    cli官网

    4.1 创建Vue脚手架

    在cmd命令窗口下执行下列步骤
    1.全局安装@vue/cli
    npm install -g @vue/cli
    (过程中不用回车,容易报错,实在不动了再回车试试,等很久的建议配置淘宝镜像)
    2.创建项目
    切换到要创建项目的目录>,使用命令创建项目
    cd /d 目标目录
    vue create xxx (xxx为自定义项目名)
    3.选择运行环境(Vue2或3或自定义)
    在这里插入图片描述

    出现这个表示创建成功在这里插入图片描述

    4.启动项目
    cd vue_test
    npm run serve
    在这里插入图片描述
    5.访问项目
    可通过 http://localhost:8080/ 访问项目

    4.2 Vue脚手架结构

    在这里插入图片描述
    分析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">
    		<!-- 配置页签图标 -->
       <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    		<!-- 引入第三方样式 -->
    		<link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">
    		<!-- 配置网页标题 -->
       <title>硅谷系统</title>
     </head>
     <body>
    		<!-- 当浏览器不支持js时noscript中的元素就会被渲染 -->
       <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>
    
    • 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

    4.3 render函数

    关于不同版本的Vue

    1. vue.js与vue.runtime.xxx.js的区别
      (1) vue.js是完整版的Vue,包含:核心功能+模板解析器
      (2) vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器

    2. 因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用
      render函数接收到的createElement函数去指定具体内容

    ① main.js如果直接这么写会报错

    //引入Vue
    import Vue from 'vue'
    //引入App组件,它是所有组件的父组件
    import App from './App.vue'
    //关闭vue的生产提示
    Vue.config.productionTip = false
    
    
    //创建Vue实例对象---vm
    new Vue({
    	el:'#app',
    	template:``,
    	components:{App},
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
    ② 报错原因
    引入的vue是阉割版的vue,里面不包含模板解析器
    ③ 解决方法
    解决方法1:使用render(渲染)函数

    • render需要返回值
    • 可以接收参数
    //render写成最终简化方式的简化步骤如下
    // ① 完整写法
    new Vue({
    	el:'#app',
    	render(createElement) { 
    		return createElement('h1','你好啊')
    	}
    })
    // ② 没有使用到this可以写成箭头函数
    new Vue({
    	el:'#app',
    	render:(createElement)=> { 
    		return createElement('h1','你好啊')
    	}
    })
    // ③ 箭头函数左面含有一个参数 可以省略小括号
    new Vue({
    	el:'#app',
    	render:createElement=> { 
    		return createElement('h1','你好啊')
    	}
    })
    // ④ 箭头函数只有一句函数体,并且还return
    new Vue({
    	el:'#app',
    	render:createElement=> createElement('h1','你好啊')
    })
    // ⑤ createElement 使用字母替代 render:q=> q('h1','你好啊')
    new Vue({
    	el:'#app',
    	render:h=> h('h1','你好啊')
    })
    
    // 页面上成功返回
    
    • 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
    • 和创建的基础代码 参数 其实还不同
      h1是HTML中的内置元素,里面需要写具体的内容,需要传递第二个参数
      如果使用的是组件 就不用内容
    // 两个参数
    new Vue({
    	el:'#app',
    	render:h=> h('h1','你好啊') 
    })
    // 一个参数
    import App from './App.vue'
    
    new Vue({
    	el:'#app',
       // render函数完成了这个功能:将App组件放入容器中
    	render: h => h(App) // 不加入引号 读取变量
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    解决方法2:引入完整版本的Vue

    //引入Vue
    import Vue from 'vue/dist/vue'
    
    Vue.config.productionTip = false
    
    new Vue({
    	el:'#app',
    	template:`

    你好啊

    `
    , })
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    关于引入阉割版vue而不使用vue的原因
    举例:

    • 引入完整版vue:买装修材料 + 买工人,装修完成后还得养着工人
    • 引入阉割版vue:买装修材料 + 雇工人,装修完成后不用养工人

    但个人认为实在多此一举了,这个例子也不能让人信服,毕竟工人吃多少饭,完整版vue又能占多少空间?阉割与否就差那么一百多K,随便一张图片都几M了,真的省这么点大小的必要?多写这么个方法就为了解决这么个小问题太费劲了

    4.4 修改默认配置

    4.4.1 查看默认配置

    vue.config.js配置文件

    1. 使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
    2. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

    查看Vue的配置文件
    vue把核心的配置文件隐藏了,怕用户修改错误,项目跑不起来程序,查看核心配置文件命令:vue inspect > output.js
    运行这个命令后会出现 output.js 文件,默认进去报错,在开头加上const a = 就行
    在这里插入图片描述
    但要注意这个文件只是给你看,修改它并不能真的修改到配置

    4.4.2 修改Vue的默认配置

    • 官网左侧栏中的都可以进行修改:https://cli.vuejs.org/zh/config/
    • 新建vue.config.js 文件 和 package.json同级,在vue.config.js中书写需要修改的配置,程序读取时,会把vue.config.js中程序员书写的相关内容,与vue的核心配置文件进行整合,最核心的配置修改不到,之后需要重新的启动npm run serve
    //vue.config.js
    module.exports = {
      pages: {
        index: {
          //入口
          entry: 'src/main.js',
        },
      },
      lintOnSave:false, //关闭语法检查
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.5 ref属性

    1. 被用来个元素或子组件注册引用信息(id的替代者)
      • 应用在html标签上获取真实DOM元素
      • 应用在组件标签上获取组件实例对象(vc)
    2. 使用方式:
      • 打标识:

        ...

      • 获取:this.&refs.xxx
    <div>
    	<h1 v-text="msg" id="title"></h1>
    	<button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>
    	<School ref="sch"/>
    	<School id="sch"/>
    </div>
    
    
    <script>
    	export default {
    		name:'App',
    		components:{},
    		data() {
    		},
    		methods: {
    			showDOM(){
    				console.log(document.getElementById("title"))
    
    				console.log(this.$refs.title) 	//1 真实DOM元素
    				console.log(this.$refs.btn) 	//2 真实DOM元素
    				console.log(this.$refs.sch) 	//3 School组件的实例对象(vc)
    			}
    		},
    	}
    </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

    1 输出h1元素
    在这里插入图片描述
    2 school 用 ref 输出vc实例
    在这里插入图片描述

    3 school 用 id 输出school组件
    在这里插入图片描述

    4.6 props配置项(重要)

    1. 功能:让组件接受外部传过来的数据
    2. 传递数据:
    3. 接收数据:
      (1)简单声明接受:props:[‘name’]
      (2)限制类型:props:{name:String}
      (3)限制类型、限制必要性、指定默认值:

    备注: props是只读的,Vue底层会监测你是否有对props所接受而来的数据进行了修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,则重新复制一份数据到data中,再修改data中的数据即可

    4.6.1 使用proprs

    在app.vue中引入student 组件并传递参数

    <div>
    	<Student name="李四" sex="女" age="18"/>
    </div>
    
    • 1
    • 2
    • 3

    student 中的组件数据不能写死,方便不同学生复用

    <script>
    	export default {
    		name:'Student',
    		data() {
    			console.log(this)
    			return {
    				msg:'我是一名热爱学习的学生',
    			}
    		},
    		// 1.简单声明接收
    		props:['name','age','sex'] 
    		
    		// 2.接收的同时对数据进行类型限制
    		props:{
    			name:String,
    			age:Number,
    			sex:String
    		} 
    		// 3.接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
    		props:{
    			name:{
    				type:String, //name的类型是字符串
    				required:true, //name是必要的
    			},
    			age:{
    				type:Number,
    				default:99 //默认值
    			},
    			sex:{
    				type:String,
    				required:true
    			}
    		}	
    	}
    </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

    在这里插入图片描述

    如果操作传入过来的数据
    如:给年龄加一岁,使用普通参数传参会出现问题

    <div>
    	<h1>{{msg}}</h1>
    	<h2>学生姓名:{{name}}</h2>
    	<h2>学生性别:{{sex}}</h2>
    	<h2>学生年龄:{{age + 1}}</h2>
    	//直接这么做学生年龄的结果是181,而不是19
    </div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    解决办法:
    app.vue中绑定age 的值

    • age 表示的是字符串
    • :age 的值是运行 “18” js表达式 里面执行的结果
    <div>
    	<Student name="李四" sex="女" :age="18"/>
    </div>
    
    • 1
    • 2
    • 3

    4.6.2 注意事项

    1. 传入的参数不能随意声明

    <script>
    	export default {
    		name:'Student',
    		data() {
    			console.log(this)
    			return {
    				msg:'我是一名热爱学习的学生',
    			}
    		},
    		props:['name','age','sex','phone'] 
    	}
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    2. 外部传递的参数不能直接修改
    案例: 修改外部传递参数age的数值

    <template>
    	<div>
    		<h1>{{msg}}</h1>
    		<h2>学生姓名:{{name}}</h2>
    		<h2>学生性别:{{sex}}</h2>
    		<h2>学生年龄:{{age}}</h2>
    		<h2>学生年龄:{{myAge+1}}</h2>
    	</div>
    </template>
    
    <script>
    	export default {
    		name:'Student',
    		data() {
    			console.log(this)
    			return {
    				msg:'我是一名热爱学习的学生',
    				//用myAge去接收age
    				myAge:this.age // props 的优先级更高,能获取到
    			}
    		},
    		methods: {
    			updateAge(){
    				this.myAge++
    			}
    		},
    		//简单声明接收
    		props:['name','age','sex'] 
    	}
    </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

    4.7 mixin配置项(混入/混合)

    1. 功能:可以把多个组件共用的配置提取成一个混入对象
    2. 使用方式:
      • 定义混入
      {
      	data(){...},
      	methods: {...}
      	...
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 使用混入
        全局混入:Vue.mixin(xxx)
        局部混入:minxins:[‘xxx’]

    基本使用

    ① 观察 student.vue 和 school.vue可以看到有相同的代码段

    student.vue

    <template>
    	<div>
    		<h2 @click="showName">学生姓名:{{name}}</h2>
    		<h2>学生性别:{{sex}}</h2>
    	</div>
    </template>
    
    <script>
    
    	export default {
    		name:'Student',
    		data() {
    			return {
    				name:'张三',
    				sex:'男'
    			}
    		},
           methods: {
               showName(){
                   alert(this.name)
               }
           },
    	}
    </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

    school.vue

    <template>
    	<div>
    		<h2 @click="showName">学校名称:{{name}}</h2>
    		<h2>学校地址:{{address}}</h2>
    	</div>
    </template>
    
    <script>
    
    	export default {
    		name:'School',
    		data() {
    			return {
    				name:'Tom学校',
    				address:'北京',
    			}
    		},
           methods: {
               showName(){
                   alert(this.name)
               }
           },
    	}
    </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

    在这里插入图片描述
    ② 新建mixin.js(文件名可以自定义)

    //分别暴露
    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
    • 19

    ③ 向student.vue 和 school.vue 中分别引入并应用

    <script>
    	//引入一个hunhe
    	import {hunhe,hunhe2} from '../mixin'
    
    	export default {
    		name:'School',
    		data() {
    			return {
    				name:'Tom学校',
    				address:'北京',
    				x:666
    			}
    		},
    		//应用混合
    		mixins:[hunhe,hunhe2],
    	}
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    混合原则

    • Vue里没有而mixin中有的,将mixin中的混合给Vue
    • Vue和mixin都有的,以Vue中的优先
    • mounted 两者都有的,会都用,且mixin的会先使用
      生命周期不以任何人为主,都要,混合的生命周期在前

    全局混合

    main.js中引入,而Student.vue 和 School.vue都不进行引入
    所有的vc 和 vm 都会得到

    //main.js
    import {hunhe,hunhe2} from './mixin'
    Vue.mixin(hunhe)
    Vue.mixin(hunhe2)
    
    • 1
    • 2
    • 3
    • 4

    4.8 插件

    1. 功能:用于增强Vue
    2. 本质:包含install方法的一个对象,install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据
    3. 定义插件:
    对象.install = function(Vue, options){
    	//1. 添加全局过滤器
    	Vue.filter(....)
    	
    	//2. 添加全局指令
    	Vue.directive(...)
    	
    	//3.配置全局混入
    	Vue.mixin(...)
    	
    	//4. 添加实例方法
    	Vue.prototype.$myMethod = function(){...}
    	Vue.prototype.$myProperty = xxx
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 使用插件:Vue.user()

    定义一个Vue插件

    export default {
    	install(Vue,x,y,z){
    		console.log(x,y,z)
    		//全局过滤器
    		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
    				}
    			},
    		})
    
    		//给Vue原型上添加一个方法(vm和vc就都能用了)
    		Vue.prototype.hello = ()=>{alert('你好啊')}
    	}
    }
    
    • 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

    main.js —> 引入、应用插件 在vm之前

    //引入插件
    import plugins from './plugins'
    
    //应用(使用)插件  
    //1,2,3为使用者传参
    Vue.use(plugins,1,2,3)
    
    //创建vm
    new Vue({
    	el:'#app',
    	render: h => h(App)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.9 scoped样式

    1. 作用:让样式在局部生效,防止样式冲突
    2. 写法: