前沿
置身世外只为暗中察看!!!Hello大家好,我是魔王哪吒!重学坚固你的Vuejs常识体系,如果有哪些知识点脱漏,还望在评论中阐明,让我能够及时更新本篇内容常识体系。欢送点赞珍藏!
谈谈你对MVC、MVP和MVVM的了解?
https://github.com/webVueBlog...
转角遇到Vuejs
- 你为啥学习Vuejs
- 前端开发的复杂化
- Vuejs的特点
- 装置Vuejs
- 体验Vuejs
- MVVM架构:data和Vue对象的拆散,Vue中的MVVM
目录:
起步
- 插值语法:Mustache,v-once,v-html,v-text,v-pre,v-block。
- 绑定属性:v-bind的介绍,v-bind的根底,v-bind的语法糖,绑定class,绑定款式。
- 计算属性
- 事件监听:v-on介绍,v-on根底,v-on参数,v-on修饰符
- 条件和循环:条件渲染,v-show指令,v-if和v-show比照
- 表单绑定:根本应用,v-model原理,其余类型,值绑定,修饰符。
组件化开发:
什么是组件化,Vue组件化开发思维
- 注册的步骤
- 全局和部分组件
- 父组件和子组件
- 注册组件语法糖
- 模板的拆散写法
- 组件的其余属性
- 父级向子级传递
- 子级向父级传递
- 父子组件的拜访
- 非父子组件通信
组件化高级语法:
- 插槽slot:编译作用域,为什么应用slot,slot的根本应用,slot的具名插槽,slot的作用域插槽。
- 动静组件
- 异步组件
- 组件申明周期
Vue Cli
- 什么是webpack
- webpack和gulp比照
- 手动webpack的配置
- Vue Cli是什么
- Vue Cli依赖环境
- Vue Cli的装置
网络封装
- 应用传统的Ajax是基于XMLHttpRequest(XHR)
- 应用jQuery-Ajax
- Vue-resource
- 应用axios
axios的应用
- 理解axios:axios申请形式
- 发送申请,发送get申请,发送并发申请,axios全局配置,常见配置选项。
- axios实例,为什么创立axios实例,如何创立axios实例,axios的封装。
- axios的拦截器:申请和响应
vuejs原理相干:响应式原理,源码。
vue.js是什么
- vue是一套用于构建用户界面的渐进式框架。
- 从自底向上逐层利用,外围库是只关注图层。
- 易于学习,便于与第三方库或既有我的项目整合。
Vue根底语法
对于基础知识须要把握,简略写写✍
vue.js装置
间接CDN引入:
- 对于制作原型或学习
代码:<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
- 对于生产环境
代码:<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
- NPM
代码:
# 最新稳定版$ npm install vue
vue响应式初体验
申明式编程:
代码:
<!DOCTYPE html><!-- 魔王哪吒 --><html> <head> <meta charset="utf-8"> <title></title> <script src="vue.js" type="text/javascript" charset="UTF-8"></script> <!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> --> </head> <body> <div id="app"> {{ a }} </div> <script type="text/javascript"> // 咱们的数据对象 var data = { a: 1 }; // 该对象被退出到一个 Vue 实例中 var vm = new Vue({ el: "#app", data: data }); // data.a = "dada" vm.a = "qianduan"; data.a == vm.a; </script> </body></html>
小案例-计算器
- 新的属性:
methods
,该属性是用于Vue
对象中定义的办法。 - 新的指令:
@click
,该指令是用于监听某个元素的点击事件,并且须要指定当产生点击时,执行的办法。
代码:
<div id="app"> <h1>以后计数{{counter}}</h1> <button @click="increment">+</button> <button @click="decrement">-</button></div><script src="../js/vue.js"></script><script> let app = new Vue({ el: '#app', data: { counter: 0 }, methods: { increment(){ this.counter++ }, decrement(){ this.counter-- }, } })</script>
Vue中的MVVM
MVVM的思维
- view是咱们的DOM
- Model是咱们抽离进去的obj
- ViewModel是咱们创立的Vue对象实例
它们之间是如何工作的呢?
- ViewModel通过Data Binding让obj中的数据实时在DOM中显示
- ViewModel通过DOM Listener来监听DOM事件,并且通过methods中的操作,来扭转obj中的数据
el
:类型:string | HTMLElement
- 作用:决定之后Vue实例会治理哪一个
DOM
data
:类型:Object | Function
- 作用:Vue实例对应的数据对象
methods
:类型:{[key:string]:Function}
- 作用:定义属于Vue的一些办法,能够在其余中央调用,也能够在指令中应用。
什么是Vue的生命周期
生命周期:☞ 事物从诞生到沦亡的整个过程
release
稳固版本debug
版本
- Mustache语法也就是双大括号
- 插值操作
- 绑定属性
- 计算属性
- 事件判断
- 循环遍历
- 阶段案例
- v-model
v-once
指令的应用
<div id="app"> <h1>{{message}}</h1> <h2 v-once>{{message}}</h2></div>
v-once
:
- 该指令前面不须要跟任何表达式
- 该指令示意元素和组件只渲染一次,不会随着数据的扭转而扭转
v-html
:
当咱们从服务器申请到的数据自身就是一个HTML代码时
- 如果间接通过
{{}}
来输入,会将HTML
格局进行解析,并且显示对应的内容。 - 能够应用
v-html
指令 - 该指令后跟上一个
string
类型 - 会将
string
的html
解析解决并且进行渲染
<h1 v-html="url"></h1>
v-text
的作用和Mustache
比拟类似,独应用于将数据显示在界面中,个别状况下,承受一个string
类型。
<div id="app"> <h2 v-text="message"></h2> <h2>{{message}}</h2></div><script src="../js/vue.js"></script><script> let vm = new Vue({ el: '#app', data: { message: '你好' } })</script>
v-pre
用于跳过这个元素和它子元素的编译过程,用于显示本来的Mustache
语法。
<div id="app"> <p v-pre>{{message}}</p></div><script src="../js/vue.js"></script><script> let app = new Vue({ el: '#app', data: { message: 'hello' } })</script>
v-cloak
斗篷的意思。
<div id="app"> <h2 v-cloak>hello{{name}}</h2></div><script> setTimeout(()=>{ let app = new Vue({ el: '#app', data: { name: 'web' } }) },10000)</script><style> [v-cloak] { display: none; }</style>
v-bind的介绍
v-bind
用于绑定一个或多个属性值,或者向另一个组件传递props
值。
<div id="app"> <a v-bind:href="link">vuejs</a> <img v-bind:src="url" alt=""></div><script> let app = new Vue({ el: '#app', data: { } })
v-bind
语法糖
v-bind
有一个对应的语法糖,就是简写形式
<div id = "app"> <a :href="link">vuejs</a> <img :src="longURL" alt=""></div>
v-bind
动静绑定class
<style> .active{ color: red; }</style><div id="app"> <h1 class="active">{{message}}</h2></div><script> const app = new Vue({ el: '#app', data: { message: 'hello' } })</script>
绑定class
有两种形式:
- 对象语法
- 数组语法
对象语法:
用法一:间接通过{}绑定一个类<h2 :class="{'active': isActive}">hello</h2>用法二,传入多个值<h2 :class="{'active': isActive, 'line': isLine}">hello</h2>用法三:<h2 class="title" :class="{'active': isActive}"></h2>用法四:能够放在一个methods或者computed中<h2 class="title" :class="classes">hello</h2>
v-bind
动静绑定class,数组语法
<div id="app"> <h2 class="title" :class="[active, line]">{{mesg}}</h2> <h2 class="title" :class="getClasses()">{{mesg}}</h2></div><script> const app = new Vue({ el: '#app', data: { message: 'hello', active: 'aaa', line: 'bbb', }, methods: { getClasses: function() { return [this.active, this.line] } } })</script>
v-bind
动静绑定style
对象语法和数组语法两种绑定。
绑定办法:对象语法:
:style="{ color: currentColor, fontSize: fontSize + 'px' }"
style
前面跟的是一个对象类型,对象的key
是css
属性名称,对象的value
是具体赋的值,值能够来自于data
中的属性。
绑定办法:数组语法:
<div v-bind:style="[baseStyles, overStyles]"></div>
style
前面跟的是一个数组的类型,多个值,宰割即可。
计算属性的根本属性
计算属性,写在实例的computed
选项中:
<div id="app"> <h2>{{firstName}}{{lastName}}</h2></div><script> const vm = new Vue({ el: '#app', data: { firstName: 'web', lastName: 'it', } })</script>
<div id="app"> <h2>{{fullName}}</h2></div><script> const vm = new Vue({ el: '#app', data: { firstName: 'jeskson', lastName: 'it', }, computed: { fullName() { return this.firstName + ' ' + this.lastName } } })</script>
计算属性的缓存:
为什么应用计算属性这个货色?
起因:计算属性会进行缓存,如果屡次应用时,计算属性只会调用一次。
setter和getter
每个计算属性都蕴含一个getter和一个setter
<div id="app"> <div>{{fullName}}</div> <div>{{firstName}}</div> <div>{{lastName}}</div></div><script> let vm = new Vue({ el: '#app', data: { firstName: 'web', lastName: 'it', }, computed: { fullName: { get() { rturn this.firstName+" "+this.lastName }, set(newValue){ const names = newValue.split(' ') this.firstName = names[0] this.lastName = names[1] } } } })</script>
computed: { fullName: function() { return this.firstName+" "+this.lastName } // 计算属性个别是没有set办法,只读属性。 fullName: { get: function() { return this.firstName + " " + this.lastName } }}
const的应用
const的应用,在JavaScript中应用const润饰的标识符为常量,不能够再次赋值。
在es6开发中,优先应用const,只有须要扭转一个标识符的时候才应用let。
在应用cost定义标识符,必须进行赋值。
常量的含意是指向的对象不能批改,然而能够扭转对象外部的属性。
什么时候应用const呢?
当咱们润饰的标识符不会被再次赋值时,就能够应用const来保证数据的安全性。
const的应用:
const a=20;a = 10; // 谬误:不能够批改const name; // 谬误,const润饰的标识符必须赋值
let和var
块级作用域:
JS中应用var来申明一个变量,变量的作用域次要是和函数的定义无关。
对于其余块定义来说是没有作用域的,比方if/for等,开发中往往会引发一些问题。
// 监听按钮的点击var btns = document.getElementsByTagName('button');for(var i=0; i<btns.length; i++) { (function(i){ btns[i].onclick = function(){ alert('点击了'+i+"个") } })(i)}
let btns = document.getElementsByTagName('button');for(let i=0;i<btns.length;i++){ btns[i].onclick = function(){ alert('点击了'+i+'个') }}
块级作用域
变量作用域:变量在什么范畴内是可用的。
var func;if(true) { var name = 'web'; func = function() { console.log(name); // web } func(); // web}// name = 'it'func(); // web -> itconsole.log(name); // web -> it
没有块级作用域引起的问题,for的块级
var btns = document.getElementsByTagName('button');for(var i=0; i<btns.length; i++) { btns[i].addEventListener('click', function(){ console.log('第'+i+'个按钮被点击'); })}
闭包:
var btns = document.getElementsByTagName('button');for(var i=0; i<btns.length;i++){ (function(i){ btns[i].addEventListener('click', function(){ console.log('第'+i+'个按钮'); }) })(i)}
为什么闭包能够解决问题,因为函数是一个作用域。
对象的加强写法
属性初始化简写和办法的简写:
// 属性的简写// es6前let name = 'web'let age = 12let obj1 = { name: name, age: age,}console.log(obj1);// es6后let obj2 = { name, age}console.log(obj2)
// 办法的简写// es6之前let obj1 = { test: function() { console.log('obj1') }}obj1.test();// es6后let obj2 = { test() { console.log('obj2') }}obj2.test();
v-on根底
v-on:click="counter++"
<div id="app"> <h2>点击次数:{{counter}}</h2> <button v-on:click="counter++">按钮点击</button> <button v-on:click="btnClick">按钮点击2</button></div>let app = new Vue({ el: '#app', data: { counter: 0 }, methods: { btnClick(){ this.counter++ } }})
v-on修饰符的应用
<div id="app"> <div @click="divClick"> web <button @click.stop="btnClick">按钮</button></div>
Vue提供了一些修饰符:
.stop 调用event.stopPropagation().prevent 调用event.preventDefault().native 监听组件根元素的原生事件.once 只触发一次回调
// 进行冒泡<button @click.stop="doThis"></button>// 阻止默认行为<button @click.prevent="doThis"></button>// 阻止默认行为,没有表达式<form @submit.prevent></form>// 串联修饰符<button @click.stop.prevent = "doThis"></button>// 键修饰符,键别名<input @keyup.enter="onEnter">// 键修饰符,键代码<input @keyup.13="onEnter">// 点击回调智慧触发一次<button @click.once="doThis"></button>
v-if,v-else-if,v-else
简略应用:
<div id="app"> <p v-if="score>=90">优良</p> <p v-else-if="score>=80">良好</p> <p v-else-if="score>=60">及格</p> <p v-else="score<60">不及格</p></div>
登录切换:
<div id="app"> <span v-if="type==='username'"> <label>用户账号:</label> <input placeholder="用户账户"> </span> <span v-else> <label>邮箱地址:</label> <input placeholder="邮箱地址"> </span> <button @click="handleToggle">切换类型</button></div><script> let app = new Vue({ el: '#app', data: { type: 'username' }, methods: { handleToggle(){ this.type = this.type === 'email' ? 'username' : 'email' } } })</script>
<div id="app"> <span v-if="isUser"> <label for="username">用户账户</label> <input type="text" id="username" placeholder="用户账户"> </span> <span v-else> <label for="email">用户邮箱</label> <input type="text" id="email" placeholder="用户邮箱"> </span> <button @click="isUser=!isUser">切换类型</button></div><script>const app = new Vue({ el: '#app', data: { isUser: true }})</script>
v-for遍历对象
<div id="app"> <ul> <li v-for="(value, key, index) in info"> {{value}}-{{key}}-{{index}} </li> </ul></div><script> let app = new Vue({ el: '#app', data: { info: { name: 'web', age: 12, } } })</script>
组件的Key属性
应用v-for时,给对应的元素或组件增加上一个:key
属性。
key的作用次要是为了高效的更新虚构dom。
数组中哪些办法是响应式的
push()pop() 删除数组中的最初一个元素shift() 删除数组中的第一个元素unshift() 在数组最后面增加元素splice()sort()reverse()
购物车
<div id="app"><table><thead><tr><th></th><th>书籍名称</th><th>出版日期</th><th>价格</th><th>购买数量</th><th>操作</th></tr></thead><tbody><tr v-for="item in books"><td v-for="value in item">{{value}}</td></tr></tbody></table></div>
表单绑定v-model
vue中应用v-model指令来实现表单元素和数据的双向绑定。
<div id="app"> <input type="text" v-model="message"> <h2>{{message}}</h2></div>
reduce作用对数组中所有的内容进行汇总。
JavaScript reduce() 办法
var numbers = [65, 44, 12, 4]; function getSum(total, num) { return total + num;}function myFunction(item) { document.getElementById("demo").innerHTML = numbers.reduce(getSum);}
定义和用法
reduce() 办法接管一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 能够作为一个高阶函数,用于函数的 compose。
留神: reduce()
对于空数组是不会执行回调函数的。
语法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
v-model的应用以及原理
<input type="text" :value="message" @input="message = $event.target.value"><script> const app = new Vue({ el: '#app', data: { message: '你好啊' }, methods: { valueChange(event){ this.message = event.target.value; } } })</script>
v-model
是语法糖,实质:
v-bind
绑定一个value
属性v-on
指令给以后元素绑定input
事件
代码:
<input type="text" v-model="message"><input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
v-model:checkbox
复选框分为两种状况,单个勾选框和多个勾选框。
单个勾选框:
v-model
即为布尔值。input
的value
并不影响v-model
的值。
多个复选框:
当是多个复选框时,对应的data
中属性是一个数组。
入选中某一个时,就会将input
的value
增加到数组中。
<div id="app"> <label for="check"> <input type="checkbox" v-model="checked" id="check">批准协定 </label> <label><input type="checkbox" v-model="hobbies" value="篮球">篮球</label> <label><input type="checkbox" v-model="hobbies" value="台球">台球</label></div>
v-model:select
select
分单选和多选两种状况
单选:只能选中一个值,多选:能够抉择多个值。
v-model
联合select
类型
和checkbox
一样,select
分单选和多选两种状况。
单选,只能抉择一个值,v-model
绑定的是一个值。当咱们选中option
中的一个时,会将它对应的value
赋值到mySelect
中。
多选,能够选中多个值。v-model
绑定的是一个数组。入选中多个值时,就会将选中的option
对应的value
增加到数组mySelects
中。
// 抉择一个值<select v-model="mySelect"> <option value="web">web</option> <option value="it">it</option></select><p>您最喜爱的{{mySelect}}</p>// 抉择多个值<select v-model="mySelects" multiple> <option value="web">web</option> <option value="it">it</option></select><p>您最喜爱的{{mySelects}}</p>
input中的值绑定
<label v-for="item in origin"> <input type="checkbox" :value="item" v-model="hobbies"> {{item}}</label>
修饰符
lazy
修饰符:
- 默认状况下,
v-model
默认是在input
事件中同步输入框的数据的。 - 一旦有数据产生扭转对应的
data
中的数据就会主动产生扭转。 lazy
修饰符能够让数据在失去焦点或者回车时才会更新。
number
修饰符:
- 默认状况下,在输入框中无论咱们输出的是字母还是数字,都会被当做字符串类型进行解决。
- 然而如果咱们心愿解决的是数字类型,那么最好间接将内容当做数字解决。
number
修饰符能够让在输入框中输出的内容主动转成数字类型。
trim
修饰符:
- 如果输出的内容首尾有很多空格,通常咱们心愿将其去除
trim
修饰符能够过滤内容左右两边的空格
示例:
<div id="app"> <input type="text" v-model.lazy="message"> <h2>{{message}}</h2></div>
什么是组件化
- 组件化是vue.js中的重要思维
- 它提供了一种形象,让咱们能够开发出一个个独立可复用的小组件来结构咱们的利用
- 任何的利用都会被形象成一颗组件树
注册组件的根本步骤:
- 创立组件结构器
- 注册组件
- 应用组件
示例:
调用Vue.extend()办法创立组件结构器调用Vue.component()办法,注册组件在Vue实例的作用范畴内应用组件
组件示例:
<div id="app"><my-cpn></my-cpn></div><script src="../js/vue.js"></script><script> // 创立组件结构器 const myComponent = Vue.extend({ template: ` <div> <h2>组件题目</h2> <p>组件段落</p> </div>` }); // 注册组件 Vue.component('my-cpn',myComponent);</script>
全局组件和部分组件
Vue.extend()
调用Vue.extend()
创立一个组件结构器。- 通常在创立组件结构器时,传入
template
代表咱们自定义组件的模板。 - 该模板在应用到组件的中央,显示的
html
代码。 - 这种写法在
Vue2.x
的文档简直看不到了。 Vue.component()
是将方才的组件结构器注册为一个组件,并且给它起一个组件的标签名称。- 注册组件的标签名,组件结构器。
示例:
组件题目<div id="app"> <my-cpn><my-cpn> <div> <my-cpn><my-cpn> </div></div>
示例:
<div id="app1"> <my-cpn></my-cpn></div><div id="app2"> <my-cpn></my-cpn></div><script src="../js/vue.js"></script><script>// 创立组件结构器const myComponent = Vue.extend({ template: ` <div> <h2>web</h2> </div> `})// 注册组件Vue.component('my-cpn',myComponent);let app1 = new Vue({ el: '#app1'})let app2 = new Vue({ el: '#app2'})
<div id="app1"> <my-cpn></my-cpn></div><div id="app2"> // 没有被渲染进去 <my-cpn></my-cpn></div><script src="../js/vue.js"></script><script>// 创立组件结构器const myComponent = Vue.extend({ template: ` <div> <h2>web</h2> </div> ` }) let app1=new Vue({ el: '#app1', components: { 'my-cpn': myComponent } }) let app2 = new Vue({ el: '#app2' })</script>
父组件和子组件
组件树
- 组件和组件之间存在层级关系
- 其中一种十分重要的关系就是父子组件的关系
示例:
<div id="app"> <parent-cpn></parent-cpn></div><script src="../js/vue.js"></script><script> // 创立一个子组件结构器 const childComponent = Vue.extend({ template: ` <div>我是子组件的内容</div> ` }) // 创立一个父组件的结构器 const parentComponent = Vue.extend({ template: ` <div> 我是父组件的内容 <child-cpn></child-cpn> </div> ` components: { 'child-cpn': childComponent } }) let app = new Vue({ el: '#app', components: { 'parent-cpn': parentComponent } })
注册组件的语法糖
示例:全局组件
<div id="app"> <cpn1></cpn1></div><script> // 全局组件注册的语法糖 // 注册组件 Vue.component('cpn1', { template: ` <div> <h2>web</h2> </div> ` }) const app = new Vue({ el: '#app', data: { message: 'web', } })</script>
<div id="app"> <cpn2></cpn2></div>// 注册部分组件的语法糖const app = new Vue({ el: '#app', data: { message: 'web' }, components: { 'cpn2': { template: ` <div> <h1>web</h1> </div> ` } }})</script>
vue
简化了注册组件的形式,提供了注册的语法糖。
组件模板抽离的写法
vue
提供了两种定义html
模块内容:
- 应用
<script>
标签 - 应用
<template>
标签
示例:
<div id="app"> <my-cpn></my-cpn></div><script type="text/x-template" id="myCpn"> <div> <h2>web</h2> </div></script><script src="../js/vue.js"></script><script> let app = new Vue({ el: '#app', components: { 'my-cpn': { template: '#myCpn' } } })</script>
template
标签
<template id="cpn"> <div> <h2>web</h2> </div></template>// 注册一个全局组件Vue.component('cpn', { template: '#cpn'})
组件能够拜访vue实例数据吗
组件是一个独自的功能模块封装,有属于本人的html
模板和本人的数据data
。
组件对象有一个data
属性,methods
属性,这个data
属性必须是一个函数,函数返回一个对象,对象外部保留着数据。
<div id="app"> <my-cpn></my-cpn></div><template id="myCpn"> <div>{{message}}</div></template><script src="..."></script><script>let app = new Vue({ el: '#app', components: { 'my-cpn': { template: 'myCpn', data() { return{ message: 'web' } } } }})
父子通信-父传子props
如何进行父子组件间的通信呢?
- 通过
props
向子组件传递数据 - 通过事件向父组件发送音讯
props
根本用法
在组件中,应用props
来申明从父级接管到的数据
props
的值:
- 字符串数组,数组中的字符串就是传递时的名称。
- 对象,对象能够设置传递时的类型,也能够设置默认值等。
camelCase
(驼峰命名法) 的 prop
名须要应用其等价的 kebab-case
(短横线分隔命名) 命名:
Vue.component('blog-post', { // 在 JavaScript 中是 camelCase 的 props: ['postTitle'], template: '<h3>{{ postTitle }}</h3>'})<!-- 在 HTML 中是 kebab-case 的 --><blog-post post-title="hello!"></blog-post>
重申一次,如果你应用字符串模板,那么这个限度就不存在了。
prop
各自的名称和类型:
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor}
<!-- 动静赋予一个变量的值 --><blog-post v-bind:title="post.title"></blog-post><!-- 动静赋予一个简单表达式的值 --><blog-post v-bind:title="post.title + ' by ' + post.author.name"></blog-post><!-- 即使 `42` 是动态的,咱们依然须要 `v-bind` 来通知 Vue --><!-- 这是一个 JavaScript 表达式而不是一个字符串。--><blog-post v-bind:likes="42"></blog-post><!-- 用一个变量进行动静赋值。--><blog-post v-bind:likes="post.likes"></blog-post>
传入一个对象的所有属性
如果你想要将一个对象的所有属性都作为 prop 传入,你能够应用不带参数的 v-bind (取代 v-bind:prop-name)
:
post: { id: 1, title: 'My Journey with Vue'}<blog-post v-bind="post"></blog-post><blog-post v-bind:id="post.id" v-bind:title="post.title"></blog-post>
一个简略的props
传递:
<div id="app"> <child-cpn :message="message"></child-cpn></div><template id="childCpn"> <div> 显示信息:{{message}}</div></template><script>let app = new Vue({ el: '#app', data: { message: 'hello' }, components: { 'child-cpn': { templte: '#childCpn', props: ['message'] } }})</script>
在 Vue
中,父子组件的关系
props
向下传递,事件向上传递。
父组件通过 props
给子组件下发数据,子组件通过事件给父组件发送音讯。
props
反对的数据类型:
StringNumberBooleanArrayObjectDateFunctionSymbol
示例:
Vue.component('my-component',{ props: { // 根底的类型查看 propA: Number, // 多个可能的类型 propB: [String, Number], // propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, default: function(){ return {message: 'web'} } }, // 自定义验证函数 propF: { vfunc: function(value) { return value > 1 } } }})
子传父
代码:
this.$emit('item-click',item)
props
用于父组件向子组件传递数据,还有一种比拟常见的是子组件传递数据或事件到父组件中。
自定义事件:
- 在子组件中,通过
$emit()
来触发事件。 - 在父组件中,通过
v-on
来监听子组件事件。
自定义事件代码:
<div id="app"> <child-cpn @increment="changeTotal" @decrement="changeTotal"></child-cpn> <h2>点击次数</h2></div><template id="childCpn"> <div> <button @click="increment">+1</button> <button @click="decrement">-1</button> </div></template>let app = new Vue({ el: '#app', data: { total: 0 }, methods: { changeTotal(counter) { this.total = counter } }, components: { 'child-cpn': { template: '#childCpn', data(){ return{ counter: 0 } }, methods: { increment(){ this.counter++; this.$emit('increment', this.counter) }, decrement(){ this.counter--; this.$emit('decrement',this.counter) } } } }})
父子组件的拜访形式:$children
有时候须要父组件间接拜访子组件,子组件间接拜访父组件,或者是子组件拜访父组件。
- 父组件拜访子组件,应用
$children
或者$refs
- 子组件拜访父组件,应用
$parent
对于$children
的拜访:
this.$children
是一个数组类型,它蕴含所有子组件对象。- 通过遍历,取出所有子组件的
message
状态。
示例:
<div id="app"> <parent-cpn></parent-cpn></div>// 父组件template<template id="parentCpn"> <div> <child-cpn1></child-cpn1> <child-cpn2></child-cpn2> <button @click="showChildCpn">显示所有子组件信息</button> </div></template>// 子组件<template id="childCpn1"> <h2>我是子组件1</h2></template>// 子组件<template id="childCpn2"> <h2>我是子组件2</h2></template>Vue.component('parent-cpn',{ template: '#parentCpn', methods: { showChildCpn(){ for(let i=0; i<this.$children.length; i++){ console.log(this.$children[i].message) } } }})
父子组件的拜访形式:$parent
子组件中间接拜访父组件,能够通过$parent
- 尽管能够通过
$parent
来拜访父组件,然而尽量不要这样做 - 子组件应该尽量避免间接拜访父组件的数据,因为这样耦合度太高了。
父子组件的拜访形式$refs
$children
的缺点:
- 通过
$children
拜访子组件,是一个数组类型,拜访其子组件要通过索引值。 - 子组件过多时,须要拿其中一个时,不能确定它的索引值,还可能发生变化。
- 获取其中一个特定的组件,能够应用
$refs
$refs
的应用:
$refs
和ref
指令通常一起应用- 通过
ref
给某个子组件绑定一个特定的id
- 通过
this.$refs.id
能够拜访到该组件
示例:
<child-cpn1 ref="child1"></child-cpn1><child-cpn2 ref="child2"></child-cpn2><button @click="show">通过refs拜访子组件</button>show() { console.log(this.$refs.child1.message); console.log(this.$refs.child2.message);}
看看一个.vue
文件我的项目
<template> <div class="xxx"> <div class="xxx" :class="{active: currentIndex === index}" @click="itemClick(index)" v-for="(item,index) in titles"> <span>{{item}}</span> </div> </div></template><script> export default { name: 'xxx', props: { titles: { type: Array, default() { return [] } } }, data: function() { return { currentIndex: 0 } }, }</script><style scoped> .xxx { xxx: xxx; }</style>
三层局部:
slot插槽的应用
vue
中的代码slot
是什么呢,它叫插槽,<slot>
元素作为组件模板之中的内容散发插槽,传入内容后<slot>
元素本身将被替换。
v-slot
用法:
- 默认插槽
- 具名插槽
- 作用域插槽
slot
以及slot-scope
的用法:子组件编写,父组件编写
默认插槽
子组件:
// 子组件<template><div class="content">// 默认插槽<content-box class="text"><slot>默认值</slot><content-box></div></template>
slot
根本应用
- 在子组件中,应用
<slot>
能够为子组件开启一个插槽。 - 该插槽插入什么内容取决于父组件如何应用。
子组件定义一个插槽:
<slot>
中的内容示意,如果没有在该组件中插入任何其余内容,就默认显示改内容。
示例:
<div id="app"> <my-cpn></my-cpn> <my-cpn> <p>web</p> </my-cpn></div><template id="myCpn"> <div> <slot>我是谁</slot> </div></template><script>Vue.component('my-cpn',{ template: '#myCpn'})let app = new Vue({ el: '#app'})</script>
应用具名插槽
- 给
slot
元素增加一个name
属性 <slot name="web"></slot>
示例:
<div id="app"> // 没有任何内容 <my-cpn></my-cpn> // 传入某个内容 <my-cpn> <span slot="left">left</span> </my-cpn> <my-cpn> <span slot="left">left</span> <span slot="center">center</span> <span slot="right">right</span></div><template id="myCpn"> <div> <slot name="left">1</slot> <slot name="center">2</slot> <slot name="right">3</slot> </div></template><script> Vue.component('my-cpn', { template: '#myCpn' }) let app = new Vue({ el: '#app' })</script>
编译作用域
Vue
实例属性:
父组件模板的所有货色都会在父级作用域内编译,子组件模板的所有货色都会在子级作用域内编译。
父组件替换插槽的标签,然而内容由子组件来提供。
模块化开发
什么是模块化,将一组模块以正确的程序拼接到一个文件中的过程,模块是实现特定性能的一组属性和办法的封装。
利用构造函数封装对象
function web() { var arr = []; this.add = function(val) { arr.push(var) } this.toString = function() { return arr.join('') }}var a = new web();a.add(1); // [1]a.toString(); // "1"a.arr // undefined
示例:
var ModuleA = (function(){ // 定义一个对象 var obj = {} // 在对象外部增加变量和办法 obj.flag = true obj.myFunc = function(info) { console.log(info) }; // 将对象返回 return obj}
if(ModuleA.flag) { console.log('web')}ModuleA.myFunc('webweb')
常见的模块化标准:
CommonJS
,AMD
,CMD
,ES6
中的Modules
什么是AMD
,异步模块定义,它是在浏览器端实现模块化开发的标准,然而该标准不是原生js
反对的,应用AMD
标准进行开发的时候须要引入第三方的库函数,就是RequireJS
。
RequireJS
解决了多个js
文件可能有依赖的关系,被依赖的文件须要早于依赖它的文件加载到浏览器;js
加载的时候浏览器会进行页面渲染,加载文件越多,页面就会失去响应工夫越长。
CMD
是什么,它是通用模块定义,解决的问题和AMD
一样,不过在模块定义形式和模块加载机会上不同,CMD
须要额定的引入第三方的库文件SeaJS
。
JavaScript模块化编程
- 能够解决我的项目中的全局变量净化问题
- 开发效率高,利于多人协同开发
- 职责繁多,不便代码复用和保护
- 解决了文件的依赖问题
那么什么是模块化呢
将一个我的项目依照性能划分,实践上一个性能一个模块,互不影响,在须要的时候载入,尽量遵循高内聚低耦合。
理解CommonJS
CommonJS 是一种思维,实质上是可复用的JavaScript,它导出特定的对象,提供其它程序应用。
应用module.exports
和exports.obj
来导出对象,并在须要它的程序中应用require('module')
加载。
模块化的外围就是:导入和导出
导出:CommonJS
module.exports = { flag: true, test(a,b) { return a+b }, demo(a,b) { return a*b }}
导入:CommonJS
// CommonJS模块let {test, demo, flag} = require('moduleA');// =>let ma = require('moduleA');let test = ma.test;let demo = ma.demo;let flag = ma.flag;
因为网站开发越来越简单,js文件又很多,就会呈现一些问题:
- 变量名抵触
- 文件依赖复杂度高
- 页面加载过多,不利于保护
CommonJS
,定义模块,一个独自的js
文件就是一个模块,每个模块都有本人独自的作用域,在该模块外部定义的变量,无奈被其余模块读取,除了定义为global
对象的属性。
模块的导出:exports
和module.exports
模块的导入:require
- 在
node
中,每个模块外部都有要给本人的module
对象 - 在
module
对象中,有一个成员exports
也是一个对象 - 通过
exports
对象导出以后办法或变量,也可通过module.exports
导出 node
简化了操作,exports
等于module.exports
,相当于var exports = module.exports
es模块的导入和导出
export function add(num1, num2) { return num1 + num2}
export function accString(param) { if (param == 0) { return '关' }else if(param == 1) { return '开' }}import { accString } from '../../utils'
const name = 'web'export default name
export default
一个模块中蕴含某个性能,如果不心愿给性能命名,能够让导入者本人来定:
export default function(){ console.log('web')}
应用:
import myFunc from '../web.js'myFunc()
export default
在同一个模块中,不容许同时存在多个
import
应用
export
指令导出了模块对外提供的接口
import
指令用于导入模块中的内容
import {name, age} from './web.js'
通过*
能够导入模块中所有所有的export
变量
import * as web from './web.js'console.log(web.name);
最初
我是程序员哆啦A梦,蓝瘦子,简书万粉优良创作者,掘金优良作者、CSDN博客专家,云+社区社区沉闷作者,致力于打造一系列可能帮忙程序员进步的优质文章。网站@http://www.dadaqianduan.cn