vue2学习笔记(2/2)

vue2学习笔记(1/2)

vue2学习笔记(2/2)

文章目录

    • 1. 初始化脚手架
    • 2. 分析脚手架&render函数
      • 文件结构图示及说明
        • main.js
        • index.html
        • App.vue
        • School.vue
        • Student.vue
      • 关于不同版本的Vue
      • 修改默认配置
        • vue.config.js配置文件
    • 3. ref属性
    • 4. props配置
    • 5. mixin混入
      • 局部混入
      • 全局混入
    • 6. 插件
      • 定义插件
      • 应用插件
    • 7. scoped样式
    • 8. Todo-list 案例
      • 组件化编码流程(通用)
      • 案例代码
        • main.js
        • App.vue
        • MyHeader.vue
        • MyList.vue
          • MyItem.vue
        • MyFooter.vue
    • 9. 浏览器本地缓存
      • localStorage
      • sessionStorage
    • 10. 组件自定义事件
      • 案例代码
        • main.js
        • App.vue
        • Student.vue
        • School.vue
    • 11. 全局事件总线
      • 图解
      • 案例代码
        • main.js
        • App.vue
        • School.vue
        • Student.vue
    • 12. 消息订阅与发布
      • 案例代码
        • main.js
        • App.vue
        • School.vue
        • Student.vue
    • 13. $nextTick
      • 案例代码
        • MyItem.vue
    • 14. 过渡与动画
      • 案例代码
        • Test.vue
          • (拿动画写)
        • Test2.vue
          • (拿过渡写)
        • Test3.vue
          • (第三方动画)
    • 15. 配置代理服务器
      • 方法一
      • 方法二
      • 案例代码
        • main.js
        • App.vue
        • vue.config.js
    • 16. github搜索案例
      • 案例代码
        • main.js
        • App.vue
        • Search.vue
        • List.vue
    • 17. vue-resource
      • main.js
      • Search.vue
    • 18. 插槽
      • 1. 默认插槽
        • App.vue
        • Category.vue
      • 2. 具名插槽
        • App.vue
        • Category.vue
      • 3. 作用域插槽
        • App.vue
        • Category.vue
    • 19. Vuex
      • 1. vuex 是什么
        • 1. 什么时候使用 Vuex
        • 2. Vuex 工作原理图
      • 2. 搭建vuex环境
      • 3. 基本使用
      • 4. 求和案例_vuex版
        • main.js
        • store/index.js
        • App.vue
        • Count.vue
      • 5. mapState与mapGetters&mapMutations与mapActions[==简写==]
        • main.js
        • store/index.js
        • App.vue
        • Count.vue
      • 6. 模块化+命名空间
        • main.js
        • store/index.js
        • store/count.js
        • store/person.js
        • App.vue
        • Count.vue
        • Person.vue
    • 20. 路由
      • 路由相关理解
      • 基本使用
        • main.js
        • App.vue
        • router/index.js
        • About.vue
        • Home.vue
      • ==几个注意点==
      • 嵌套路由
        • 案例代码
          • public/index.html
          • main.js
          • router/index.js
          • app.vue
          • pages/Home.vue
          • pages/News.vue
          • pages/Message.vue
          • pages/About.vue
          • components/Banner.vue
      • 命名路由
      • 路由的query参数
      • 路由的params参数
      • 路由的props配置
      • router-link的replace属性
      • 编程式路由导航
      • 缓存路由组件
      • 两个新的生命周期钩子
      • 路由守卫
        • 全局(前置/后置)路由守卫
        • 独享路由守卫
        • 组件内路由守卫
      • 路由懒加载
      • 路由器的两种工作模式
        • 打包部署刷新页面404的问题
          • 使用nginx
    • 21. UI 组件库
      • 移动端常用 UI 组件库
      • PC 端常用 UI 组件库
    • 22. 配置@
      • 创建jsconfig.json文件
    • 23. axios
      • 1、安装axios
      • 2、创建ajax.js
      • 3、暴露请求接口方法
      • 4、使用
    • 24. MockJs
      • 1、安装mockJs
      • 2、编写mockServer.js文件
      • 3、创建mockAjax.js
      • 4、暴露请求接口方法
      • 5、使用
    • 25. QRCode
    • 26. vue-lazyload

1. 初始化脚手架

说明

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

具体步骤

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

npm install -g @vue/cli

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

vue create 项目名

第三步:启动项目

npm run serve  

