前言
上家公司的项目主要是使用jQuery和Angular1,然后自己学了React,没想到来到这家公司突然开始做vue,不过vue还是挺容易上手的。下面是vue技术栈的一些总结,都是来自官网,主要是自己对vue技术栈知识点的一些整理,因此此文很水,建议阅读我的上一篇文章Vuejs技术栈从CLI到打包上线实战全解析
Vue
独立构建和运行时构建
有两种构建方式,独立构建和运行构建。它们的区别在于前者包含模板编译器而后者不包含。
模板编译器的职责是将模板字符串编译为纯JavaScript的渲染函数。如果你想要在组件中使用template选项,你就需要编译器。
生命周期
具体查看官网的流程图,要注意的是created和mounted区别,created是vm实例已创建但未挂载,因此一些DOM操作应该放在mounted中。异步请求放在created或者mounted暂时没发现什么区别,如您知道有什么区别,请评论指出。
计算(computed)属性
模板内的表达式不应该包含太多的逻辑,对于任何复杂逻辑,都应当使用计算属性
computed属性和methods不同的是计算属性是基于它们的依赖进行缓存的。
computed属性和computed属性,通常更好的想法是使用computed属性而不是命令式的watch回调。虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的watcher。当你想要在数据变化响应时,执行异步操作或开销较大的操作,这是很有用的。
数组更新检测
数组的变异方法(mutation method,会改变被这些方法调用的原始数组)会触发视图更新,有以下七个:
push() pop() shift() unshift() splice() sort() reverse()
当使用非变异方法时,可以用新数组替换旧数组,或者使用Vue.set方法。
对象更新
可以用新对象替换旧对象,或者使用Vue.set方法
Vue.set(vm.someObject, 'foo', 'bar') this.someObject = Object.assign({}, this.someObject, { a:1, b:2 })
事件处理器
Vue.js为v-on提供了事件修饰符和按键修饰符
表单控件绑定
可以用v-model指令在表单控件元素上创建双向数据绑定。常见修饰符有.lazy、.number、.trim。
也可以使用自定义事件的表单输入组件。
组件
Vue组件的API来自三部分:props,events和slots:
Props允许外部环境传递数据给组件
Events允许组件触发外部环境的副作用
Slots允许外部环境将额外的内容组合在组件中。
1)组件的data属性必须是函数
2)父子组件
在Vue.js中,父子组件的关系可以总结为 props down, events up 。父组件通过props向下传递数据给子组件,子组件通过events给父组件发送消息。
prop是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
另外,每次父组件更新时,子组件的所有prop都会更新为最新值。这意味着你不应该在子组件内部改变prop。如果你这么做了,Vue会在控制台给出警告。
为什么我们会有修改prop中数据的冲动呢?通常是这两种原因:
1.prop作为初始值传入后,子组件想把它当作局部数据来用;
2.prop作为初始值传入,由子组件处理成其它数据输出。
对这两种原因,正确的应对方式是:
1.定义一个局部变量,并用prop的值初始化它:
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
2.定义一个计算属性,处理prop的值并返回。
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
注意在JavaScript中对象和数组是引用类型,指向同一个内存空间,如果prop是一个对象或数组,在子组件内部改变它会影响父组件的状态。
3)非父子组件
有时候两个组件也需要通信(非父子关系)。在简单的场景下,可以使用一个空的Vue实例作为中央事件总线。在复杂的情况下,我们应该考虑使用专门的状态管理模式。
4).sync修饰符
在一些情况下,我们可能会需要对一个prop进行『双向绑定』。
2.0中移除了.sync,Vue2.3.0+又将其添加回来了,但是这次它只是作为一个编译时的语法糖存在,它会被扩展为一个自动更新父组件属性的v-on侦听器。如下代码
<comp :foo.sync="bar"></comp>
会被扩展为:
<comp :foo="bar" @update:foo="val => bar = val"></comp>
当子组件需要更新foo的值时,它需要显式地触发一个更新事件:
this.$emit('update:foo', newValue)
5)使用slot进行内容分发
作用域插槽:接收从子组件中传递的prop对象。作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表每一项
6)动态组件、is特性和keep-alive指令
7)子组件索引
尽管有props和events,但是有时仍然需要JavaScript中直接访问子组件。为此可以使用ref为子组件指定一个索引ID。
异步更新队列
虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。
过渡效果
Vue在插入、更新或者移除DOM时,提供多种不同方式的应用过渡效果。包括以下工具:
在CSS过渡和动画中自动应用class
可以配合使用第三方CSS动画库,如Animate.css
在过渡钩子函数中使用JavaScript直接操作DOM
可以配合使用第三方JavaScript动画库,如Velocity.js
1)单元素/组件的过渡
Vue提供了transition的封装组件,在下列情形中,可以给任何元素和组件添加过渡
条件渲染(使用v-if)
条件展示(使用v-show)
动态组件
组件根节点
2)多个元素的过渡
对于原生标签可以使用 v-if/v-else
3)多个组件的过渡
多个组件的过渡我们可以使用动态组件。
4)列表过渡
Render函数和JSX
自定义指令
和Angular的指令类似,主要操作DOM,下面是一个滚动加载的指令,holder暂时没想到什么更好的处理方法:
let scrollCallback = function (callback) { let windowH = window.innerHeight let getDocumentHeight = function () { var body = document.body var html = document.documentElement return Math.max( body.offsetHeight, body.scrollHeight, html.clientHeight, html.offsetHeight, html.scrollHeight ) } let scrollH = document.documentElement.scrollTop || document.body.scrollTop if (windowH + scrollH >= getDocumentHeight() - (this.holder || 20)) { callback() } } let callBackWarpped export default { bind (el, binding, vnode) { let holder if (vnode.data && vnode.data.attrs && vnode.data.attrs['scroll-placeholder']) { holder = parseInt(vnode.data.attrs['scroll-placeholder']) } else { holder = 20 } callBackWarpped = scrollCallback.bind({el, holder}, binding.value) window.addEventListener('scroll', callBackWarpped, false) }, unbind: function () { window.removeEventListener('scroll', callBackWarpped, false) } }
混合
混合是一种灵活的分布式复用Vue组件的方式。混合对象可以包含任意组件选项。以组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。
插件
1)创建插件
Vue.js的插件应当有一个公开方法install。这个方法的第一个参数是Vue构造器 , 第二个参数是一个可选的选项对象。
2)使用插件
通过全局方法Vue.use()使用插件:
// 调用 `MyPlugin.install(Vue)` Vue.use(MyPlugin)
也可以传入一个选项对象:
Vue.use(MyPlugin, { someOption: true })
vue-router
两种导航方式
1)router-link声明式导航
<router-link to="/foo">Go to Foo</router-link>
router-link对应的路由匹配成功,将自动设置class属性值.router-link-active。
2)编程式导航
// 字符串 router.push('home') // 对象 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: 123 }}) // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})
重命名(redirect)和别名(alias)
两种路由模式
vue-router默认hash模式,也可以设置为路由的history模式。
导航钩子
vue-router提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式可以在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的。
路由meta
一个路由匹配到的所有路由记录会暴露为$route对象(还有在导航钩子中的route对象)的$route.matched数组。因此,我们需要遍历$route.matched来检查路由记录中的meta字段。
过渡动效
router-view是基本的动态组件,所以我们可以用transition组件给它添加一些过渡效果。
数据获取
有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:
导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示『加载中』之类的指示。
导航完成之前获取:导航完成前,在路由的enter钩子中获取数据,在数据获取成功后执行导航。
滚动行为(scrollBehavior)
注意: 这个功能只在HTML5 history模式下可用。
路由懒加载
当打包构建应用时,Javascript包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
结合Vue的异步组件和Webpack的code splitting功能,轻松实现路由组件的懒加载。
const Foo = resolve => require(['./Foo.vue'], resolve) const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ] })
router-link
可以设置tag、append、active-class、exact等属性
有时候我们要让 "激活时的CSS类名" 应用在外层元素,而不是a标签本身,那么可以用router-link渲染外层元素,包裹着内层的原生a标签:
<router-link tag="li" to="/foo"> <a>/foo</a> </router-link>
在这种情况下,a将作为真实的链接(它会获得正确的 href 的),而"激活时的CSS类名"则设置到外层的li。
Router构造配置
routes、mode、base、linkActiveClass、scrollBehavior
对组件注入
1)注入的属性
通过在Vue根实例的router配置传入router实例,下面两个属性成员会被注入到每个子组件。
$router:router实例
$route:当前激活的路由信息对象。这个属性是只读的,里面的属性是immutable(不可变)的,不过你可以watch(监测变化)它。
2)允许的额外配置:beforeRouteEnter、beforeRouteLeave
vuex
state
1)单一状态树
Vuex使用单一状态树--是的,用一个对象就包含了全部的应用层级状态。至此它便作为一个『唯一数据源(SSOT)』而存在。这也意味着,每个应用将仅仅包含一个store实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
2)在Vue组件中获得Vuex状态
最好在根实例中注册store选项,该store实例会注入到根组件下的所有子组件中,且子组件能通过this.$store访问到。而不是在每个需要使用state的组件中需要频繁地导入。
3)mapState辅助函数
当一个组件需要获取多个状态时候,可以使用mapState辅助函数帮助我们生成计算属性,这样可以简化代码书写。mapState函数会返回一个对象,然后可以使用对象展开运算符将它与局部计算属性混合使用。
4)不要滥用vuex
使用Vuex并不意味着你需要将所有的状态放入Vuex。虽然将所有的状态放到Vuex会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。
getters
getters用来从store中的state中派生出一些状态,例如对列表进行过滤并计数:
computed: { doneTodosCount () { return this.$store.state.todos.filter(todo => todo.done).length } }
getters可以认为是store的计算属性。和state类似,有mapGetters辅助函数。
mutations
更改Vuex的store中的状态的唯一方法是提交mutation。Vuex中的mutations非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受state作为第一个参数
1)提交载荷(Payload)
你可以向store.commit传入额外的参数,即mutation的载荷(payload):
// ... mutations: { increment (state, n) { state.count += n } } store.commit('increment', 10)
2)Mutations需遵守Vue的响应规则
3)使用常量替代Mutation事件类型
4)mutation必须是同步函数
5)在组件中提交Mutations
你可以在组件中使用this.$store.commit('xxx')提交mutation,或者使用mapMutations辅助函数将组件中的methods映射为store.commit调用(需要在根节点注入store)。
actions
actions类似于mutation,不同在于:
actions提交的是mutation,而不是直接变更状态。
actions可以包含任意异步操作。
1)在组件中分发Action
你在组件中使用this.$store.dispatch('xxx')分发action,或者使用mapActions辅助函数将组件的methods映射为store.dispatch调用(需要先在根节点注入store)
2)组合Actions
Action通常是异步的,那么如何知道action什么时候结束呢?更重要的是,我们如何才能组合多个action,以处理更加复杂的异步流程?
首先,你需要明白store.dispatch可以处理被触发的action的回调函数返回的Promise,并且store.dispatch仍旧返回Promise。
使用async/await会更加简单:
// 假设 getData() 和 getOtherData() 返回的是 Promise actions: { async actionA ({ commit }) { commit('gotData', await getData()) }, async actionB ({ dispatch, commit }) { await dispatch('actionA') // 等待 actionA 完成 commit('gotOtherData', await getOtherData()) } }
Modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变得相当臃肿。
为了解决以上问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态
插件
Vuex的store接受plugins选项,这个选项暴露出每次mutation的钩子。Vuex插件就是一个函数,它接收store作为唯一参数。
严格模式
开启严格模式,仅需在创建store的时候传入strict:true
在严格模式下,无论何时发生了状态变更且不是由mutation函数引起的,将会抛出错误。这能保证所有的状态变更都能被调试工具跟踪到。
不要在发布环境下启用严格模式!严格模式会深度监测状态树来检测不合规的状态变更--请确保在发布环境下关闭严格模式,以避免性能损失。
表单处理
测试
热重载
以上是关于Vuejs技术栈的知识汇总的详细内容。更多信息请关注PHP中文网其他相关文章!

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

