摘要:添加事件侦听器时使用模式。只当事件是从侦听器绑定的元素本身触发时才触发回调。差别在哪里将特性名转换为从开始支持语法糖,会扩展成一个更新父组件绑定值的侦听器。如果需要条件渲染多个元素,可以使用包裹。
1.前言 安装
直接用 引入(本地或者cdn)
npm npm install vue
vue-cli官方脚手架
# 全局安装 vue-cli $ npm install --global vue-cli # 创建一个基于 webpack 模板的新项目 $ vue init webpack my-project # 安装依赖,走你 $ cd my-project $ npm install $ npm run dev简介
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。Vue 的核心库只关注视图层,对应view。
Vue数据驱动,jQuery是结构驱动
原理内部使用Object.defineProperty(最低支持IE9)把所有属性全部转为 getter/setter,为每个组件绑定了watcher 实例对象,并且把属性作为依赖项,当依赖项的setter调用时,watcher将会重新计算,从而更新组件。
[组件render]-<创建>-[getter、setter]-<收集依赖>-[watcher]
[触发setter]-<通知>-[watcher]-<触发>-[组件渲染函数]-<更新>-[组件]
.png)
开发环境vueTools
vscode【Vetur、Vue2 Snippets】
weboack
2.实例 声明式渲染{{ message }}
//js var vm = new Vue({ el: "#app", data: { message: "Hello Vue!" } })数据与方法
当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
// 我们的数据对象 var data = { a: 1 } // 该对象被加入到一个 Vue 实例中 var vm = new Vue({ data: data }) // 他们引用相同的对象! vm.a === data.a // => true // 设置属性也会影响到原始数据 vm.a = 2 data.a // => 2 // ... 反之亦然 data.a = 3 vm.a // => 3
当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时 data 中存在的属性是响应式的。也就是说如果你添加一个新的属性,将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,那么你仅需要设置一些初始值。
var data = { a: 1 } var vm = new Vue({ el: "#example", data: data }) vm.$data === data // => true vm.$el === document.getElementById("example") // => true // $watch 是一个实例方法 vm.$watch("a", function (newValue, oldValue) { // 这个回调将在 `vm.a` 改变后调用 })自身属性和方法
vue实例自身暴露的属性和方法通过前缀$来获取
var data = { a: 1 } var vm = new Vue({ el: "#example", data: data }) vm.$data === data // => true vm.$el === document.getElementById("example") // => true实例生命周期
每个 Vue 实例在被创建之前都要经过一系列的初始化过程(生命周期)。在这个过程中会运行一些叫做生命周期钩子的函数,用户可以在不同阶段添加自己的代码来做一些事情。
beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created:在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount:在挂载开始之前被调用:相关的 render 函数首次被调用。
mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。
beforeUpdate:数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子
beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
activated/deactivated:keep-alive 组件激活/停用时调用,
errorCaptured:当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
注意:
beforeCreate,created外的钩子在服务器端渲染期间不被调用。
不要在选项属性或回调上使用箭头函数,比如
//错误,会导致this不会指向Vue 实例 created: () => console.log(this.a) vm.$watch("a", newValue => this.myMethod())Vue对象的选项
var vm = new Vue({ // 数据 data: "声明需要响应式绑定的数据对象", props: "接收来自父组件的数据", propsData: "创建实例时手动传递props,方便测试props", computed: "计算属性", methods: "定义可以通过vm对象访问的方法", watch: "Vue实例化时会调用$watch()方法遍历watch对象的每个属性", // DOM el: "将页面上已存在的DOM元素作为Vue实例的挂载目标", template: "可以替换挂载元素的字符串模板", render: "渲染函数,字符串模板的替代方案", renderError: "仅用于开发环境,在render()出现错误时,提供另外的渲染输出", // 生命周期钩子 beforeCreate: "发生在Vue实例初始化之后,data observer和event/watcher事件被配置之前", created: "发生在Vue实例初始化以及data observer和event/watcher事件被配置之后", beforeMount: "挂载开始之前被调用,此时render()首次被调用", mounted: "el被新建的vm.$el替换,并挂载到实例上之后调用", beforeUpdate: "数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前", updated: "数据更改导致虚拟DOM重新渲染和打补丁之后被调用", activated: "keep-alive组件激活时调用", deactivated: "keep-alive组件停用时调用", beforeDestroy: "实例销毁之前调用,Vue实例依然可用", destroyed: "Vue实例销毁后调用,事件监听和子实例全部被移除,释放系统资源", // 资源 directives: "包含Vue实例可用指令的哈希表", filters: "包含Vue实例可用过滤器的哈希表", components: "包含Vue实例可用组件的哈希表", // 组合 parent: "指定当前实例的父实例,子实例用this.$parent访问父实例,父实例通过$children数组访问子实例", mixins: "将属性混入Vue实例对象,并在Vue自身实例对象的属性被调用之前得到执行", extends: "用于声明继承另一个组件,从而无需使用Vue.extend,便于扩展单文件组件", provide&inject: "2个属性需要一起使用,用来向所有子组件注入依赖,类似于React的Context", // 其它 name: "允许组件递归调用自身,便于调试时显示更加友好的警告信息", delimiters: "改变模板字符串的风格,默认为{{}}", functional: "让组件无状态(没有data)和无实例(没有this上下文)", model: "允许自定义组件使用v-model时定制prop和event", inheritAttrs: "默认情况下,父作用域的非props属性绑定会应用在子组件的根元素上。当编写嵌套有其它组件或元素的组件时,可以将该属性设置为false关闭这些默认行为", comments: "设为true时会保留并且渲染模板中的HTML注释" });3.模板语法
Vue.js 使用了基于 HTML 的模板语法,必须是合法的 HTML。在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。
插值 文本Message: {{ msg }} 这个将不会改变: {{ msg }}HTML
Using v-html directive:
只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。
特性在插值中可以使用表达式,但只限简单表达式。
{{ message.split("").reverse().join("") }}指令
指令 (Directives) 是带有 v- 前缀的特殊属性。
指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
现在你看到我了
...
指令 | 预期/限制 | 作用 |
---|---|---|
v-text | string | 文本插值 |
v-html | string | html插值 |
v-show | any | 条件显示 |
v-if、v-else、v-else-if | any | 条件渲染 |
v-for | Array/Object/number/string | 列表渲染 |
v-on(@) | Function/Inline Statement/Object | 事件绑定 |
v-bind(:) | any (with argument)/Object (without argument) | 特性绑定 |
v-model | 仅限/ | 双向绑定 |
v-pre | 忽略编译 | |
v-cloak | 避免显示Mustache | |
v-once | 一次性渲染 |
修饰符 (Modifiers) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。
v-on能使用的修饰符:
修饰符 | 作用 |
---|---|
.stop | 调用 event.stopPropagation()。 |
.prevent | 调用 event.preventDefault()。 |
.capture | 添加事件侦听器时使用 capture 模式。 |
.self | 只当事件是从侦听器绑定的元素本身触发时才触发回调。 |
.{keyCode / keyAlias} | 只当事件是从特定键触发时才触发回调。 |
.native | 监听组件根元素的原生事件。 |
.once | 只触发一次回调。 |
.left | (2.2.0) 只当点击鼠标左键时触发。 |
.right | (2.2.0) 只当点击鼠标右键时触发。 |
.middle | (2.2.0) 只当点击鼠标中键时触发。 |
.passive | (2.3.0) 以 { passive: true } 模式添加侦听器 |
v-bind能使用的修饰符:
修饰符 | 作用 |
---|---|
.prop | 被用于绑定 DOM 属性 (property)。(差别在哪里?) |
.camel | (2.1.0+) 将 kebab-case 特性名转换为 camelCase. (从 2.1.0 开始支持) |
.sync | (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。 |
v-model能使用的修饰符:
修饰符 | 作用 |
---|---|
.lazy | 取代 input 监听 change 事件 |
.number | 输入字符串转为数字 |
.trim | 输入首尾空格过滤 |
对于任何复杂逻辑,你都应当使用计算属性,而不应直接放在模板中。
计算属性也是响应式的,但是它会基于它们的依赖进行缓存的,只有当缓存改变,它才会重新求值;否则会直接返回缓存的结果,而不必再次执行函数。
应当优先使用计算属性而不是侦听属性。
Original message: "{{ message }}"
Computed reversed message: "{{ reversedMessage }}"
var vm = new Vue({ el: "#example", data: { message: "Hello" }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split("").reverse().join("") } } })
下面的计算属性不会更新,因为Date.now() 不是响应式依赖。
computed: { now: function () { return Date.now() } }计算属性缓存 vs 方法
Reversed message: "{{ reversedMessage() }}"
// 在组件中 methods: { reversedMessage: function () { return this.message.split("").reverse().join("") } }
方法在每次调用时总会再次执行函数。
setter计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter
computed: { fullName: { // getter get: function () { return this.firstName + " " + this.lastName }, // setter set: function (newValue) { var names = newValue.split(" ") this.firstName = names[0] this.lastName = names[names.length - 1] } } }侦听器
Ask a yes/no question:
{{ answer }}
watch: { // 如果 `question` 发生改变,这个函数就会运行 question: function (newQuestion, oldQuestion) { this.answer = "Waiting for you to stop typing..." this.getAnswer() } }销毁
// const unWatch = app.$watch("text", (newText, oldText) => { // console.log(`${newText} : ${oldText}`) // }) // setTimeout(() => { // unWatch() // }, 2000)5. Class与Style绑定 Class 对象语法
当value为真时,绑定对应的key到class
数组语法data: { classObject: { active: true, "text-danger": false } }
data: { activeClass: "active", errorClass: "text-danger" }
也可以使用三元表达式。
// isActive为真添加activeClass,errorClass始终存在混合
用在组件上
class将被添加到该组件的根元素上面。该元素上已经存在的class不会被覆盖。
注意:和普通的class并存,并不会覆盖(不同名),最终会合成一个class。
Style自动侦测并添加相应浏览器引擎前缀。
对象语法CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名。
data: { activeColor: "red", fontSize: 30 } data: { styleObject: { color: "red", fontSize: "13px" } }数组语法
可以将多个样式对象应用到同一个元素上
多重值
6.条件渲染 v-if(v-else、v-else-if)
根据表达式的值的真假条件渲染元素。
ABCNot A/B/C
如果需要条件渲染多个元素,可以使用包裹。
Title
Paragraph 1
Paragraph 2
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。添加一个具有唯一值的 key 属性可以强制其重新渲染。
v-show根据表达式之真假值,切换元素的 display CSS 属性。
7.列表渲染 数组Hello!
包含变异(改变原数组)和非变异(生成新数组,不改变原数组)两组方式,都将触发更新。
变异方法:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
非变异方法(需用新数组替换原数组):filter()、concat()、slice()
不能检测的变动:
当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
对象Vue 不能检测对象属性的添加或删除。
对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 现在是响应式的 vm.b = 2 // `vm.b` 不是响应式的
可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性
var vm = new Vue({ data: { userProfile: { name: "Anika" } } }) vm.$set(this.userProfile, "age", 27)
多个属性可以使用Object.assign() 或 _.extend()
this.userProfile = Object.assign({}, this.userProfile, { age: 27, favoriteColor: "Vue Green" })delete
对应的删除属性使用vm.$delete(obj,key)
key当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。
建议尽可能在使用 v-for 时为每一项提供一个唯一的 key。
循环组件的时候,key是必须的。
其他
v-for的循环对象也可以是计算属性和带返回值的method 方法。
利用带有 v-for 的 渲染多个元素
v-for和v-if处于同一节点时,v-for 具有比 v-if 更高的优先级
8.事件处理 事件new Vue({ el: "#example-3", methods: { say: function (message) { alert(message) }, say2: function (message,event) { // 现在我们可以访问原生事件对象 if (event) event.preventDefault() alert(message) } } })事件修饰符
修饰符可以串联,代码会以串联的顺序产生。
修饰符 | 作用 |
---|---|
.stop | 调用 event.stopPropagation()。 |
.prevent | 调用 event.preventDefault()。 |
.capture | 添加事件侦听器时使用 capture 模式。 |
.self | 只当事件是从侦听器绑定的元素本身触发时才触发回调。 |
.once | 只触发一次回调。 |
Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符,能够提升移动端的性能,但是要避免和.prevent一起使用。
按键修饰符...
在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符。
全部的按键别名:.enter、.tab、.delete (捕获“删除”和“退格”键)、.esc、.space、.up、.down、.left、.right
自定义按键修饰符别名
// 可以使用 `v-on:keyup.f1` Vue.config.keyCodes.f1 = 112
自动匹配按键修饰符
系统修饰键
.ctrl、.alt、.shift、.meta。
在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。
Do something
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
鼠标按钮修饰符
.left、.right、.middle
仅响应特定的鼠标按钮
可以用 v-model 指令在表单 及 元素上创建双向数据绑定。
v-model仅为v-on:input和v-bind:value的语法糖而已。
注意:v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
文本/多行文本
Message is: {{ message }}
复选框
Checked names: {{ checkedNames }}
new Vue({ el: "#example-3", data: { checkedNames: [] } }) //Checked names: [ "Jack", "John", "Mike" ]
单选按钮
Picked: {{ picked }}
new Vue({ el: "#example-4", data: { picked: "" } }) //Picked: Two
选择框
Selected: {{ selected }}
new Vue({ el: "...", data: { selected: "" } }) //Selected: B
为多选时则返回一个数组Selected: [ "A", "B" ]
值绑定复选框
单选按钮
选择框的选项
修饰符.lazy,默认input事件触发,使用此修饰则改为change事件触发
.number将输入的值转换为数值
.trim过滤掉输入内容的首尾空白字符
10.组件 简介
组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。组件是具有特殊功能的自定义元素。
所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。
注册组件 全局组件局部组件//注意确保在初始化根实例之前注册组件 // 注册 Vue.component("my-component", { template: " A custom component!" })
var Child = { template: "自动注册A custom component!" } new Vue({ // ... components: { //将只在父组件模板中可用 "my-component": Child } })
webpack 的 vue cli3+
import Vue from "vue" import upperFirst from "lodash/upperFirst" import camelCase from "lodash/camelCase" const requireComponent = require.context( // 其组件目录的相对路径 "./components", // 是否查询其子目录 false, // 匹配基础组件文件名的正则表达式 /Base[A-Z]w+.(vue|js)$/ ) requireComponent.keys().forEach(fileName => { // 获取组件配置 const componentConfig = requireComponent(fileName) // 获取组件的 PascalCase 命名 const componentName = upperFirst( camelCase( // 剥去文件名开头的 `"./` 和结尾的扩展名 fileName.replace(/^./(.*).w+$/, "$1") ) ) // 全局注册组件 Vue.component( componentName, // 如果这个组件选项是通过 `export default` 导出的, // 那么就会优先使用 `.default`, // 否则回退到使用模块的根。 componentConfig.default || componentConfig ) })
data必须是带return的函数
如果将组件用于像 以下类型模板无此限制:、JavaScript 内联模板字符串、.vue 组件 可以包含、、、
内只允许有一个根元素
可以有多个
、支持src导入 父组件向子组件传递数据。 如果你想把一个对象的所有属性作为 prop 进行传递,可以使用不带任何参数的 v-bind 为组件的 prop 指定验证规则,会在组件实例创建之前进行校验。如果传入的数据不符合要求,Vue 会发出警告。 type 可以是下面原生构造器:String、Number、Boolean、Function、Object、Array、Symbol 组件可以接收任意传入的特性,这些特性都会被添加到组件的根元素上,且会做合并处理。 子组件向父组件传递数据。 使用 $on(eventName) 监听事件 使用 $emit(eventName) 触发事件 {{ total }} .sync @update的语法糖 等价于 v-model(仅适用于表单输入组件) v-on:input和v-bind:value的语法糖 等价于 简单场景bus.js
注: 还可以使用$ref、$parent、$child进行通信,不过不推荐。 复杂的场景请使用vuex 为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为内容分发。 除非子组件模板包含至少一个 最初在 这是一些初始内容 这是更多的初始内容 这是一些初始内容 这是更多的初始内容 仍然可以有一个匿名插槽,它是默认插槽,作为找不到匹配的内容片段的备用插槽。如果没有默认插槽,这些找不到匹配的内容片段将被抛弃。 主要内容的一个段落。 另一个主要段落。 这里有一些联系信息 主要内容的一个段落。 另一个主要段落。 和普通的插槽对比,能够传递数据。 通过使用保留的 把切换出去的组件保留在内存中,保留其状态或避免重新渲染 组件复用性,松耦合 谨慎使用ref 在大型应用中使用异步加载 PascalCase声明, kebab-case使用 为递归组件添加name 对低开销的静态组件使用 v-once Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。 适用场景:条件渲染 (使用 v-if)、条件展示 (使用 v-show)、动态组件、组件根节点 hello v-enter:定义进入过渡的开始状态。在元素被插入时生效,在下一个帧移除。 v-enter-active:定义过渡的状态。在元素整个过渡过程中作用,在元素被插入时生效,在 transition/animation 完成之后移除。这个类可以被用来定义过渡的过程时间,延迟和曲线函数。 v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入一帧后生效 (与此同时 v-enter 被删除),在 transition/animation 完成之后移除。 v-leave: 定义离开过渡的开始状态。在离开过渡被触发时生效,在下一个帧移除。 v-leave-active:定义过渡的状态。在元素整个过渡过程中作用,在离开过渡被触发后立即生效,在 transition/animation 完成之后移除。这个类可以被用来定义过渡的过程时间,延迟和曲线函数。 v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发一帧后生效 (与此同时 v-leave 被删除),在 transition/animation 完成之后移除。 动画在css中使用animation即可,其他和过渡类似。 我们可以通过以下特性来自定义过渡类名: hello 可以通过 appear 特性设置节点在初始渲染的过渡 当有相同标签名的元素切换时,建议给元素设置key。 in-out:新元素先进行过渡,完成之后当前元素过渡离开。 out-in:当前元素先进行过渡,完成之后新元素过渡进入。 多个组件的过渡使用动态组件 使用 它会以一个真实元素呈现:默认为一个 。你也可以通过 tag 特性更换为其他元素。 内部元素 总是需要 提供唯一的 key 属性值 也可以通过 move-class 属性手动设置 创建可复用过度组件,将 动态过渡,通过动态绑定name实现 混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。当组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。 当组件和混合对象含有同名选项时,这些选项将以恰当的方式混合。比如,同名钩子函数将混合为一个数组,因此都将被调用。另外,混合对象的 钩子将在组件自身钩子 之前 调用 。 值为对象的选项,例如 methods, components 和 directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。
Vue.extend() 也使用同样的策略进行合并。 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。 一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。 指令钩子函数会被传入以下参数:
el:指令所绑定的元素,可以用来直接操作 DOM 。
binding:一个对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。 https://cn.vuejs.org/v2/guide... 数据对象: 过滤器可以用在两个地方:双花括号插值和 v-bind 表达式。 过滤器可以串联,依次执行,前面的输出作为后面一个的输入。 过滤器可以接收参数(管道符前面的值作为第一个参数,括号内的第一个参数为第二个,依次类推) 直接用 引入(本地或者cdn) npm npm install vue
必须要通过 Vue.use() 明确地安装路由功能,且要通过 router 配置参数注入Vue实例,从而让整个应用都有路由功能。 将页面组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们
to: 属性指定目标地址,默认渲染成带有正确链接的 标签,
replace:相当于router.replace() 不会留下 history 记录
append:设置 append 属性后,则在当前(相对)路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b
tag: 属性生成别的标签.。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名。
active-class:链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置。 将激活 class 应用在外层元素: 在这种情况下, 将作为真实的链接(它会获得正确的 href 的),而 "激活时的CSS类名" 则设置到外层的 。 路由视图容器 如果 动态路径参数params
动态路径查询参数query
区别:params定义了就是路由的一部分,就必须要传,否则匹配失败,query可以缺省 当路由参数变化时,组件的生命周期钩子不会再被调用。 watch(监测变化) $route 对象: 使用beforeRouteUpdate 守卫: 同一个路径可以匹配多个路由时,谁先定义的,谁的优先级就最高。 以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。 如果想在父路由渲染内容,可以定义一个空的子路由。 导航到不同的 URL,会向 history 栈添加一个新的记录。 onComplete:在导航成功完成 (在所有的异步钩子被解析之后) 调用 onAbort:在导航终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 调用 和router.push功能一样,唯一区别就是不会向 history 添加新记录 前进或后退nN步,类似 window.history.go(n) /a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样 使用 props 将组件和路由解耦 如果 props 被设置为 true,route.params 将会被设置为组件属性 如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用。 你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。 vue-router 默认 hash 模式。 开启history 模式,将充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面,但需要后端配合。 vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next("/") 或者 next({ path: "/" }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: "home" 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。 beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。可以通过传一个回调给 next来访问组件实例。 导航被触发。 在失活的组件里调用离开守卫。 调用全局的 beforeEach 守卫。 在重用的组件里调用 beforeRouteUpdate 守
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。 转载请注明本文地址:https://www.ucloud.cn/yun/100897.html 摘要:升级的区别与的断层式升级不同,延续了自己的风格。在命名方式和上有一些区别,掌握它们是你升级整个项目的关键。以下内容都是来源于个人项目的一些经验之谈,并非系统性的阐述。总目录前端经验收集器转载自个人建了前端学习群,旨在一起学习前端。
升级的区别
与angular的断层式升级不同,vue延续了自己的风格。在命名方式和API上有一些区别,掌握它们是你升级整个项目的关键。以下内容都是来源于个人... 摘要:菜鸟教程这是一个属性其值是字符串菜鸟教程同上这是一个属性其值是字符串用于定义的函数,可以通过来返回函数值。它们都有前缀,以便与用户定义的属性区分开来。
开篇语
我最近学习了js,取得进步,现在学习vue.js.建议新手学习,请不要用npm的方式(vue-cli,vue脚手架),太复杂了. 请直接下载vue.js文件本地引入,就上手学习吧参照菜鸟教程网站的vue.js教程http://... 摘要:请记住,会告诉浏览器你不想阻止事件的默认行为。而单单释放也不会触发事件。修饰符修饰符允许你控制由精确的系统修饰符组合触发的事件。当一个被销毁时,所有的事件处理器都会自动被删除。
1、监听事件
用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。
Add 1
The button above has been clicked {{ counte... 摘要:复选框当选中时当没有选中时这里的和特性并不会影响输入控件的特性,因为浏览器在提交表单时并不会包含未被选中的复选框。
1、基础用法
v-model指令可以实现表单元素和Model中数据的双向数据绑定。只能运用在表单元素中(input、radio、text、address、email、select、checkbox、textarea)
可以用 v-model 指令在表单 、 及 元素上... 摘要:组件名在注册一个组件的时候,我们始终需要给它一个名字。局部注册全局注册往往是不够理想的。基础组件的自动化全局注册可能你的许多组件只是包裹了一个输入框或按钮之类的元素,是相对通用的。记住全局注册的行为必须在根实例通过创建之前发生。
1、组件名
在注册一个组件的时候,我们始终需要给它一个名字。
Vue.component(my-component-name, { /* ... */ })
... 摘要:父子组件通信父组件通过向下传递数据给子组件,子组件通过给父组件发送消息。是一个对象而不是字符串数组时,它包含验证要求。状态管理由于多个状态分散的跨越在许多组件和交互间,大型应用的复杂度也随之增长。提供了,可以通过文档学习。
什么是vue
vue是一个前端框架,主要两个特点:数据绑定、组件化。
安装环境
根据教程安装环境:node.js、npm、webpack、vue-cli主要的命... 阅读 2435·2023-04-25 21:26 阅读 1479·2021-11-25 09:43 阅读 1888·2019-08-30 15:52 阅读 903·2019-08-30 14:05 阅读 2587·2019-08-29 16:10 阅读 376·2019-08-29 13:48 阅读 1826·2019-08-29 12:47 阅读 1240·2019-08-23 18:04、
、
、 这样的元素里面,为了遵循规范,应该使用is:
Vue.component("child", {
// 声明 props
props: ["message"],
// 就像 data 一样,prop 也可以在模板中使用
// 同样也可以在 vm 实例中通过 this.message 来使用
template: "{{ message }}"
})
动态 Prop:
todo: {
text: "Learn Vue",
isComplete: false
}
字面量语法 vs 动态语法
验证
Vue.component("example", {
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 value > 10
}
}
}
})
Vue.component("button-counter", {
template: "",
data: function () {
return {
counter: 0
}
},
methods: {
incrementCounter: function () {
this.counter += 1
this.$emit("increment")
}
},
})
new Vue({
el: "#counter-event-example",
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
父子双向通信
// 通过 input 事件带出数值
this.$emit("input", Number(formattedValue))
this.$emit("input", Number(formattedValue))
非父子组件通信
var bus = new Vue()
// 触发组件 A 中的事件
bus.$emit("id-selected", 1)
// 在组件 B 创建的钩子中监听事件
bus.$on("id-selected", function (id) {
// ...
})
编译作用域: 父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。
具名插槽
我是子组件的标题
我是父组件的标题
我是父组件的标题
我是子组件的标题
作用域插槽
这里可能是一个页面标题
这里可能是一个页面标题
动态组件
var vm = new Vue({
el: "#example",
data: {
currentView: "home"
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})
keep-alive
注意事项
new Vue({
el: "#demo",
data: {
show: true
}
})
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
过渡的类名
enter-class、enter-active-class、enter-to-class (2.1.8+)、leave-class、leave-active-class、leave-to-class (2.1.8+)
设定持续时间
JavaScript 钩子
// ...
methods: {
// --------
// 进入中
// --------
beforeEnter: function (el) {
// ...
},
// 此回调函数是可选项的设置,done 是必须的
// 与 CSS 结合时使用
enter: function (el, done) {
// ...
done()
},
afterEnter: function (el) {
// ...
},
enterCancelled: function (el) {
// ...
},
// --------
// 离开时
// --------
beforeLeave: function (el) {
// ...
},
// 此回调函数是可选项的设置,done 是必须的
// 与 CSS 结合时使用
leave: function (el, done) {
// ...
done()
},
afterLeave: function (el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// ...
}
}
初始渲染的过渡
多个元素的过渡
多个组件的过渡
列表过渡
12.可复用性和组合
混合
// 定义一个混合对象
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log("hello from mixin!")
}
}
}
// 定义一个使用混合对象的组件
var Component = Vue.extend({
mixins: [myMixin]
})
// 注册一个全局自定义指令 `v-focus`
Vue.directive("focus", {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// 注册一个局部自定义指令
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
//使用
钩子函数
// @returns {VNode}
createElement(
// {String | Object | Function}
// 一个 HTML 标签字符串,组件选项对象,或者
// 解析上述任何一种的一个 async 异步函数,必要参数。
"div",
// {Object}
// 一个包含模板相关属性的数据对象
// 这样,您可以在 template 中使用这些属性。可选参数。
{
// (详情见下面的数据对象)
},
// {String | Array}
// 子节点 (VNodes),由 `createElement()` 构建而成,
// 或使用字符串来生成“文本节点”。可选参数。
[
"先写一些文字",
createElement("h1", "一则头条"),
createElement(MyComponent, {
props: {
someProp: "foobar"
}
})
]
)
{
// 和`v-bind:class`一样的 API
"class": {
foo: true,
bar: false
},
// 和`v-bind:style`一样的 API
style: {
color: "red",
fontSize: "14px"
},
// 正常的 HTML 特性
attrs: {
id: "foo"
},
// 组件 props
props: {
myProp: "bar"
},
// DOM 属性
domProps: {
innerHTML: "baz"
},
// 事件监听器基于 `on`
// 所以不再支持如 `v-on:keyup.enter` 修饰器
// 需要手动匹配 keyCode。
on: {
click: this.clickHandler
},
// 仅对于组件,用于监听原生事件,而不是组件内部使用
// `vm.$emit` 触发的事件。
nativeOn: {
click: this.nativeClickHandler
},
// 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
// 赋值,因为 Vue 已经自动为你进行了同步。
directives: [
{
name: "my-custom-directive",
value: "2",
expression: "1 + 1",
arg: "foo",
modifiers: {
bar: true
}
}
],
// Scoped slots in the form of
// { name: props => VNode | Array
过滤器
{{ message | capitalize }}
//定义局部过滤器
filters: {
capitalize: function (value) {
if (!value) return ""
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
//定义全局过滤器
Vue.filter("capitalize", function (value) {
if (!value) return ""
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
{{ message | filterA | filterB }}
{{ message | filterA("arg1", arg2) }}
13.Vue-Router
安装
动态路由匹配
//定义
routes: [
// 动态路径参数 以冒号开头
{ path: "/user/:id", component: User }
]
//调用
$route.params.id
//定义
routes: [
// 动态路径参数 以冒号开头
{ path: "/user?id=6456456", component: User }
]
//调用
$route.query.id
想对路由参数的变化作出响应的话,有以下两种方式:const User = {
template: "...",
watch: {
"$route" (to, from) {
// 对路由变化作出响应...
}
}
}
const User = {
template: "...",
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don"t forget to call next()
}
}
匹配优先级
因此,404类的页面一定要放在最后,路由是按照声明顺序匹配,如果不是最后则404之后的页面都会跳转到404。const router = new VueRouter({
routes: [
{ path: "/user/:id", component: User,
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的
在 Vue 实例内部,调用 this.$router.push// 字符串
router.push("home")
// 对象
router.push({ path: "home" })
// 命名的路由
router.push({ name: "user", params: { userId: 123 }})
// 带查询参数,变成 /register?plan=private
router.push({ path: "register", query: { plan: "private" }})
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
重定向
const router = new VueRouter({
routes: [
//path
{ path: "/a", redirect: "/b" },
//name
{ path: "/a", redirect: { name: "foo" }},
//方法
{ path: "/a", redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
别名
const router = new VueRouter({
routes: [
{ path: "/a", component: A, alias: "/b" }
]
})
路由组件传参
const User = {
props: ["id"],
template: "
const router = new VueRouter({
routes: [
{ path: "/promotion/from-newsletter", component: Promotion, props: { newsletterPopup: false } }
]
})
const router = new VueRouter({
routes: [
{ path: "/search", component: SearchUser, props: (route) => ({ query: route.query.q }) }
]
})
HTML5 History 模式
const router = new VueRouter({
mode: "history",
routes: [...]
})
导航守卫
//前置守卫:确保要调用 next 方法,否则钩子就不会被 resolved。
router.beforeEach((to, from, next) => {
// ...
})
//后置守卫
router.afterEach((to, from) => {
// ...
})
//解析守卫:在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
router.beforeResolve((to, from) => {
// ...
})
参数说明
//与全局前置守卫的方法参数是一样的
const router = new VueRouter({
routes: [
{
path: "/foo",
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
组件内的守卫
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
解析流程
相关文章
Vue 笔记三:Vue2.0与1.0的区别
(原创)vue 学习笔记
vue2.0学习笔记(事件处理)
vue2.0学习笔记(表单输入绑定)
vue2.0学习笔记(组件注册)
Vue2.0 学习笔记
发表评论
0条评论
pumpkin9
男|高级讲师
TA的文章
阅读更多
tensorflow2.4.1
能让你更早下班的Python垃圾回收机制
css 特殊属性
JavaScript实现 满天星 导航栏
使用H5新标签重构旧项目时的思考
canvas 实现 github404动态效果
用PerformanceTiming来检测页面性能
前端必备基础