第六章 前端开发学习——Vue框架javascript
1、Vue介绍css
2、Vue实例html
3、Vue视图前端
4、Vue组件vue
5、Vue过分动画java
1、Vue介绍webpack
1.前端框架介绍web
A)前端框架有npm
B)Angular、Vue、React的区别bootstrap
Angular1和Angular2之后的版本 是彻底不一样的两个框架; 通常Angular1被称做Angular.js, Angular以后的版本被称做 Angular
Vue与Angular的语法很是类似
Vue没有像Angular同样深刻开发,只保证了基本功能。 Angular过于笨重
Vue的运行速度比Angular快得多
Angular的脏检查机制带来诸多性能问题
2.什么是Vue(what):
Vue与JQuery的区别:
Vue是前端框架(MVVM) ,对项目进行分层。 处理数据
Vue优势:
MVVM
V 视图层 View
VM (控制层) VIEW-MODEL
3.多页面应用与单页面应用
A)多页面应用(MultiPage Application,MPA)
多页面跳转刷新全部资源,每一个公共资源(js、css等)需选择性从新加载,经常使用于 app 或 客户端等
B)单页面应用(SinglePage Web Application,SPA)
只有一张Web页面的应用,是一种从Web服务器加载的富客户端,单页面跳转仅刷新局部资源 ,公共资源(js、css等)仅需加载一次,经常使用于PC端官网、购物等网站
二者对比:
4.Vue入门
A)安装
方式一:直接<script>引入
方式二:CDN
https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js
https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js
# 以手动指定版本号
方式三:NPM
在用 Vue 构建大型应用时推荐使用 NPM 安装[1]。NPM 能很好地和诸如 webpack 或 Browserify 模块打包器配合使用。同时 Vue 也提供配套工具来开发单文件组件。
npm install vue
方式四:构建工具 (CLI)
npm install -g @vue/cli
vue create my-project
2、Vue实例
1.建立实例
A)建立实例
var app = new Vue({ el: '#app', })
B)挂载元素
2.数据与方法
A)添加数据data
Vue({
data: {
}
})
B)实例方法
Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来
3.计算属性和侦听器
A)添加方法methods
Vue({
methods: {
}
})
B)添加计算属性computed
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue</title> <style> p { border:1px solid #ccc; padding: 20px; width: 400px; } </style> </head> <body> <div id="app"> <h1>Vue计算属性</h1> <hr> firstName: <input type="text" v-model='firstName'> <br> lastName: <input type="text" v-model='lastName'> <br> <p> {{ fullName }} </p> </div> <script src="../vue.js"></script> <script> //建立Vue实例 let vm = new Vue({ el:'#app', data: { firstName:'', lastName:'' }, computed: { fullName: function(){ return this.firstName + this.lastName } } }); //console.log(vm.fullName) //console.log(typeof vm.fullName) </script> </body> </html>
Vue({ computed: { 属性名: function(){ } } })
C)添加侦听属性watch
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue</title> <style> p { border:1px solid #ccc; padding: 20px; width: 400px; } </style> </head> <body> <div id="app"> <h1>Vue计算属性</h1> <hr> 请输入全名: <input type="text" v-model='fullName'> <p> lastName: {{ lastName }} </p> <p> firstName: {{ firstName }} </p> </div> <script src="../vue.js"></script> <script> //建立Vue实例 let vm = new Vue({ el:'#app', data: { fullName:'', firstName:'', lastName:'' }, watch: { fullName: function(){ this.firstName = this.fullName.split(' ')[0] this.lastName = this.fullName.split(' ')[1] } } }) </script> </body> </html>
Vue({ watch: { 属性: function(){ } } })
D)方法,计算属性,侦听属性的区别
它们三者都是以函数为主体,可是它们之间却各有区别。
计算属性与方法:
咱们能够将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是彻底相同的。然而,不一样的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会从新求值。这就意味着只要 message 尚未发生改变,屡次访问 reversedMessage 计算属性会当即返回以前的计算结果,而没必要再次执行函数。
相比之下,每当触发从新渲染时,调用方法将总会再次执行函数。
计算属性与侦听属性:
4.delimiters
做用:改变纯文本插入分隔符。
5.生命周期
A)生命周期钩子函数(红色重要经常使用)
(1)beforeCreate
在实例初始化以后,数据观测(data observer)和 event/watcher 事件配置以前被调用。
(2)created:
数据建立成功 data methods computed watch
在这里从服务器获取数据
在实例建立完成后被当即调用。在这一步,实例已完成如下的配置:数据观测(data observer)、属性和方法的运算、watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
(3)beforeMount
在挂载开始以前被调用,相关的 render 函数将首次被调用。
注意:该钩子在服务器端渲染期间不被调用。
(4)mounted:此时,Vue实例已经挂载到元素上。 操做DOM请在这里。
el 被新建立的 vm.el替换,并挂载到实例上去以后调用该钩子。若是root实例挂载了一个文档内元素,当mounted被调用时vm.el 也在文档内。页面渲染完成后初始化的处理均可以放在这里。
注意:mounted 不会承诺全部的子组件也都一块儿被挂载。
(5)beforeUpdate
数据更新时调用,发生在虚拟 DOM 从新渲染和打补丁以前。
你能够在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
(6)updated
因为数据更改致使的虚拟 DOM 从新渲染和打补丁,在这以后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,因此你如今能够执行依赖于 DOM 的操做。然而在大多数状况下,你应该避免在此期间更改状态。若是要相应状态改变,一般最好使用计算属性或 watcher 取而代之。
注意:updated 不会承诺全部的子组件也都一块儿被重绘。
(7)activated
keep-alive 组件激活时调用。
(8)deactivated
keep-alive 组件停用时调用。
(9)beforeDestroy
实例销毁以前调用。在这一步,实例仍然彻底可用。
(10)destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的全部东西都会解绑定,全部的事件监听器会被移除,全部的子实例也会被销毁。
B)生命周期图示
3、Vue视图
1.基本模板语法
A)文本
v-text
指令也能够用于数据绑定,若是要更新部分的 textContent ,须要使用 插值。v-once
指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新B)原始HTML
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你须要使用 v-html 指令
Tips:你的站点上动态渲染的任意 HTML 可能会很是危险,由于它很容易致使 XSS 攻击。请只对可信内容使用 HTML 插值,毫不要对用户提供的内容使用插值。
C)属性
D)使用JavaScript表达式(不建议)
{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>
{{ var a = 1 }} <!-- 这是语句,不是表达式 -->
{{ if (ok) { return message } }} <!-- 流控制也不会生效,请使用三元表达式 -->
E)防止刷新或加载闪烁
2.指令
v-bind缩写
<!-- 完整语法 --> <a v-bind:href="url">...</a> <!-- 缩写 --> <a :href="url">...</a>
v-on缩写
<!-- 完整语法 --> <a v-on:click="doSomething">...</a> <!-- 缩写 --> <a @click="doSomething">...</a>
3.条件渲染与列表渲染
A)条件渲染
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue条件渲染</title> <style> .box { border:1px solid #ccc; padding: 10px; width: 600px; } </style> </head> <body> <div id="app"> <h1>条件渲染</h1> <hr> <button @click="isShow = !isShow">改变</button> <!-- <div class="box" v-if="true"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem quo saepe, eum nisi. Atque, pariatur ad sapiente alias, dignissimos tempora iusto ullam veritatis, obcaecati ipsa dicta sunt dolorem ducimus eos! </div> --> <template v-if="isShow"> <h2>锄禾</h2> <p>锄禾日党务</p> <p>锄禾日党务</p> <p>锄禾日党务</p> </template> <div class="box" v-else> HELLO 同志 </div> <hr> <input type="number" v-model="tag" max="3" min="0" step="1"> <div class="box" v-if="tag == 0" key="1"> 00000000000000000000000000 </div> <div class="box" v-else-if="tag == 1" key="2"> 1111111111111111111111111111 </div> <div class="box" v-else-if="tag == 2" key="3"> 222222222222222222222222222222 </div> <div class="box" v-else key="4"> else esle else else else else </div> <hr> <p v-show="false">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam incidunt perspiciatis, soluta repellendus ipsa placeat hic? Aspernatur modi, corporis incidunt deserunt accusantium laudantium, voluptates maxime eveniet maiores a labore nam.</p> </div> <script src="../vue.js"></script> <script> new Vue({ el:'#app', data: { isShow: true, tag:0 } }) </script> </body> </html>
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
<h1 v-show="ok">Hello!</h1>
与 v-if 的区别
v-if
是“真正”的条件渲染,由于它会确保在切换过程当中条件块内的事件监听器和子组件适当地被销毁和重建。v-show
就简单得多——无论初始条件是什么,元素老是会被渲染,而且只是简单地基于 CSS 进行切换。
B)列表渲染
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>列表渲染</title> </head> <body> <div id="app"> <h1>列表渲染</h1> <hr> <button @click="updateItemList()">更新数组</button> <ul> <li v-for="(item,index) in itemList"> {{index}} {{item}} </li> </ul> <table> <tr> <th>序号</th> <th>姓名</th> <th>年龄</th> <th>工做</th> <th>地址</th> </tr> <tr v-for="item in dataList" :key="item.id" v-if="item.id > 2"> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td>{{ item.age }}</td> <td>{{ item.job }}</td> <td>{{ item.address }}</td> </tr> </table> </div> <script src="../vue.js"></script> <script> new Vue({ el:'#app', data: { itemList: ['曹操', '诸葛亮', '刘备', '孙权', '周瑜', '董卓'], dataList: [ {id:1, name:'曹操', age:19, job:'大王', address:'许都'}, {id:2,name:'诸葛亮', age:19, job:'丞相', address:'许都'}, {id:3,name:'刘备', age:19, job:'大王', address:'许都'}, {id:4,name:'孙权', age:19, job:'大王', address:'许都'}, {id:5,name:'董卓', age:19, job:'大王', address:'许都'} ] }, methods: { updateItemList: function(){ //this.itemList[1] = '贾宝玉' //this.itemList.push('贾宝玉'); //this.itemList.pop(); //this.itemList.reverse(); Vue.set(this.itemList, 1, '赵云') } } }) </script> </body> </html>
<ul id="example-1"> <li v-for="item in items"> {{ item.message }} </li> </ul>
v-for 还支持一个可选的第二个参数为当前项的索引
<ul id="example-2"> <li v-for="(item, index) in items"> {{ index }} - {{ item.message }} </li> </ul>
<!-- 只取值 --> <li v-for="value in object"> {{ value }} </li> <!-- 值、属性名 --> <div v-for="(value, key) in object"> {{ key }}: {{ value }} </div> <!--值、属性名、索引--> <div v-for="(value, key, index) in object"> {{ index }}. {{ key }}: {{ value }} </div>
数组
因为 JavaScript 的限制,Vue 不能检测如下变更的数组:
当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如:vm.items.length = newLength
对象
仍是因为 JavaScript 的限制,Vue 不能检测对象属性的添加或删除
方法
Vue.set()
vm.$set()
<div>
<span v-for="n in 10">{{ n }} </span>
</div>
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每一个 v-for 循环中。
<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }} </li>
3.样式
A)绑定HTML Class
对象语法
方法一:
<div v-bind:class="{ active: isActive }"></div>
方法二:
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"> </div>
方法三:
<div v-bind:class="classObject"></div>
数组语法
<div v-bind:class="[activeClass, errorClass]"></div>
B)绑定内联样式
对象语法
方法一:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
方法二:
<div v-bind:style="styleObject"></div>
数组语法
数组语法能够将多个样式对象应用到同一个元素上
<div v-bind:style="[baseStyles, overridingStyles]"></div>
当 v-bind:style
使用须要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。
4.事件绑定
A)事件绑定
监听事件
事件处理方法
<div id="example-2"> <!-- `greet` 是在下面定义的方法名 --> <button v-on:click="greet">Greet</button> </div>
内联调用方法
有时也须要在内联语句处理器中访问原始的 DOM 事件。能够用特殊变量 $event 把它传入方法
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
B)事件修饰符
.stop
<!-- 阻止单击事件继续传播 阻止事件冒泡--> <a v-on:click.stop="doThis"></a>
.prevent
<!-- 提交事件再也不重载页面 阻止默认事件--> <form v-on:submit.prevent="onSubmit"></form>
.capture
<!-- 添加事件监听器时使用事件捕获模式 --> <!-- 即元素自身触发的事件先在此到处理,而后才交由内部元素进行处理 --> <div v-on:click.capture="doThis">...</div>
.self
<!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <!-- 即事件不是从内部元素触发的 --> <div v-on:click.self="doThat">...</div>
.once
<!-- 点击事件将只会触发一次 2.1.4新增--> <a v-on:click.once="doThis"></a>
.passive
<!-- 滚动事件的默认行为 (即滚动行为) 将会当即触发 2.3.0新增--> <!-- 而不会等待 `onScroll` 完成 --> <!-- 这其中包含 `event.preventDefault()` 的状况 --> <!--.passive 修饰符尤为可以提高移动端的性能。--> <div v-on:scroll.passive="onScroll">...</div>
补充:
①修饰符能够串联
<a v-on:click.stop.prevent="doThat"></a>
②容许只有修饰符
<form v-on:submit.prevent></form>
C)按键修饰符
数字
按键别名
<!-- 回车键 --> <input v-on:keyup.enter="submit">
<!-- 只有在 `keyCode` 是 13 时(ASCII码13是回车键)调用 `vm.submit()` --> <input v-on:keyup.13="submit">
D)系统修饰键
能够用以下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
组合键
<!-- Alt + C --> <input @keyup.alt.67="clear"> <!-- Ctrl + Click --> <div @click.ctrl="doSomething">Do something</div>
5.表单输入绑定
你能够用 v-model
指令在表单 <input>
及 <textarea>
元素上建立双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。
v-model
会忽略全部表单元素的 value、checked、selected 特性的初始值而老是将 Vue 实例的数据做为数据来源。你应该经过 JavaScript 在组件的 data 选项中声明初始值。
A)基础语法
①文本
<input v-model="message" placeholder="edit me"> <textarea v-model="message" placeholder="add multiple lines"></textarea>
②复选框
单个复选框
<input type="checkbox" id="checkbox" v-model="checked"> <input type="checkbox" v-model="toggle" true-value="yes" false-value="no" >
多个复选框
<div id='example'> <input type="checkbox" id="jack" value="Jack" v-model="checkedNames"> <label for="jack">Jack</label> <input type="checkbox" id="john" value="John" v-model="checkedNames"> <label for="john">John</label> <input type="checkbox" id="mike" value="Mike" v-model="checkedNames"> <label for="mike">Mike</label> <br> <span>Checked names: {{ checkedNames }}</span> </div>
③单选按钮
绑定value对应的字符串
<div id="example"> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> </div>
④选择框
单选,绑定对应所选的值
<div id="example"> <select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> </div>
多选时 ,绑定到一个数组
<div id="example"> <select v-model="selected" multiple style="width: 50px;"> <option>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected }}</span> </div>
B)修饰符
.lazy
在默认状况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步
添加 lazy 修饰符,从而转变为使用 change 事件进行同步
<!-- 在“change”时而非“input”时更新 --> <input v-model.lazy="msg" >
若是想自动将用户的输入值转为数值类型,能够给 v-model 添加 number 修饰符
<input v-model.number="age" type="number">
自动过滤用户输入的首尾空白字符,能够给 v-model 添加 trim 修饰符
<input v-model.trim="msg">
4、Vue组件
什么是组件(what):
组件(Component)是 Vue.js 最强大的功能之一。组件能够扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些状况下,组件也能够表现为用 is 特性进行了扩展的原生 HTML 元素。
全部的 Vue 组件同时也都是 Vue 的实例,因此可接受相同的选项对象(除了一些根级特有的选项)并提供相同的生命周期钩子。
如何理解组件:
简单理解,每一个Page就是一个组件 (注册组件、登陆组件、商品列表组件),页面的组成部分 (轮播图,选项卡,下拉菜单...),组件其实就是一个独立的 HTML,它的内部可能有各类结构、样式、逻辑,某些地方来讲有些像 iframe,它都是在页面中引入以后展示另外一个页面的内容,但实际上它与 iframe 又彻底不一样,iframe 是一个独立封闭的内容,而组件既是一个独立的内容,仍是一个受引入页面控制的内容。
一般一个应用会以一棵嵌套的组件树的形式来组织:
例如,你可能会有页头、侧边栏、内容区等组件,每一个组件又包含了其它的像导航连接、博文之类的组件。
为何要使用组件(why):
举个简单的列子,最近个人项目中有一个日历模块,多个页面都要用这个日历,而每一个页面的日历都存在一些差异,若是不使用组件,我要完成这个项目,作到各个页面的日历大致一致,而部分地方存在差别,我可能就须要写几套日历代码了。
而使用组件呢?一套代码,一个标签,而后分别在不一样地方引用,根据不一样的需求进行差别控制便可。
<calendar></calendar>
我能够经过给 calendar 传递值实如今本页面对日历的控制,让它知足我这个页面的某些单独需求。
有人会问,你 calendar 标签是什么鬼?前面有这么一句话,组件是自定义元素。calendar 就是我自定义的元素,它就是一个组件。因此在项目中,你会发现有各类五花八门的标签名,他们就是一个个组件。
组件的构成:
data
methods
computed
watch
template 模板
钩子函数
...
1.组件基础
A)注册组件
咱们把建立一个组件称为注册组件,若是你把组件理解成为变量,那么注册组件你就能够理解为声明变量。咱们经过 Vue.component 来注册一个全局组件。
Vue.component(componentName, { //选项 })
对于自定义组件的命名,Vue.js 不强制遵循 W3C 规则(小写,而且包含一个短杠),尽管这被认为是最佳实践。
*根实例
一个组件就是一个 vue实例
根实例(new Vue()) 其实根实例 就是根组件
B)组件选项
与建立Vue示例时的选项相同(除了一些根级特有的选项)
一个组件的 data 选项必须是一个函数 (每一个组件实例具备本身的做用域,组件复用不会互相影响)
C)组件使用
组件能够复用
D)组件模板
每一个组件模板必须只有一个根元素
模板形式一:内联模板 (不推荐)
<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
<p>Not parent's transclusion content.</p>
</div>
</my-component>
模板形式二:template 选项指定字符串 (模板字符串)
模板形式三:X-Templates模板
<script type="text/x-template" id="hello-world-template"> <p>Hello hello hello</p> </script> Vue.component('hello-world', { template: '#hello-world-template' })
模板形式四:单文件组件(.vue)(最优,工做中使用较多)
E)全局组件与局部组件
全局组件
局部组件
F)父组件与子组件
父子组件断定只在组件使用时考虑
下图根组件模板内使用其它组件,因此这些组件都是子组件
2.组件之间的嵌套使用与互相通讯
组件设计初衷就是要配合使用的,最多见的就是造成父子组件的关系:组件 A 在它的模板中使用了组件 B。它们之间必然须要相互通讯:父组件可能要给子组件下发数据,子组件则可能要将它内部发生的事情告知父组件。
每一个组件的做用域都是独立的,因此在组件嵌套使用的时候子组件不能直接使用父组件中的数据。
A)父组件经过Prop向子组件传递数据
基本使用
在子组件中声明 prop,而后添加一个 message
<child message="hello!"></child>
Vue.component('child', { // 声明 props props: ['message'], // 就像 data 同样,prop 也能够在模板中使用 // 一样也能够在 vm 实例中经过 this.message 来使用 template: '<span>{{ message }}</span>' })
一个组件默承认以拥有任意数量的 prop,任何值均可以传递给任何 prop。咱们可以在组件实例中访问这个值,
而后直接传入值就能够在子组件中使用 message。
Tips:若某个组件须要在根组件中使用,组件(Vue.component)必须先注册到Vue类中再实例化
其它形式:
a)
b)
Prop 的大小写
HTML 中的特性名是大小写不敏感的,因此浏览器会把全部大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名须要使用其等价的 kebab-case (短横线分隔命名) 命名
<blog-post v-bind="post"></blog-post>
等价于
<blog-post v-bind:id="post.id" v-bind:title="post.title" ></blog-post>
咱们能够为组件的 prop 指定验证要求
Vue.component('my-component', { props: { // 基础的类型检查 (`null` 匹配任何类型) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true }, // 带有默认值的数字 propD: { type: Number, default: 100 }, // 带有默认值的对象 propE: { type: Object, // 对象或数组且必定会从一个工厂函数返回默认值 default: function () { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function (value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 } } } })
类型列表:
B)子组件经过事件向父组件传递数据
在父组件中使用 on(eventName)监听事件,而后在子组件中使用on(eventName)监听事件,而后在子组件中使用emit(eventName) 触发事件,这样就能实现子组件向父组件传值。
①子组件定义模板,定义事件addCount()
②子组件向父组件发送事件this.$emit
③父组件的模板中的子组件经过自定义事件监听
④父组件定制对应方法
使用事件抛出一个值
有的时候用一个事件来抛出一个特定的值是很是有用的。这时可使用 $emit
的第二个参数来提供这个值
3.插槽slot
A)经过插槽分发内容
Something bad happened.· 会替换掉 slot标签
Vue.component('alert-box', { template: ` <div class="demo-alert-box"> <strong>Error!</strong> <slot></slot> </div> ` })
<alert-box>
Something bad happened.
</alert-box>
B)模板中多个插槽
组件模板
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
调用组件
<base-layout> <template slot="header"> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <p slot="footer">Here's some contact info</p> </base-layout>
C)插槽默认内容
<button type="submit"> <slot>Submit</slot> </button>
4.动态组件
A)实现动态组件
在不一样组件之间进行动态切换
<component is="组件名" class="tab"></component>
components: { 'login-component': { template: ` <form action="#"> <div class="form-group"> <label for="#">用户名</label> <input type="text" class="form-control" /> </div> <div class="form-group"> <label for="#">密码</label> <input type="password" class="form-control" /> </div> <button class="btn btn-default btn-block">登陆</button> </form> ` }, 'register-component': { template: ` <form action="#"> <div class="form-group"> <label for="#">用户名</label> <input type="text" class="form-control" /> </div> <div class="form-group"> <label for="#">密码</label> <input type="password" class="form-control" /> </div> <div class="form-group"> <label for="#">确认密码</label> <input type="password" class="form-control" /> </div> <button class="btn btn-primary btn-block">注册</button> </form> ` }, 'no-login-component': { template:` <div> 我是李刚,我不用登陆,我牛逼 </div> ` } }
B)在动态组件上使用 keep-alive
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
主要用于保留组件状态或避免从新渲染
<!-- 基本 --> <keep-alive> <component :is="view"></component> </keep-alive> <!-- 多个条件判断的子组件 --> <keep-alive> <comp-a v-if="a > 1"></comp-a> <comp-b v-else></comp-b> </keep-alive>
C)绑定组件选项对象
动态组件能够绑定 组件选项对象(有component属性的对象),而不是已注册组件名的示例
var tabs = [ { name: 'Home', component: { template: '<div>Home component</div>' } }, { name: 'Posts', component: { template: '<div>Posts component</div>' } }, { name: 'Archive', component: { template: '<div>Archive component</div>', } } ] new Vue({ el: '#dynamic-component-demo', data: { tabs: tabs, currentTab: tabs[0] } })
<component v-bind:is="currentTab.component" class="tab" > </component>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>动态组件</title> <link rel="stylesheet" href="../dist/css/bootstrap.css"> <style> .panel { border-top: none; } </style> </head> <body> <div id="app"> <div class="container"> <div class="page-header"> <h1>动态组件</h1> </div> <div class="row"> <div class="col-md-6"> <ul class="nav nav-tabs"> <li v-for="item,index in tabs" :class="{active:isTab(index)}" @click="setTab(index)"><a href="javascript:0">{{ item.tabName }}</a></li> </ul> <div class="panel"> <div class="panel-body"> <keep-alive> <component :is="tabs[tab].tabComponent"></component> </keep-alive> </div> </div> </div> </div> </div> </div> <script src="../dist/js/vue.js"></script> <script> //建立根实例 new Vue({ el:'#app', data: { tabs: [ {'tabName':'登陆', 'tabComponent':'login-component'}, {'tabName':'注册', 'tabComponent':'register-component'}, {'tabName':'免登陆', 'tabComponent':'no-login-component'}, ], tab: 0 }, methods: { isTab(index) { return this.tab === index; }, setTab(index) { this.tab = index; } }, components: { 'login-component': { template: ` <form action="#"> <div class="form-group"> <label for="#">用户名</label> <input type="text" class="form-control" /> </div> <div class="form-group"> <label for="#">密码</label> <input type="password" class="form-control" /> </div> <button class="btn btn-default btn-block">登陆</button> </form> ` }, 'register-component': { template: ` <form action="#"> <div class="form-group"> <label for="#">用户名</label> <input type="text" class="form-control" /> </div> <div class="form-group"> <label for="#">密码</label> <input type="password" class="form-control" /> </div> <div class="form-group"> <label for="#">确认密码</label> <input type="password" class="form-control" /> </div> <button class="btn btn-primary btn-block">注册</button> </form> ` }, 'no-login-component': { template:` <div> 我是李刚,我不用登陆,我牛逼 </div> ` } } }) </script> </body> </html>
5.组件的其余特性
A)解析DOM模板时的注意事项
有些 HTML 元素,诸如 <ul>
、<ol>
、<table>
和 <select>
,对于哪些元素能够出如今其内部是有严格限制的。而有些元素,诸如 <li>
、<tr>
和 <option>
,只能出如今其它某些特定的元素内部。
<table> <blog-post-row></blog-post-row> </table>
上面的写法,渲染效果会不甚理想,能够采用如下写法
<table> <tr is="blog-post-row"></tr> </table>
须要注意的是若是咱们从如下来源使用模板的话,这条限制是不存在的:
<script type="text/x-template">
B)Prop的一些问题
HTML 中的特性名是大小写不敏感的,因此浏览器会把全部大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名须要使用其等价的 kebab-case (短横线分隔命名) 命名
若是你使用字符串模板,那么这个限制就不存在了。
组件上定义的非Prop属性 会传递到 组件模板的根元素上
class 和 style 特性会很是智能,即两边的值会被合并起来
子组件中,对prop从新赋值,会报警告
C)组件的相关问题
想要在一个组件的根元素上直接监听一个原生事件。这时,你可使用 v-on 的 .native 修饰符
<base-input v-on:focus.native="onFocus"></base-input>
在有些状况下,咱们可能须要对一个 prop 进行“双向绑定”
推荐以 update:my-prop-name 的模式触发事件
//子组件中 this.$emit('update:title', newTitle) <!-- 上级组件 模板中 --> <text-document v-bind:title="doc.title" v-on:update:title="doc.title = $event" ></text-document>
以上写法能够换成下列写法
<text-document v-bind:title.sync="doc.title"></text-document>
5、Vue过分动画
【待补充】