Python和JavaScript在性能和效率方面的差异主要体现在:1)Python作为解释型语言,运行速度较慢,但开发效率高,适合快速原型开发;2)JavaScript在浏览器中受限于单线程,但在Node.js中可利用多线程和异步I/O提升性能,两者在实际项目中各有优势。

JavaScript起源于1995年,由布兰登·艾克创造,实现语言为C语言。1.C语言为JavaScript提供了高性能和系统级编程能力。2.JavaScript的内存管理和性能优化依赖于C语言。3.C语言的跨平台特性帮助JavaScript在不同操作系统上高效运行。

JavaScript在浏览器和Node.js环境中运行,依赖JavaScript引擎解析和执行代码。1)解析阶段生成抽象语法树(AST);2)编译阶段将AST转换为字节码或机器码;3)执行阶段执行编译后的代码。

Python和JavaScript的未来趋势包括:1.Python将巩固在科学计算和AI领域的地位,2.JavaScript将推动Web技术发展,3.跨平台开发将成为热门,4.性能优化将是重点。两者都将继续在各自领域扩展应用场景,并在性能上有更多突破。

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。

是的,JavaScript的引擎核心是用C语言编写的。1)C语言提供了高效性能和底层控制,适合JavaScript引擎的开发。2)以V8引擎为例,其核心用C 编写,结合了C的效率和面向对象特性。3)JavaScript引擎的工作原理包括解析、编译和执行,C语言在这些过程中发挥关键作用。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

Dreamweaver CS6
视觉化网页开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。