3.Vue从入门到精通 (第三章 使用Vue脚手架)

Vue从入门到精通 (第三章 使用Vue脚手架)

  • 第三章. 使用Vue脚手架
    • 3.1 初始化脚手架
      • 3.1.1 说明
      • 3.1.2 具体步骤
    • 3.2 分析脚手架结构
    • 3.3 修改默认配置( 修改后重新运行npm run serve命令 )
    • 3.4 ref属性
    • 3.5 props属性
    • 3.6 mixin混入
      • 3.6.1 局部混合
      • 3.6.2 全局混合
    • 3.7 插件
    • 3.8 scoped
    • 3.9 Todo-list案例
    • 3.10 浏览器本地存储
      • 3.10.1 localStorage
      • 3.10.2 sessionStorage
    • 3.11 组件的自定义事件
      • 3.11.1 绑定自定义事件
      • 3.11.2 解绑自定义事件
      • 3.11.3 自定义事件总结
    • 3.12 全局事件总线
    • 3.13 消息订阅与发布
    • 3.14 $nextTick
    • 3.15 动画
    • 3.16 过渡
      • 3.16.1 单个元素的过渡
      • 3.16.2 多个元素的过渡
    • 3.17 集成第三方动画

第三章. 使用Vue脚手架

3.1 初始化脚手架

3.1.1 说明

  • Vue脚手架时是Vue官方提供的标准化开发工具(开发平台)
  • 最新的版本是4.x
  • 文档: https://cli.vuejs.org/zh/

3.1.2 具体步骤

第一步(仅第一次执行):全局安装@vue/cli

npm install -g @vue/cli

第二步:切换到你要创建项目的目录,然后使用命令创建项目

vue create 项目名称

第三步:启动项目

npm run server

备注:

  1. 如出现下载缓慢请配置npm淘宝镜像:npm config set registry https://registry.npm.taobao.org

  2. Vue脚手架隐藏了所有webpack相关的配置,若想查看具体的webpakc配置,请执行:

    vue inspect > output.js (但是output配置文件仅可以查看,并不能直接在上面修改)

  

3.2 分析脚手架结构

脚手架文件结构

  ├── node_modules 
  ├── public
  │  ├── favicon.ico: 页签图标
  │  └── index.html: 主页面
  ├── src
  │  ├── assets: 存放静态资源
  │  │  └── logo.png
  │  │── component: 存放组件
  │  │  └── HelloWorld.vue
  │  │── App.vue: 汇总所有组件
  │  │── main.js: 入口文件
  ├── .gitignore: git版本管制忽略的配置
  ├── babel.config.js: babel的配置文件
  ├── package.json: 应用包配置文件 
  ├── README.md: 应用描述文件
  ├── package-lock.json:包版本控制文件

3.3 修改默认配置( 修改后重新运行npm run serve命令 )

vue.config.js配置文件

  1. 脚手架默认的配置文件是隐藏的,使用vue inspect > output.js可以查看到Vue脚手架的默认配置。

  2. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh

vue.config.js 文件 直接放入到根目录下,需要覆盖的配置写入文件即可,脚手架会自动进行合并,覆盖原来默认的配置

module.exports = {
  pages: {
    index: {
      //入口
      entry: 'src/main.js',
    },
  },
	lintOnSave:false, //关闭语法检查
}

3.4 ref属性

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第1张图片





总结:

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

.....

```或 `````` 2. 获取:```this.$refs.xxx```

3.5 props属性

<template>
    <div class="school">
        <h1>{{msg}}</h1>
        <h2>学生姓名:{{name}}</h2>
        <h2>学生年龄:{{myAge}}</h2>
        <button @click="addAge">增加年龄</button>
    </div>
</template>

<script>
export default {
    name:"School",
    data(){
        return {
            msg:'我就一学生',
            myAge:this.age
        }
    },
    methods:{
        addAge(){
            this.myAge++
        }
    },
    // 简单声明接收, 最常用
    props:['name', 'age'] 

    // 接收的同时对数据类型进行限制
    // props:{
    //     name:String,
    //     age:Number
    // }

    // 接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
    // props:{
    //     name:{
    //         type:String,
    //         required:true  // 设置必填项
    //     },
    //     age:Number,
    //     default:99  // 设置默认值
    // }
}
</script>

props总结:

1. 功能:让组件接收外部传过来的数据
2. 传递数据:
3. 接收数据:
    1. 第一种方式(只接收):props:['name'] 
    2. 第二种方式(限制类型):props:{name:String}
    3. 第三种方式(限制类型、限制必要性、指定默认值):
        props:{
        	name:{
        	type:String, //类型
        	required:true, //必要性
        	default:'老王' //默认值
        	}
        }

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

3.6 mixin混入

混入就是:如果两个或多个文件中有相同的代码,那么可以将相同的代码抽离出来,形成一个文件,在需要的地方引入这个文件,实现原本的功能

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第2张图片

3.6.1 局部混合

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第3张图片

对于data以及methods等来说,如果混合文件中有,原文件中也有,那么就以原文件为主,

对于生命周期函数来说,如果混合文件和源原文件都有,那么全都要

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第4张图片

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第5张图片

3.6.2 全局混合

一旦使用全局, vm以及各个vc上全部具备混合文件中所具备的特征

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第6张图片

总结:

1. 功能:可以把多个组件共用的配置提取成一个混入对象
2. 使用方式:
    第一步定义混合:
    {
        data(){....},
        methods:{....}
    }

    第二步使用混入:
    ​	全局混入:Vue.mixin(xxx)
    ​	局部混入:mixins:['xxx']

3.7 插件

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第7张图片

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第8张图片

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第9张图片

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第10张图片
3.Vue从入门到精通 (第三章 使用Vue脚手架)_第11张图片

3.8 scoped

编码时在不同组件中写的样式都会被汇总到一起,因此会产生一个问题是,如果两个组件中的样式名字相同,那么就会产生冲突,冲突后会按照先后引入组件的次序不同,后引入组件会覆盖前面引入组件的样式

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第12张图片

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第13张图片

注意:App.vue比较特殊,其内部写的style不但要自己使用,也要为别的组件使用,因此一般不用scoped修饰

3.9 Todo-list案例

1. 组件化编码流程:
    ​	(1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
    ​	(2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
    ​			1).一个组件在用:放在组件自身即可。
    ​			2). 一些组件在用:放在他们共同的父组件上(状态提升)。
    ​	(3).实现交互:从绑定事件开始。
2. props适用于:
    ​	(1).父组件 ==> 子组件 通信
    ​	(2).子组件 ==> 父组件 通信(要求父先给子一个函数)
3. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
4. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。

3.10 浏览器本地存储

3.10.1 localStorage

<!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>localStorage</title>
</head>
<body>
    <h2>localStorage</h2>
    <button onclick="saveData()">点击保存数据</button>
    <button onclick="readData()">点击读取数据</button>
    <button onclick="deleteData()">点击删除数据</button>
    <button onclick="deleteAllData()">点击清空数据</button>

    <script>
        function saveData(){
            let p = {name:'张三', age:18}
            // window可省略
            window.localStorage.setItem("msg","hello!!")
            localStorage.setItem("msg2",666)   // 即使是数字,保存的时候也会转成字符串
            window.localStorage.setItem("person",JSON.stringify(p))
        }

        function readData(){
            console.log(localStorage.getItem('msg'))

            const result = localStorage.getItem("person")  // 如果数据不存在,那么就返回null
            console.log(JSON.parse(result))  // 数据不存在时,JSON.parse解析也为null
        }

        function deleteData(){
            localStorage.removeItem("msg")
        }

        function deleteAllData(){
            localStorage.clear()
        }
    </script>
</body>
</html>

3.10.2 sessionStorage

<!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>sessionStorage</title>
</head>
<body>
    <h2>sessionStorage</h2>
    <button onclick="saveData()">点击保存数据</button>
    <button onclick="readData()">点击读取数据</button>
    <button onclick="deleteData()">点击删除数据</button>
    <button onclick="deleteAllData()">点击清空数据</button>

    <script>
        function saveData(){
            let p = {name:'张三', age:18}
            // window可省略
            window.sessionStorage.setItem("msg","hello!!")
            sessionStorage.setItem("msg2",666)   // 即使是数字,保存的时候也会转成字符串
            window.sessionStorage.setItem("person",JSON.stringify(p))
        }

        function readData(){
            console.log(sessionStorage.getItem('msg'))

            const result = sessionStorage.getItem("person")  // 如果数据不存在,那么就返回null
            console.log(JSON.parse(result))  // 数据不存在时,JSON.parse解析也为null
        }

        function deleteData(){
            sessionStorage.removeItem("msg")
        }

        function deleteAllData(){
            sessionStorage.clear()
        }
    </script>
</body>
</html>

总结:

  1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)

  2. 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。

  3. 相关API:

    1. xxxxxStorage.setItem('key', 'value');
      该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。

    2. xxxxxStorage.getItem('person');

      ​ 该方法接受一个键名作为参数,返回键名对应的值。

    3. xxxxxStorage.removeItem('key');

      ​ 该方法接受一个键名作为参数,并把该键名从存储中删除。

    4. xxxxxStorage.clear()

      ​ 该方法会清空存储中的所有数据。

  4. 备注:

    1. SessionStorage存储的内容会随着浏览器窗口关闭而消失。
    2. LocalStorage存储的内容,需要手动清除才会消失。
    3. xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那么getItem的返回值是null。
    4. JSON.parse(null)的结果依然是null。

3.11 组件的自定义事件

3.11.1 绑定自定义事件

  • 通过父组件给子组件绑定一个自定义事件 实现子给父传递数据 方式一:通过@或者v-on

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第14张图片

  • 通过父组件给子组件绑定一个自定义事件 实现子给父传递数据 方式二:通过ref

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第15张图片

  • 要让自定义事件只响应一次,使用once
使用@或者v-on时可直接在后面加once
<Student v-on:atguigu.once="getStudentName"/>
    
 使用ref时将$on更换为$once
this.$refs.student.$once('atguigu',this.getStudentName)
  • 自定义事件传递多个参数

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第16张图片
3.Vue从入门到精通 (第三章 使用Vue脚手架)_第17张图片

3.11.2 解绑自定义事件

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第18张图片

3.11.3 自定义事件总结

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:

    2. 第二种方式,在父组件中:

      <Demo ref="demo"/>
      ......
      mounted(){
         this.$refs.xxx.$on('atguigu',this.test)
      }
      
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

  4. 触发自定义事件:this.$emit('atguigu',数据)

  5. 解绑自定义事件this.$off('atguigu')

  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  7. 注意:通过this.$refs.xxx.$on('atguigu',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

3.12 全局事件总线

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第19张图片
3.Vue从入门到精通 (第三章 使用Vue脚手架)_第20张图片
3.Vue从入门到精通 (第三章 使用Vue脚手架)_第21张图片

  1. 一种组件间通信的方式,适用于任意组件间通信。

  2. 安装全局事件总线:

    new Vue({
       ......
       beforeCreate() {
          Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
       },
        ......
    }) 
    
  3. 使用事件总线:

    1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.$bus.$on('xxxx',this.demo)
      }
      
    2. 提供数据:this.$bus.$emit('xxxx',数据)

  4. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

3.13 消息订阅与发布

  1. 一种组件间通信的方式,适用于任意组件间通信。

  2. 使用步骤:

    1. 安装pubsub:npm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'

    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }
      
    4. 提供数据:pubsub.publish('xxx',数据)

    5. 最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去取消订阅。

案例:Student组件发送消息,School组件订阅消息

3.Vue从入门到精通 (第三章 使用Vue脚手架)_第22张图片
3.Vue从入门到精通 (第三章 使用Vue脚手架)_第23张图片

3.14 $nextTick

  1. 语法:this.$nextTick(回调函数)

  2. 作用:在下一次 DOM 更新结束后执行其指定的回调。

  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。

当你修改了数据之后,vue帮你操作完dom之后,把真实的dom放入页面了,vue再帮忙调用nextTick函数

3.15 动画

vue封装的动画要求写在transition标签中,以进场和离场动画为例,若不给transition标签指定名字hello,那么这两个动画的名字要固定的写为.v-enter-active和.v-leave-active,如果给transition指定name为hello,那么两个动画的名字为.hello-enter-active和.hello-leave-active,如果希望在开始时就有出场动画,就要在transition标签上加入:appear=“true”, 可简写为appear

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<transition name="hello" appear>
			<h1 v-show="isShow">你好啊!</h1>
		</transition>
	</div>
</template>

<script>
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
</script>

<style scoped>
	h1{
		background-color: orange;
	}

	.hello-enter-active{
		animation: atguigu 0.5s linear;
	}

	.hello-leave-active{
		animation: atguigu 0.5s linear reverse;
	}

	@keyframes atguigu {
		from{
			transform: translateX(-100%);
		}
		to{
			transform: translateX(0px);
		}
	}
</style>

3.16 过渡

3.16.1 单个元素的过渡

vue封装transition时,元素进场或者离场时会给内部的元素添加两对共六个样式,分别是

1 进入的起点.hello-enter、2 离开的终点 .hello-leave-to

3 进入的全过程.hello-enter-active、 4 离开的全过程 .hello-leave-active

5 进入的终点.hello-enter-to、 6 离开的起点 .hello-leave

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<transition name="hello" appear>
			<h1 v-show="isShow">你好啊!</h1>
		</transition>
	</div>
</template>

<script>
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
</script>

<style scoped>
	h1{
		background-color: orange;
	}
	/* 进入的起点、离开的终点 */
	.hello-enter,.hello-leave-to{
		transform: translateX(-100%);
	}
	.hello-enter-active,.hello-leave-active{
		transition: 0.5s linear;
	}
	/* 进入的终点、离开的起点 */
	.hello-enter-to,.hello-leave{
		transform: translateX(0);
	}

</style>

3.16.2 多个元素的过渡

多个元素过渡要使用transition-group 标签,并且其内部的元素要有key值标识

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<transition-group name="hello" appear>
			<h1 v-show="!isShow" key="1">你好啊!</h1>
			<h1 v-show="isShow" key="2">尚硅谷!</h1>
		</transition-group>
	</div>
</template>

3.17 集成第三方动画

安装animate.css库,命令为 npm i animate.css

transition-group标签的名字要改为animate__animated animate__bounce

对其内部的标签配置进入和离开的动画,进入动画配置为enter-active-class=“animate__swing”,离开动画leave-active-class=“animate__backOutUp”

<template>
	<div>
		<button @click="isShow = !isShow">显示/隐藏</button>
		<transition-group 
			appear
			name="animate__animated animate__bounce" 
			enter-active-class="animate__swing"
			leave-active-class="animate__backOutUp"
		>
			<h1 v-show="!isShow" key="1">你好啊!</h1>
			<h1 v-show="isShow" key="2">尚硅谷!</h1>
		</transition-group>
	</div>
</template>

<script>
	import 'animate.css'
	export default {
		name:'Test',
		data() {
			return {
				isShow:true
			}
		},
	}
</script>

<style scoped>
	h1{
		background-color: orange;
	}
</style>

Vue封装的过度与动画总结

  1. 作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。

  2. 图示:

  3. 写法:

    1. 准备好样式:

      • 元素进入的样式:
        1. v-enter:进入的起点
        2. v-enter-active:进入过程中
        3. v-enter-to:进入的终点
      • 元素离开的样式:
        1. v-leave:离开的起点
        2. v-leave-active:离开过程中
        3. v-leave-to:离开的终点
    2. 使用包裹要过度的元素,并配置name属性:

      
         

      你好啊!

    3. 备注:若有多个元素需要过度,则需要使用:,且每个元素都要指定key值。

你可能感兴趣的:(#,Vue,vue.js,javascript,前端)