Vue基础第三天之“生命周期 、非单文件和单文件组件、组件嵌套、VC、创建vue脚手架、render函数、ref属性、props配置、mixin(混入)、插件、组件化编码流程、兄弟组件之间的通信”


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=\, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 
        一、生命周期_挂载流程
        1.beforeCreate在数据监测和数据代理之前
        2.created在数据监测和数据代理之后
        3.beforeMount未经vue编译-挂载之前  
        4.mounted经vue编译-挂载之后(一般,开启定时器,发送网络请求、订阅消息、绑定自定义事件、等初始化操作)

        二、生命周期_更新流程
        1.beforeUpdate数据更新之前,页面是旧的数据
        2.updated数据更新之后,页面是旧的数据
        
        三、生命周期_销毁流程
        1. vm.$destroy()完全销毁一个实例,清理它与其它实例的连接,解绑它的全部指令以及自定义事件监听器
        2.beforeDestroy销毁之前-在事件里面的所有对数据的更改,都不会对数据进行更新(一般,关闭定时器,取消订阅消息、解绑自定义事件等收尾操作)
        3.destroyed销毁之后-没什么用,被忽略

        四、生命周期总结
        1.常用的生命周期钩子:
		1-1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
		1-2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

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

        3.vm的生命周期
        3-1.
        将要创建==>beforeCreate在数据监测和数据代理之前
        创建完毕==>created在数据监测和数据代理之后

        3-2.
        将要挂载==>beforeMount未经vue编译-挂载之前  
        挂载完毕==>mounted经vue编译-挂载之后(一般,开启定时器,发送网络请求、订阅消息、绑定自定义事件、等初始化操作)

        3-3.
        将要更新==>beforeUpdate数据更新之前,页面是旧的数据
        更新完毕==>updated数据更新之后,页面是旧的数据

        3-4.
        将要销毁==>beforeDestroy销毁之前-在事件里面的所有对数据的更改,都不会对数据进行更新(一般,关闭定时器,取消订阅消息、解绑自定义事件等收尾操作)
        销毁完毕==>destroyed销毁之后-没什么用,被忽略



        五、非单文件组件
        什么是非单文件组件?
        一个文件中包含有n个组件!
        1.Vue中使用组件的三大步骤:
		1-1、定义组件(创建组件)
		1-2、注册组件
		1-3、使用组件(写组件标签)

		2、如何定义一个组件?
		使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
		区别如下:
		2-1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
		2-2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
		备注:使用template可以配置组件结构。

		3、如何注册组件?
		3-1.局部注册:靠new Vue的时候传入components选项
		3-2.全局注册:靠Vue.component('组件名',组件)

		4、编写组件标签:
		<school></school>


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

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

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

        七、组件嵌套
        1.标准的组件嵌套是在div中不写标签的,通过app标签去统一管理组件
        2.组件嵌套就是在组件里面
        2-1.声明组件
        2-2.注册组件,注册的位置为组件里,写components,把声明组件,写进去
        2-3.使用组件

        八、关于VueComponent:(需要了解构造函数)
		1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。

		2.我们只需要写<school/>或<school></school>,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。
        注意:vc和vm是有区别的,比如el

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

        十、单文件组件
        1.报错浏览器不能直接支持ES6的语法,比如:.vue文件浏览器是不能直接运行的,需要脚手架

        十一、创建vue脚手架
        1.安装脚手架npm install -g vue-cli 或者使用淘宝镜像使用cnpm

        2.创建项目vue create vue_test

        3.选择vue2.0版本(babel是ES6语法转ES5 eslint语法检查)

        4.cd vue_text进入项目

        5.npm run serve运行项目

        十二、分析脚手架结构
        0..gitignore是git的管理文件,哪些文件不想进行git管理

        1.babel.config.js
        配置babel这个ES6语法转ES5,需要配置一下,拿官方配置的就可以了

        2.package-lock.json包管理器
        dependencies包管理控制文件(以后安装这个版本的时候,可以最快的安装到指定版本)
        compat-data这个包是版本、下载地址、

        3.package.json配置说明书
        "lint": "vue-cli-service lint"语法检查,基本上不用

        4.README.md项目说明

        十三、render函数
        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函数去指定具体内容。
        3.render(createElent){//考虑到你引入的是个残缺版的vue  返回的是个函数
        4.render:q=> q('h1','你好啊')写法问题,因为只有一句省略了return
        5.为什么引入残缺版的vue,方便打包的时候,剔除残缺的vue,减少文件大小
        
        十四、修改默认配置
        1.使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh
        2.lintOnSave:false,//关闭语法检查

        十五、ref属性
        1. 被用来给元素或子组件注册引用信息(id的替代者)
        2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
        3. 使用方式:
        3-1. 打标识:```<h1 ref="xxx">.....</h1>``` 或 ```<School ref="xxx"></School>```
        3-2. 获取:```this.$refs.xxx```

        十六、props配置
        1.关于:age="18" 和 age="18",加:号的是动态绑定的值, 不加:是字符串
        1. 功能:让组件接收外部传过来的数据

        2. 传递数据:```<Demo name="xxx"/>```

        3. 接收数据:

        3-1. 第一种方式(只接收):```props:['name'] ```

        3-2. 第二种方式(限制类型):```props:{name:String}```

        3-3. 第三种方式(限制类型、限制必要性、指定默认值):

            ```js
            props:{
                name:{
                type:String, //类型
                required:true, //必要性
                default:'老王' //默认值
                }
            }
            ```

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


         十七、mixin(混入)
            1. 功能:可以把多个组件共用的配置提取成一个混入对象

            2. 使用方式:

            第一步定义混合:

                ```
                {
                    data(){....},
                    methods:{....}
                    ....
                }
                ```

                第二步使用混入:

                ​	全局混入:```Vue.mixin(xxx)```
                ​	局部混入:```mixins:['xxx']	```
            
        
         十八、插件

        1. 功能:用于增强Vue

        2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。

        3. 定义插件:

            ```js
            对象.install = function (Vue, options) {
                // 1. 添加全局过滤器
                Vue.filter(....)
            
                // 2. 添加全局指令
                Vue.directive(....)
            
                // 3. 配置全局混入(合)
                Vue.mixin(....)
            
                // 4. 添加实例方法
                Vue.prototype.$myMethod = function () {...}
                Vue.prototype.$myProperty = xxxx
            }
            ```

        4. 使用插件:```Vue.use()```

        十九、组件化编码流程(通用)
        1.实现静态组件:抽取组件
        2.展示动态数据
        2-1.数据的类型、名称是什么?
        2-2.数据保存在哪个组件?
        3.交互--从绑定事件监听开始

        二十、兄弟组件之间的通信
        1.借助父级进行通信

   -->
    <div id="root">
     <p v-text = 'n'></p>
      <p>当前显示的值为{{n}}</p>
      <button @click="nclick">n+1</button>
      <button @click="xiaohui">销毁vm</button>

      <h2 :style = '{opacity}'>欢迎学习vue</h2>
      <button @click="opacity = 1">透明度设置为1</button>
      <button @click="stopb">点我停止变化</button>

      <hr>
      <hello></hello>   
      <hr>
      <p>{{msg}}</p>
      <hr>
      <!-- 第三步:编写组件标签 -->
      <xuexiao></xuexiao>   
      <hr>
      <xuesheng></xuesheng>  
      <hr> 
      
    </div>
    <div id="root2">
     
    </div>

    <script type="text/javascript">
        Vue.config.productionTip = false//阻止 vue在启动时生成生产提示

        //第一步.创建组件school
        const school = Vue.extend({
            //el:#root,//组件定义时,一定不用写el配置项
            template:`
            <div>
            <h2>学校名称:{{schoolName}}</h2>
	        <h2>学校地址:{{address}}</h2>
            <button @click="showName">点我停止变化</button>

            </div>`,
            data(){
                return{
                    schoolName:'尚硅谷',
					address:'北京昌平'
                }
            },
            methods:{
                showName(){
                    alert(this.schoolName)
                    alert(this.x)
                }
            }
        })

        //第一步.创建组件student
        const student = Vue.extend({
            //el:#root,//组件定义时,一定不用写el配置项
            template:`
            <div>
            <h2>学生姓名:{{studentName}}</h2>
			<h2>学生年龄:{{age}}</h2>
            <school></school>
            </div>`,
            data(){
                return{
                    studentName:'小明',
                    age:'男',
                }
            },
            components:{
                school:school,
            }
        })
        const hello = Vue.extend({
            //el:#root,//组件定义时,一定不用写el配置项
            template:`
            <div>
            <h2>全局注册组件:{{studentName}}</h2>
			
            </div>`,
            data(){
                return{
                    studentName:'你好啊',
                }
            }
        })

        const app = Vue.extend({
            //el:#root,//组件定义时,一定不用写el配置项
            template:`
            <div>
                <student></student>  
                <hello></hello>  
            </div> 
            `,
            components:{
                student:student,
               
            }
           
        })

        Vue.component('hello',hello)
        Vue.prototype.x = 99

        new Vue({
            el:'#root2', 
            template:`
            <app></app>   
            ` ,
            components:{
                app:app,
            }
            
        })

        const vm = new Vue({
            el:'#root',
            // template:`
			// 	<div>
			// 		<h2>当前的n值是:{{n}}</h2>
			// 		<button @click="add">点我n+1</button>
			// 	</div>
			// `,
            components:{//第二步.注册组件(局部注册)
                xuexiao:school,
                xuesheng:student,
            },
            data(){
                return{
                    n:1,
                    opacity:1,
                    msg:'你好呀'
                }
            },
            methods: {
                nclick(){
                    console.log('是否解绑事件监听器')
                    this.n++
                },
                xiaohui(){
                    vm.$destroy()
                },
                stopb(){
                    this.$destroy()
                    // clearInterval(this.timer)
                }
            },
            watch:{
                n(){
                    console.log('n变了')
                }
            },
            beforeCreate() {//在数据监测和数据代理之前
                console.log('beforeCreate')
                // console.log(this)
                // debugger;
            },
            created() {//在数据监测和数据代理之后
                console.log('created')
                // console.log(this)
                // debugger;
            },
            beforeMount() {//未经vue编译-挂载之前  
                console.log('beforeMount')
                // console.log(this)
                // debugger;
                document.querySelector('p').innerHTML='哈哈'//修改dom元素,是不会有反应的

            },
            mounted() {//经vue编译-挂载之后-一般,开启定时器,发送网络请求、订阅消息、绑定自定义事件、等初始化操作
                // console.log('mounted')
                // console.log(this)
                // document.querySelector('p').innerHTML='哈哈'//修改dom元素,是有效的

                // debugger;
                this.timer = setInterval(() => {
					console.log('setInterval')
					this.opacity -= 0.01
					if(this.opacity <= 0) this.opacity = 1
				},16)
            },
            beforeUpdate() {//数据更新之前,页面是旧的数据
                // console.log('beforeUpdate')
                // console.log(this.n)
                // debugger;

            },
            updated() {//数据更新之后,页面是旧的数据
                // console.log('updated')
                // console.log(this.n)
                // debugger;
            },
            beforeDestroy() {//销毁之前-在事件里面的所有对数据的更改,都不会对数据进行更新
                // this.nclick()
                // console.log( this.n)
                // console.log('beforeDestroy')
                //一般,关闭定时器,取消订阅消息、解绑自定义事件等收尾操作
                clearInterval(this.timer)

                
            },
            destroyed() {//销毁之后-没什么用,被忽略
                console.log('destroyed')
                
            },
            
        })

        function Demo(){
            this.a = 1
            this.b = 2
        }
        const d = new Demo()
        console.log(Demo.prototype)//显示原型属性
        console.log(d.__proto__)//显示原型属性

        console.log(Demo.prototype === d.__proto__)

        //他们2个都指向-原型对象
        //程序员通过显示原型属性操作原型对象,追加一个x属性,值为99
        Demo.prototype.x = 99//通过Demo的显示原型属性,接触原型对象,给对象加x
        // console.log('@',d.__proto__.x)
        console.log('@',d)


    </script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值