Vue
是一套构建用户界面的渐进式框架,与其他框架不同的是,Vue可以自底向上逐层应用。Vue的核心库只关注视图层易于上手,还便于与第三方库或既有项目整合。兼容性:Vue不支持IE8及以下版本,因为Vue使用了无法模拟的ES5特性,但它支持所有兼容ES5的浏览器。 Vue虽然没有完全遵循MVVM模型,但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel 的缩写) 这个变量名表示 Vue 实例。
开发者工具:再使用Vue时,推荐再浏览器上安装Vue Devtools。它允许再一个更友好的界面中审查和调试Vue应用。
VS Code编码工具添加 Vetur(开发工具插件)
-
安装: npm install -g @vue/cli
-
创建一个项目: vue create my-project(项目名)
-
项目目录解读:
node_modules : 依赖包
public :里边有index.html模板文件
.browserslistrc : 告诉浏览器不能低于哪个版本
.gitignore : git的忽略文件
.babel.config.js : babel的配置文件
src :
assets : 图片,css
components : 公共组件
App.vue : 第一个组件
main.js : 主入口文件
registerServiceWorker.js : 它是用来做离线缓存等任务的,实际上就是为Vue项目注册了一个service worker。这样的话,如果在线上,只要访问过一次该网站,以后即使没有网络也可以访问(此时使用的是之前缓存的资源)。 -
项目运行命令 npm run serve | yarn serve(安装yarn)
模板语法
Vue.js使用了基于HTML的模板语法,允许开发者声明式的将DOM绑定至底层Vue实例的数据,所有Vue的模板都是合法的HTML。在底层的实现上,Vue将模板编译成虚拟DOM渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
语法:Message: {{ msg }} 双花括号中,可以存在语法,单行表达式,必须有返回值,有结果的才叫表达式
缩写: v-bind ---> : --- v-on -----> @
你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。请只对可信内容使用 HTML插值,绝不要对用户提供的内容使用插值。
模板表达式都被放在沙盒中,只能访问全局变量的一个白名单,如 Math 和 Date
你不应该在模板表达式中试图访问用户定义的全局变量。
胡子语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind 指令:<div v-bind:id="dynamicId"></div>
在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写
条件渲染
- v-if指令用于条件性的渲染一块内容,这块内容只会再指令表达式返回true时被渲染。v-if是一个指令,必须添加到一个元素上。经常结合
<template></template>
标签使用。 - 另一个用于根据条件展示元素的是 v-show 指令。用法大致一样,不同的是带有 v-show 的元素始终会被渲染并保留在 DOM
中。v-show 只是简单地切换元素的 CSS 属性 display。注意,v-show 不支持<template>
元素,也不支持 v-else。
v-if 和 v-show 的区别:
v-if 是真正的条件渲染,它会确保再切换过程中条件块内的事件监听和子组件适当的被销毁和重建。v-if是惰性的,如果在初始渲染时条件为假则什么也不做,直到变为true才会渲染条件快。相比之下,v-show不管初始条件是什么,元素总是会被渲染,并且只是简单的基于CSS进行切换。一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此如果需要非常频繁的切换则使用v-show好;如果在运行时条件很少改变则使用v-if较好。
- v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用。
- Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 属性即可
- 不推荐同时使用 v-if 和 v-for,当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。
列表渲染
v-for指令基于一个数组来渲染一个列表。使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。在 v-for 块中,我们可以访问所有父作用域的 property。你也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法。
语法: v-for="(item,name,index) in arr" :key=“index”
事件处理
监听事件 : v-on指令
语法:<button @:click="clickme" || @:click="clickme(参数,$event)">事件对象</button>
事件处理方法 : 在methods对象中定义方法
事件修饰符:修饰符可以串联
.stop----event.stopPropagation()
.prevent-----event.preventDefault()
.capture
.self
.once-----事件只能触发一次
.passive
- Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。这个 .passive 修饰符尤其能够提升移动端的性能。
- 滚动事件的默认行为 (即滚动行为) 将会立即触发,而不会等待
onScroll
完成,这其中包含event.preventDefault()
的情况
<div v-on:scroll.passive="onScroll">...</div>
不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。
【注】使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
- 按键修饰符 :Vue 允许为 v-on 在监听键盘事件时添加按键修饰符
.enter .tab .delete (捕获“删除”和“退格”键) .esc .space .up .down .left .right - 系统修饰键
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。 .ctrl .alt .shift .meta
【注意】修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17
数组的更新检测
-
变异方法:Vue将被侦听的数组的变异方法进行了包裹,所以它们也将会触发视图更新。 push() pop() shift() unshift() splice() sort() reverse()
-
非变异方法:替换数组,filter() concat() slice() 它们不会改变原数组,而总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组
-
由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。 对象变更检测注意事项
由于JS的限制,Vue不能检测对象属性的添加或删除:对于已经创建的实例,Vue不允许动态添加根级别的响应式属性,但是可以使用Vue.set(object,propertyName,value)
this.$set(this.currentObj,‘name’,‘王五’)
Class与Style绑定
- 绑定HTML Class
Vue中使用 v-bind 来操作元素的class列表和内联样式。
对象语法 :
<div v-bind:class="{active:isActive}"></div>
<div class="static" v-bind:class="{active:isActive,box:isBox}"></div>
数组语法:
<div v-bind:class="[activeClass,errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
如果你也想根据条件切换列表中的 class,可以用三元表达式:
<div v-bind:class="[isActive ? activeClass : errorClass]"></div>
数组嵌套对象:必须是数组嵌套对象,不能是对象嵌套数组
<div v-bind:class="[{active:isActive},errorClass]"></div>
绑定内联样式
v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式或短横线分隔(记得用引号括起来)来命名<div v-bind:style="{color:activeColor,fontSize:20+'px'}"></div>
绑定的数据对象不必内联定义在模板里:
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
自动添加前缀
当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS property 时,如 transform,Vue.js 会自动侦测并添加相应的前缀。
多重值
从 2.3.0 起你可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。
表单输入绑定
Vue中使用 v-model 指令在表单,以及元素上创建双向数据绑定。本质上是语法糖,它负责监听用户的输入事件以更新数据。v-model 会忽略所有表单元素的 value、checked、selected attribute 的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。
例子:
<input v-model="message" placeholder="edit me">
<p>显示 : {{message}}</p>
在文本区域插值 ({{text}}) 并不会生效,应用 v-model 来代替。
修饰符 :
.lazy , .number , .trim
计算属性和侦听器
- 计算属性
在模板中放入太多逻辑会让模板过重且难以维护,计算属性由此而来。对于任何复杂逻辑,你都应当使用计算属性
例:<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
这里我们声明了一个计算属性 reversedMessage。
我们提供的函数将用作 属性 this.reversedMessage 的 getter 函数。
-
计算属性缓存 vs 方法
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。每当触发重新渲染时,调用方法将总会再次执行函数(计算属性不是实时更新的,而方法每一次都执行,耗费内存更大) -
侦听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
}
组件基础
Vue组件本质是一个拥有预定义选项的Vue实例。<style>
标签里的scoped属性指的是:此样式只在当前组件生效。
- 创建组件 : 组件时可复用的Vue实例
组件的组成部分:HTML(必选项) JavaScript CSS
Template 中必须有且只有一个根元素
引入组件 :
引入 :import A from ‘./xxx’
注入 : components:{ A }
使用 : < A /> - 组件复用
JS中的data必须是函数,如果不是函数则无法做到每个组件都是独立的对象,此点受到了JS本质的影响,如果无法独立,则无法做到组件的复用。
【注意】不要在选项 property 或回调上使用箭头函数,因为箭头函数并没有 this,this 会作为变量一直向上级作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。
组件的分类
-
智能组件
作用 : 获取数据,处理数据,响应业务 -
木偶组件
作用 : 展示效果
组件组织
通常一个应用会以一棵嵌套的组件树的形式来组织,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。每个组件必须只有一个根元素。
- 通过 Prop 向子组件传递数据,一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
父组件:Nav是子组件
<Nav :NavData="LeftNav"/>
<Nav :NavData="RightNav"/>
//这里的id取的是data函数里边的数据,id的数据类型是number
<Nav title="我是父组件传递数据" desc="我是描述信息" :id="id"/>
data(){
return{
LeftNav:['导航1','导航2','导航3'],
RightNav:['导航4','导航5','导航6']
}
}
子组件:通过 props 接收
//遍历获取传过来的数据
<li v-for="(item,index) in NavData" :key="index">{{item}}</li>
方式1: props:["NavData"]
方式2: props:{
title:String,
desc:String,
id:Number//也可以是多类型 id:[Number,String]
}
-
Prop类型 :Number , String , Boolean , Array , Object , Function , Promise
-
传递静态或动态Prop
<Nav title="我是传递的静态数据" :id="id"+"我是传递的动态数据"/>
-
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
【注】在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。 -
Prop验证
props:{
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
propB: [String, Number], //多个可能的类型
propC: {
type: String,
required: true // 必填的字符串
},
propD: {
type: Number,
default: 100 // 带有默认值的数字
},
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: () { // 带有默认值的对象
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
自定义事件
监听子组件事件(子组件向父组件传递数据)
-
子组件定义点击事件,在事件中子组件可以通过调用内建的 $emit 方法并传入事件名称来触发一个事件
-
父组件用子组件定义的事件名来自定义事件(须在子组件的标签上),在事件中通过参数来接收子组件传递过来的数据
例:子组件:<button @click="sendData">子组件数据传递到父组件</button>
sendData(){ this.$emit('mySend',this.shiwu) || this.$emit('update:mySend',this.shiwu) }
父组件 :<SliderChild @mySend="getData"/> || <SliderChild @mySend="data=>msg=data"/> || <SliderChild :mySend.sync="msg"/>
getData(data){ console.log(data) }
.sync修饰符
【注】带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似 v-model。
EventBus-同级组件之间的数据传递
优点:没有别的级别关系的限制;缺点:EventBus不会随着组件的销毁而自动销毁,需要通过 beforeDestory 手动销毁。
- 通过介质传递,同一个子元素或者同一个父元素
- 通过 EventBus 实现组件之间数据传递
第一步:在utils文件夹下创建一个 EventBus.js文件,创建 EventBus并且挂载到全局上:
import Vue from 'vue'
const EventBus = new Vue();
//defineProperties在vue中是个非常重要的知识点
//双向数据绑定的原理就在这个方法上
Object.defineProperties(Vue.prototype,{
$bus:{
get:function(){
return EventBus
}
}
})
第二步:主入口文件 main.js 引入
import './utils/EvenBus.js'
第三步:A组件通过 this.$bus.$emit 发送
<button @click="sendData">发送数据</button>
data(){
return{
msg:"我是AComponent数据"
}
},
methods:{
sendData(){
// EventBus.$emit("getData",this.msg)
this.$bus.$emit("getData",this.msg)
}
}
第四步:B组件通过 $on 来接收,并且一定记得销毁
<div>
BC接收AC传递过来的数据:{{ BCdata }}
</div>
data(){
return{
BCdata:""
}
},
mounted(){
// EventBus.$on("getData",res=>{
// this.BCdata = res;
// })
this.$bus.$on("getData",res=>{
this.BCdata = res;
})
},
beforeDestory(){
this.$bus.$off('msg',{ }) //一定要记得销毁,否则会出现bug
}
插槽
Vue 实现了一套内容分发的 API,将 元素作为承载分发内容的出口。插槽内可以包含任何模板代码,包括 HTML,甚至其它的组件。将父组件的内容放到子组件指定的位置叫做内容分发
编译作用域
插槽中使用动态数据时规定,哪里使用哪里定义。也就是:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
后备内容
有时为一个插槽设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染。<slot>我是默认值</slot>
具名插槽
有时我们需要多个插槽,对于这样的情况, 元素有一个特殊的 元素:name。这个元素可以用来定义额外的插槽,一个不带 name 的 出口会带有隐含的名字“default”。在一个 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称,v-slot 可以缩写为 #
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
<slot name="header"></slot>
<slot name="footer"></slot>
现在 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 中的内容都会被视为默认插槽的内容。【注意】v-slot 只能添加在 上。
作用域插槽
让父级插槽内容能够访问子组件中的数据。为了让data(数据)在父级的插槽内容中可用,我们可以将data作为 元素的一个属性绑定上去 ,绑定在 元素上的属性被称为插槽 prop。
现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:
<template v-slot:strdata="data">
{{ data.strdata }}
</template>
我们选择将包含所有插槽 prop 的对象命名为data,可以随便定义。
动态组件
可以在一个多标签的界面中使用 is 属性来切换不同的组件
例:
<component :is="isComponent"></component>
<button @click="Acomponent">AComponent组件</button>
<button @click="Bcomponent">BComponent组件</button>
data(){
return{
isComponent:AComponent
}
},
methods:{
Acomponent(){
this.isComponent = AComponent
},
Bcomponent(){
this.isComponent = BComponent
}
}
当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。为了解决这个问题,我们可以用一个 元素将其动态组件包裹起来。
<keep-alive>
<component :is="isComponent"></component>
</keep-alive>
异步组件
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
处理边境情况
这些功能都是有劣势或危险的场景的。
- 访问根实例
在每个 new Vue 实例的子组件中,其根实例可以通过 $root 进行访问
new Vue({
data:{
foo : 1
},
methods:{
baz:function...
}
})
// 获取根组件的数据 this.$root.foo
// 写入根组件的数据this.$root.foo = 2
// 调用根组件的方法this.$root.baz()
-
访问父级组件实例
$parent
也可以用来从一个子组件访问父组件的实例。在绝大多数情况下,触达父级组件会使得你的应用更难调试和理解,尤其是当你变更了父级组件的数据的时候。所以一般不建议使用。
语法 :($parent.msg) -
访问子组件实例或子元素
尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。可以通过 ref 这个属性为子组件赋予一个 ID 引用,然后在 mounted(生命周期函数)中用this.$refs.xx
获取。【注意】$refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 $refs。
<base-input ref="usernameInput"></base-input>
this.$refs.usernameInput
Vue实例
-
创建一个vue实例
每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的,Vue 的设计也受到了MVVM的启发。 -
数据与方法
当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。当这些数据改变时,视图会进行重渲染。【注:只有当实例被创建时就已经存在于 data 中的 property 才是响应式的。】如果知道会在晚些时候需要一个 property,但是一开始它为空或不存在,那么你仅需要设置一些初始值。
例如:data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
}
//这里唯一的例外是使用 Object.freeze(),这会阻止修改现有的 property,
//也意味着响应系统无法再追踪变化。
实例生命周期钩子
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
beforeCreate--------组件创建之前 //初始化操作
created------------组件创建之后 //网络请求 额外的组件操作
beforeMount------------组件渲染之前 //判断业务需求 是否需要渲染
mounted-----------组件渲染之后 //网络请求 额外的组件操作
beforeUpdate------------组件更新之前 //数据更新前需要额外处理
updated----------组件更新之后 //数据对比,或者数据更新的提示
beforeDestroy-----------组件销毁之前//组件中持续执行的状态需要在这里毁,
//例如:定时器,事件
destroy-----------组件销毁之后 //一般不做操作
过渡的类名
在进入/离开的过渡中,会有6个class切换
v-enter v-enter-active v-enter-to
v-leave v-leave-active v-leave-to
自定义指令
- 注册一个全局自定义指令----在main.js文件中
Vue.directive('focus',{
inserted(el){
el.focus()
}
})
在任意子组件中都可使用:<input type="text" v-focus>
自动聚焦功能
- 局部自定义指令
directives:{ //和data属性同级
focus:{ //自动聚焦
inserted(el){
el.focus()
}
},
red:{
inserted(el){
el.style.color = "red"; //将内容设置为红色
}
}
}
在当前组件中使用:<div v-red>哈哈哈哈哈</div>
钩子函数
bind : 只调用一次,指令第一次绑定带元素时调用,在这里可以进行一次性的初始化设置。
inserted : 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update : 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
- 钩子函数参数
指令钩子函数会被传入以下参数:
-el:指令所绑定的元素,可以用来直接操作 DOM。
-binding:一个对象,包含以下元素:
name:指令名,不包括 v- 前缀。
value:指令的绑定值。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。
arg:传给指令的参数,可选。
modifiers:一个包含修饰符的对象。
-vnode:Vue 编译生成的虚拟节点。
-oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
- 动态指令参数
<div v-pin:[directive]="100">hakshajsjasajjoak</div> //100这里是个对象
data(){
return{
directive : 'right'
}}
Vue.directive('pin',{
inserted(el,binding){
el.style.position = 'fixed';
el.style[binding.arg] = binding.value + 'px'
}
})
directive 参数可以根据组件实例数据进行更新。
渲染函数 & JSX语法
vue中的 <template></template>
块是可以使用JSX语法的 render()函数来替换的(react中使用的就是JSX语法,render函数渲染)
例如:
data(){
return{
msg : '尿素奥扫婆萨普就撒娇'
}
},
render(){
return(
<div>你好我是JSX语法----{ this.msg }</div>
)
}
过滤器
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式,过滤器应该被添加在 JavaScript 表达式的尾部,由管道符号 “ |”指示。当全局过滤器和局部过滤器重名时,会采用局部过滤器。过滤器可以串联。过滤器是 JavaScript 函数,因此可以接收参数
- 定义全局过滤器
Vue.filter('author',function(value){
if(!value)return;
return value+'-----理想生活过滤'
})
<div>{{str | author}}</div>
- 在子组件定义局部过滤器
filters:{
sum(value,num2,num1){
return num2 + value + num1
},
}
<div>{{100 | sum(100,200)}}</div>
Vue插件
- 安装
- 全局引入
- 在组件中配置
【注意】在js中引入资源需要使用 require("…/xxx")
例如:swiper
Vue插件----->资源列表/Awesome Vue-->跳转到github
安装 :vue-awesome-swiper@3.1.3(swiper插件)
swiper版本 : "^5.2.0",
全局引入:
import VueAwesomeSwiper from 'vue-awesome-swiper';
import 'swiper/css/swiper.css' //有时候会报错,找node_modules文件夹
Vue.use( VueAwesomeSwiper )
在组件中配置:
<swiper :options="swiperOption">
<swiper-slide class="swiper-slide" v-for="(item,index) in carouselArr" :key="index">
<img :src="item"/>
</swiper-slide>
<!-- 分页器 -->
<div class="swiper-pagination" slot="pagination"></div>
<!-- 左右箭头 -->
<div class="swiper-button-prev" slot="button-prev"></div>
<div class="swiper-button-next" slot="button-next"></div>
</swiper>
<script>
export default {
data(){
return {
swiperOption:{
//显示分页
pagination: {
el: '.swiper-pagination'
},
//设置点击箭头
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
},
//自动轮播
autoplay: {
delay: 2000,
//当用户滑动图片后继续自动轮播
disableOnInteraction: false,
},
//开启循环模式
loop: true
},
carouselArr : [1,2,3]
}
}
}
</script>