备注:

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

  2. Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpakc 配置,请执行:vue inspect > output.js ,可以在该文件中看到所有的配置。

vue2学习笔记(2/2)_第1张图片

2. 分析脚手架&render函数

文件结构图示及说明

vue2学习笔记(2/2)_第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:包版本控制文件
main.js
/* 
	该文件是整个项目的入口文件(当执行npm run serve的时候,就会从当前目录下的src目录中找到main.js)
*/
//引入Vue(此处引入的vue是不带模板编译器的版本)
import Vue from 'vue'

//引入App组件,它是所有组件的父组件
import App from './App.vue'

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

/* 
	关于不同版本的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函数去指定具体内容。
*/

//创建Vue实例对象---vm
new Vue({
	el:'#app', // 也可以使用vm.$mount('#app')
    
	//render函数完成了这个功能:将App组件放入容器中
  	render: h => h(App),
    
	// render:q=> q('h1','你好啊')
    
    /* 完整写法
       render(createElement){
       	  return createElement('h1','你好啊');
       }
    */

	// template:`

你好啊

`, // 因为引入的vue没有模板解析器版本的,所以不能使用template配置项
// components:{App}, })
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">  
		
		<link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">
		
    <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>

App.vue
<template>
	<div>
		<img src="./assets/logo.png" alt="logo">
		<School>School>
		<Student>Student>
	div>
template>

<script>
	//引入组件
	import School from './components/School'
	import Student from './components/Student'

	export default {
		name:'App',
		components:{
			School,
			Student
		}
	}
script>

School.vue
<template>
	<div class="demo">
		<h2>学校名称:{{name}}h2>
		<h2>学校地址:{{address}}h2>
		<button @click="showName">点我提示学校名button>	
	div>
template>

<script>
	 export default {
		name:'School',
		data(){
			return {
				name:'尚硅谷',
				address:'北京昌平'
			}
		},
		methods: {
			showName(){
				alert(this.name)
			}
		},
	}
script>

<style>
	.demo{
		background-color: orange;
	}
style>
Student.vue
<template>
	<div>
		<h2>学生姓名:{{name}}h2>
		<h2>学生年龄:{{age}}h2>
	div>
template>

<script>
	 export default {
		name:'Student',
		data(){
			return {
				name:'张三',
				age:18
			}
		}
	}
script>

关于不同版本的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函数去指定具体内容。

修改默认配置

vue.config.js配置文件

加载。

  1. 使用vue inspect > output.js可以将默认的webpack配置输出到output.js,来查看到Vue脚手架的默认配置。

  2. 在package.json同级目录下创建vue.config.js配置文件,可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh,点击配置参考

  3. vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。

    // 如:
    module.exports = {
        pages: {
            index: {
                // page 的入口
                entry: 'src/main.js',
            }
        },
        lintOnSave:false, // 关闭保存时语法检查而报错
    }
    

3. ref属性

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

      .....

    2. 获取:this.$refs.xxx
  4. 如果有多个元素都使用了相同名称的ref(比如ref=‘xxx’),会被放入数组中,即可以通过$refs[‘xxx’][索引]来访问(比如:$refs[‘xxx’][0])。

App.vue

<template>
	<div>
		<h1 v-text="msg" ref="title">h1>
		<button ref="btn" @click="showDOM">点我输出上方的DOM元素button>
		<School ref="sch"/>
	div>
template>

<script>
	//引入School组件
	import School from './components/School'

	export default {
		name:'App',
		components:{School},
		data() {
			return {
				msg:'欢迎学习Vue!'
			}
		},
		methods: {
			showDOM(){
                
				console.log(this.$refs.title) //真实DOM元素
				console.log(this.$refs.btn)   //真实DOM元素
                
				console.log(this.$refs.sch)   //School组件的实例对象(vc)
                                              // 这里拿到vc对象后,可以直接调用vc组件实例对象中的方法,
                                              // 访问vc组件实例对象中的属性,还可以拿到vc组件的$el属性来操作dom
                
			}
		},
	}
script>

4. 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中的数据。不建议在子组件中修改由props接收到的属性,哪怕是修改使用props接收到的对象中的属性,虽然可以实现功能,但不建议这么改,虽然这种情况没有报出警告,因为vue这里的监测只是浅层次的监测。

示例

App.vue

<template>
	<div>
		<Student name="李四" sex="" :age="18"/>
	div>
template>

<script>
	import Student from './components/Student'

	export default {
		name:'App',
		components:{Student}
	}
script>

Student.vue

<template>
	<div>
		<h1>{{msg}}h1>
		<h2>学生姓名:{{name}}h2>
		<h2>学生性别:{{sex}}h2>
		<h2>学生年龄:{{myAge+1}}h2>
		<button @click="updateAge">尝试修改收到的年龄button>
	div>
template>

<script>
	export default {
		name:'Student',
		data() {
			console.log(this)
			return {
				msg:'我是一个尚硅谷的学生',
				myAge:this.age // 因为props接收的数据优先于data,所以这里可以直接使用
			}                  // 避免直接修改传入的prop值,如果需要改,最好使用data接收props中的值,或使用计算属性
			                   // 因为当父组件重新渲染时,这个传入的prop值又会变掉,就会覆盖掉子组件修改的这个值了
							   // (也就是改了相当于待会父组件一刷新又被覆盖了)
                               // 针对这种情况,基础的做法:让父类提供一个可以修改值的函数,将此函数传给子组件,子组件
                               //                     调用此函数修改值
		},
		methods: {
			updateAge(){
				this.myAge++
			}
		},
		//简单声明接收(接收的props优先于data、methods、computed放到组件实例对象(vc)上)
        //          (所以props已经定义了,那么在其它配置项去定义同名的,会有警告)
		// props:['name','age','sex'] 

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

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

5. mixin混入

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

  2. 使用方式:

    第一步定义混合:

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

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

vue2学习笔记(2/2)_第3张图片

局部混入

在main.js同级目录下,创建mixin.js

export const hunhe = {
	methods: {
		showName(){
			alert(this.name)
		}
	},
	mounted() {
		console.log('你好啊!')
	},
}
export const hunhe2 = {
	data() {
		return {
			x:100,
			y:200
		}
	},
}

School.vue

<template>
	<div>
		<h2 @click="showName">学校名称:{{name}}h2>
		<h2>学校地址:{{address}}h2>
	div>
template>

<script>
	//引入一个hunhe
	import {hunhe,hunhe2} from '../mixin'

	export default {
		name:'School',
		data() {
			return {
				name:'尚硅谷',
				address:'北京',
				x:666
			}
		},
		mixins:[hunhe,hunhe2], // 当混入的配置于组件中的data或method有重复情况时,以组件中的为准
	}                          // 当混入的配置中配置了mounted等生命周期函数时,混入配置与组件的mounted都会生效
script>

Student.vue

<template>
	<div>
		<h2 @click="showName">学生姓名:{{name}}h2>
		<h2>学生性别:{{sex}}h2>
	div>
template>

<script>
	import {hunhe,hunhe2} from '../mixin'

	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男'
			}
		},
		mixins:[hunhe,hunhe2]
	}
script>

全局混入

修改main.js,添加如下代码

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
import {hunhe,hunhe2} from './mixin' // 导入mixin.js
//关闭Vue的生产提示
Vue.config.productionTip = false

Vue.mixin(hunhe)    // 引用全局混入,每个组件实例都会混入这些配置,包括vm本身
Vue.mixin(hunhe2)


//创建vm
new Vue({
	el:'#app',
	render: h => h(App)
})

6. 插件

1、功能:用于增强Vue

2、本质:包含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 = xxxx
}

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

vue2学习笔记(2/2)_第4张图片

定义插件

// plugin.js
// 下面是通过暴露一个含有install函数的对象的写法,也可以暴露一个plugin函数并使用module.exports导出此函数,引用用法一样
// 其实只要暴露一个含有install函数的对象或者暴露一个plugin函数,使用es6模块化语法暴露或者使用commonjs语法暴露出来都一样
export default {
	install(Vue,x,y,z){  // 暴露一个对象,对象中必须要有一个install方法,接收到的第一个参数是Vue构造函数
		console.log(x,y,z) // 这个打印输出是在浏览器的console中可以看到,也就是说插件的这个方法在创建vm前执行
                           // 那么其实定义插件的意思就是在告诉Vue在创建vm实例之前要做的事情
		//全局过滤器
		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('你好啊')}
	}
}

应用插件

// main.js

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'

//引入插件
import plugin from './plugin'

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

//应用(使用)插件
Vue.use(plugin,1,2,3)  // 也可以添加额外的参数,install函数能够收到

//创建vm
new Vue({
	el:'#app',
	render: h => h(App)
})

7. scoped样式

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

  2. 写法: