一、传统方式和组件方式编写应用比较

传统方式编写应用

Vue 组件化编程_vue.js

组件方式编写应用

Vue 组件化编程_前端_02

组件:就是实现应用中局部功能代码和资源的整合

Vue 组件化编程_前端_03

二、单文件

1、非单文件组件

1、什么是非单文件组件:一个文件中包含n个组件

2、单文件组件

一个文件只包含一个组件,单文件组件都是.vue结尾的

3、使用组件三大步骤

第一步:定义组件

第二步:注册组件

第三步:使用组件


<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> </head> <body> <div id="root"> <!--第三步骤:使用组件--> <student></student> </div> </body> <script> /*第一步:定义组件*/ const student = Vue.extend({ /*自定义组件时,不要用el属性, 因为最终所有的组件都是被vm管理,由vm决定要挂载到哪个容器*/ //使用template可以配置组件结构 template:` <div> <span>{{name}}</span> <span>{{age}}</span> </div> `, /*data要写成普通函数形式,不能写成对象形式,因为一个组件被多个地方使用,任何一个地方修改了data对象,其他地方也会发生变化*/ data(){ return{ name:'张三', age:20 } } }); //第二步:注册组件(全局注册) Vue.component('student',student); const vm = new Vue({ el:"#root", /*第二步:注册组件(局部注册)*/ components:{ student } }); </script> </html>


备注:

1、组件名写法

一个单词组成

第一种写法:首字母小写如student

第二种写法:首字母大写Student

多个单词组成

第一种写法:kebab-case命名如my-student 注册的时候要用引号

第二种写法:CamelCase命名如MyStudent,需要vue脚手架支持

2、一个简写方式

const student = Vue.extend(options) 简写 const student = options

上面案例简写


const student = { /*自定义组件时,不要用el属性, 因为最终所有的组件都是被vm管理,由vm决定要挂载到哪个容器*/ //使用template可以配置组件结构 template:` <div> <span>{{name}}</span> <span>{{age}}</span> </div> `, /*data要写成普通函数形式,不能写成对象形式,因为一个组件被多个地方使用,任何一个地方修改了data对象,其他地方也会发生变化*/ data(){ return{ name:'张三', age:20 } } }


三、ref

1、作用

获取dom元素或者组件实列对象vc

2、实现


<template> <div> <!--ref应用在组件上--> <student ref="stu"></student> <!--ref应用在dom元素是--> <h1 ref="dom" id="dom"></h1> <button @click="showDom">获取h1dom</button> </div> </template> <script> import student from "./student"; export default { name: "test", components:{ student }, data(){ return{ } }, methods:{ showDom(){ //原生通过id获取元素 console.log(document.getElementById('dom')) //ref应用在组件上获取的是组件实列对象vc console.log(this.$refs.stu)// //ref应用在dom元素是 获取真实的dom元素 console.log(this.$refs.dom)// } } } </script> <style scoped> </style>


结果

Vue 组件化编程_javascript_04

四、props

1、作用

同一个组件传入不同数据展示不同界面

2、实现

定义一个展示学生信息的组件(模板),传入数据展示不同的学生信息


<template> <div> <h1>{{msg}}</h1> <h1>{{name}}</h1> <h1>{{age}}</h1> </div> </template> <script> export default { name: "student", data(){ return{ msg:'hello' } }, /*第1种:声明简单接受*/ props:['name', 'age'] //第2种:接受+限制类型 props:{ name:String, age:Number } //第3种:接受+限制类型+默认值+必填指定 props:{ name:{ type:String,//类型 required:true//必填 }, age:{ type: Number, required: false, default:10//默认值 } } } </script> <style scoped> </style>


调用


<template> <div> <!--传入组件所需值即可--> <student name="张三" :age="15"></student> </div> </template> <script> import student from "./student"; export default { name: "test", components:{ student }, data(){ return{ } } } </script> <style scoped> </style>


说明

1、props不允许修改的,如上面的student页面修改age值,控制台有错误提示,若业务有需要可以在student中的data中定义一个属性,将props的复制即可


<template> <div> <h1>{{msg}}</h1> <h1>{{name}}</h1> //这里是data中的值 <h1>{{myAge}}</h1> </div> </template> <script> export default { name: "student", data(){ return{ msg:'hello', //复制props的属性值 myAge:this.age } }, props:['name', 'age'] } </script> <style scoped> </style>


2、有些值不能传比如key ref等这些是不允许传入的

五、mixin

1、作用

把多个组件共用的配置提取成一个混入(mixin)对象

2、定义混入

定义一个js文件 文件名自定义 内容


export const hunru1 = { data(){ return{ x:200 } }, methods:{ showNum(){ alert("111") } }, mounted() { console.log("minin钩子函数") } }; export const hunru2 = { data(){ return{ xx:400 } } }


3、局部混入


<template> <div> <h1>{{name}}</h1> <h1>{{age}}</h1> <!--直接使用混入中的属性值--> <h1>{{x}}</h1> <h1>{{xx}}</h1> </div> </template> <script> import {hunru1, hunru2} from "../mixin"; export default { name: "student", data(){ return{ name:'张三', age:10 } }, //如果混入也有挂载 先执行混入的 mounted() { console.log("1111") }, //必须是数组,所以可以引入多个 mixins:[hunru1,hunru2] } </script> <style scoped> </style>


4、全局混入

再main.js中使用


import Vue from 'vue' import App from './App.vue' import {hunru1, hunru2} from "./mixin"; //项目中所有的vc 和vm引入 Vue.mixin(hunru2) Vue.mixin(hunru1) Vue.config.productionTip = false new Vue({ render: h => h(App), }).$mount('#app')


5、说明

混入中定义data和methods中属性或者和方法在原组件中的重复了 则以原组件为准,但是如果钩子重复了则都会执行 先执行原组件的再执行混入的

六、scoped

1、scoped作用

让样式局部生效 防止全局冲突


<style scoped> </style>


2、原理

通过给当前组件根元素加一个data-v,然后结合选择器实现

Vue 组件化编程_前端_05

说明


<!--如果不写lang 则默认使用css,使用less需要安装less-loader 安装如果出现webpack版本错误 将less-loader版本降低--> <style lang="less" scoped> </style>


七、组件化通信

1、父传子

方式:通过props

2、子传父

方式:自定义emit事件

3、任意组件之间通信

第一种方式:全局事件总线

1、安装全局事件总线


new Vue({ render: h => h(App), beforeCreate() { Vue.prototype.$bus = this } }).$mount('#app')


2、使用事件总线

在要接受数据的组件中给bus绑定自定义事件,事件的回调留在组件自身


mounted(){ this.$bus.on('hello',mydata) }


提供数据


this.$bus.$emit('hello',mydata)


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


this.$bus.$off('hello')


第二种方式:消息订阅与发布

八、浏览器存储

localstorage和sessionStorage统称webStorage

1、localStorage

1、特定

浏览器关闭 存储的数据不会消失,只有以下两种情况会消失

引导用户操作了localstorage的clear()或者removeItem()

用户清空了浏览器缓存

2、相关api


/*存储相关*/ //存储相同的key会替换 localStorage.setItem("name","dddd") localStorage.setItem("name","dddd1") //数值类型存储会转成字符串 localStorage.setItem("age",19) //只要value给的不是string 会转成string,即调用的tostring 所以下面存储的[object,object] localStorage.setItem("person",person) //可以通过json.stringify()将对象转成字符串存储 localStorage.setItem("person1",JSON.stringify(person)) /*读取*/ console.log(localStorage.getItem("name")) console.log(localStorage.getItem("age")) console.log(localStorage.getItem("person1")) //读没有存储的数据 返回的是null,JSON.parse(xxx)也返回null console.log(localStorage.getItem("xx")) //读取对象字符串并转成对象 console.log(JSON.parse(localStorage.getItem("person1"))) /*删除*/ //删除指定的key localStorage.removeItem("person") //清空 localStorage.clear();


2、sessionStorage

1、会话存储,浏览器一关闭 sessionStorage存储的数据消失
2、所有的api和localStorage一样