系统性学习vue-组件及脚手架

书接上文

Vue组件及脚手架

  • 初始化脚手架
    • 说明
    • 步骤
  • 分析脚手架结构
  • render函数
  • 修改默认配置
  • ref属性
  • props配置
  • mixin 混入/混合
    • 定义混合
    • 局部混合
    • 全局混合
  • 插件
  • scoped样式
    • 安装less-loader
  • 浏览器的本地存储 webStorage
    • localStroage 本地存储
    • sessionStorage 会话存储
  • 组件自定义事件
    • 绑定
    • 解绑
    • 组件绑定原生事件
  • 全局事件总线 GlobalEventBus
    • 安装
    • 绑定事件 接收数据
    • 触发事件 传递数据
  • 消息订阅与发布 pubsub
  • $nextTick
  • transition
    • 动画效果
    • 过渡效果
    • transition-group
    • 集成第三方动画

初始化脚手架

说明

Vue脚手架是Vue官方提供的标准化开发工具(开发平台)
CLI: command line interface (命令行接口工具) 俗称脚手架

步骤

备注:

  • 如果下载缓慢可以配置npm淘宝镜像: npm config set registry https://registry.npm.taobao.org
  • Vue脚手架隐藏了所有webpack相关配置,弱项查看具体的webpack配置,请执行vue inspect > output.js
  1. (仅第一次执行)全局安装@vue/cli, 安装好就可以使用vue命令了
    npm install -g @vue/cli

  2. 切换到要创建项目的目录(可用cd命令,也可以直接文件下shift+右键选择’在此处打开窗口’),然后使用命令创建项目
    vue create xxxxx(项目名称)
    会出现一个选项
    系统性学习vue-组件及脚手架_第1张图片
    目前先选择vue2
    又来一个问题,先选NPM吧
    在这里插入图片描述

  3. 启动项目(运行的是官方给写好的HelloWorld代码)
    来到项目目录下,执行命令
    npm run serve
    至此准备完成
    系统性学习vue-组件及脚手架_第2张图片
    如果要停止服务的话,命令行按Ctrl+c(两遍)

分析脚手架结构

整个脚手架内容如下,
系统性学习vue-组件及脚手架_第3张图片

  • .gitignore git忽略文件配置
  • babel.config.js babel的配置文件
  • package-lock.json&package.json 符合npm规范的工程都会有这两个文件
    package.json 应用包配置文件,包含名称,版本,依赖等
    系统性学习vue-组件及脚手架_第4张图片package-lock.json 包版本控制文件
  • README.md 应用描述文件
  • src/main.js 当执行npm run serve命令后直接运行的就是这个文件,是整个项目的入口文件
    逐行分析↓
import Vue from "vue"; //引入Vue
import App from "./App.vue"; //引入App组件,是所有组件的父组件

Vue.config.productionTip = false; //关闭Vue的生产提示

// 创建Vue实例对象
new Vue({
  render: (h) => h(App), //将App组件放入容器中
}).$mount("#app"); //绑定模板

  • src/assets 存放静态资源,如图片
  • src/components 存放组件文件,除了App.vue
  • public/favicon.ico 网站页签图标
  • public/index.html 页面文件
    接着分析
DOCTYPE html>
<html lang="">
  <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">
    
    
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    
    
    <title><%= htmlWebpackPlugin.options.title %>title>
  head>
  <body>
    
    <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>
    
  body>
html>

render函数

main.js中有一行render: (h) => h(App),
按我们的想法应该是

template: ``,
components: { App },

替换成我们的写法运行
报错了
翻译一下就是"嘿,你这用的vue不是完全版的,要不你就用完全版的,要不就用render方法"
系统性学习vue-组件及脚手架_第5张图片
嗯?不是完全版的vue?那先找一下目前用的是哪个vue
在这里插入图片描述
因为我们引入写的是文件夹名称,默认会找到index
但其实引入的是哪个js文件呢
来到node_modules/vue/package.json文件进行查到,搜索module,这个module就是控制当使用es6模块化语法引入的时候的具体引入文件
在这里插入图片描述
这个vue.runtime.esm.js就是我们真正引入的残缺版的vue
而完整版的就是相同目录下的vue.js
那么为什么要用一个残缺版的vue呢?

关于不同版本的Vue:

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

vue.runtime.esm.js缺少的是模板解析器,用来识别template属性内容
而打包后就已经将vue翻译成js文件了,不需要解析器
而解析器占整个vue体积的1/3,懂的都懂

render: (h) => h(App),完整写法

render(createElement) {
	return createElement(App);
},

修改默认配置

图中红色框出的文件或文件夹名称是不可以更改了, 是vue配置并将配置文件隐藏了
系统性学习vue-组件及脚手架_第6张图片
其他的就是可以修改的
官网有配置项文档
修改配置项后需要重启服务

ref属性

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

    ...

    ...
    获取 this.$refs.xxx
<div ref="h1">Hello World!div>
<div ref="h2">Hello World!div>
<div ref="h3">Hello World!div>
console.log(this.$refs);

输出结果
系统性学习vue-组件及脚手架_第7张图片
给组件添加ref,就能获取到vc
而原生的document.getElementById获取到的只能是组件模板结构

props配置

让组件接收外部传过来的数据
props是只读的,Vue底层会检测你对props的修改,如果进行了修改,就会发出警告.若业务需求确实需要修改,那么请复制props的内存到data中一份,然后去修改data中的数据
注意:v-model绑定的值不能是props传过来的值,因为props是不可以修改的

App.vue中

<HelloWorld name="Qiu" :age="20">HelloWorld>
<HelloWorld name="Cai" :age="18">HelloWorld>

子级组件需要接收这些数据,
有三种方法

  • props: ["name", "age"],
    这样数据类型就是传进来的类型
  • props: { name: String, age: Number, },
    这样就会对类型进行限制
  • 还有一个更加完整的
    可以控制类型,是否必输和默认值
props: {
  name: {
    type: String,
    required: true,
  },
  age: {
    type: Number,
    default: 999,
  },
},

props的优先级高于data
当我们想更改传过来的数据时,是不允许直接修改props内数据
所以可以再定义一个变量存放这个数据,再根据需求进行更改

data(){
	return {
		myName:this.name
	}
}
props:{
	name: String,
  	age: Number,
}

mixin 混入/混合

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

定义混合

创建一个js脚本,名称可以随便取,这里就用mixin了,里面可以配置所有组件可配置的属性

// mixin.js
// 分别暴露
export const mix = {
  data() {
    return {
      sex: "girl",
    };
  },
  mounted() {
    console.log("你好啊,我是mixin");
  },
};

局部混合

组件中引用

import { mix } from "../mixin.js";
export default {
  mixins: [mix],
};

直接就可以在组件里使用了

<h2>i am a {{ sex }}h2>

组件和混入数据冲突时,会优先使用组件数据
声明周期钩子函数冲突时,如两边都定义了mounted,那都会执行, 混合的先执行

模块化小知识
export default xxx 是默认暴露,引用时是import xxx from "xxx"
export const xxx = {} 是分别暴露,引用是是import {xxx} from "xxx"

全局混合

在main.js中引入混合并配置

import { mix } from "./mixin.js"; //引入混合
Vue.mixin(mix); //全局混合

这样所有组件都不需要在引入,直接就可以只用混合的内容

插件

用于增强Vue,添加一些全局使用的功能
本质:包含install方法的一个对象,install的第一个参数是Vue(Vue构造函数),之后的参数是插件使用者传递的数据

定义插件(一般命名为plugins.js)
里面必须写install方法,默认参数是Vue构造函数

// 插件
const obj = {
  // 固定钩子函数
  install(Vue) {
  //install(Vue, author) { //接收多个参数
    console.log("我是衩件儿", Vue);
    // 这里就可以对Vue进行各种操作
    // Vue.directives() 自定义指令
    // Vue.mixin() 混入
    // Vue.prototype.$myMthod = function{...} //添加实例方法
    // 等等...
  },
};
// 默认暴露
export default obj;

在main.js引入并使用插件

import plugins from "./plugins"; //引入插件

Vue.use(plugins); //使用插件
// Vue.use(plugins, "Cai"); //使用插件 添加参数 可多个

这样所有组件都可以使用插件里配置的东西了
相当于外挂

scoped样式

作用是让样式在局部生效,防止冲突