四个 Vue.js 的编程小技巧
以下是我从过去一年使用 Vue.js 中学到的一些技巧。
1. 使用组件内的箭头函数
在 ES6 中引入了一种定义函数的新方法。 这种新的方法使得打字的时间更短,速度更快,但其作用范围来自于它如何界定作用域。当使用旧的函数定义方法时,this
关键字的作用范围并不按照我们想要的方式起作用。 例如:
function Person () {
this.age = 0;
setInterval(function growUp () {
// `this.age` 未定义
// 这个函数已经声明了它自己的作用域
// 与 Person 范围不同
this.age += 1;
}, 1000)
}
growUp
函数已经定义了自己的作用域,因此 this
不需要引用 Person 对象。 你可以通过将 Object 实例存储在变量中或将函数作用域绑定到父容器来获得所需的行为。
// 存储 `this` 作用域
// 一个变量重用
function Person () {
var that = this;
that.age = 0;
setInterval(function growUp () {
that.age += 1;
}, 1000)
}
// 绑定函数的 `this`
function Person () {
this.age = 0;
setInterval(function growUp () {
this.age += 1;
}.bind(this), 1000)
}
或者,我们可以使用箭头函数。 由于它自动将其作用域绑定到父级,因此不需要额外的 “修复”。
function Person () {
this.age = 0;
setInterval(() => {
this.age += 1;
}, 1000)
}
更简洁和直接!?
2. 使用单文件组件
单文件组件 是我最喜欢的 Vue.js 功能之一。 它允许我们定义可重用模板并将应用程序的各个部分分成可管理的部分。 构建工具需要使用单文件组件。
有多种方法来定义Vue组件。
例如:
Vue.component('my-counter', {
data () {
return {
count: 0
}
},
methods: {
add () {
this.count += 1;
}
},
template: `<div>
<div>{{ count }}</div>
<button @click="add()">Increment</button>
</div>`
}
});
现在与单文件组件相同的组件:
<template lang="html">
<div>
<div>{{ count }}</div>
<button @click="add()">Increment</button>
</div>
</template>
<script>
export default {
data () {
return {
count: 0
}
},
methods: {
add () {
this.count += 1;
}
}
}
</script>
小组件的好处可能不会那么明显,但即便如此,我们也可以获得模板结构的语法高亮显示,并且更容易进行可视化扫描并找到我们正在寻找的内容。
3. 全局插件
使用更大的应用程序时,我们可能会重用相似的方法、计算属性甚至是整个组件。我们可以定义一次并作为全局插件来安装,而不是在每个组件中重写方法或者是引入整个组件。
我们可以在同一个组件中引入所需要的组件和方法:
<template lang="html">
<div>
<user-container v-for="u in users">
<p>{{ sayHello(u.name) }}</p>
</user-container>
</div>
</template>
<script>
import UserContainer from './UserContainer'
export default {
components: {
UserContainer,
},
methods: {
sayHello (name) {
return `Hello ${name}!`
}
},
computed: {
users () {
return this.$store.getters['users']()
}
}
}
</script>
我们还可以创建一个插件并安装它:
import UserContainer from './UserContainer'
const Plugin = {
install (Vue, options) {
// <g-user-container> component will be globally available
Vue.component('GUserContainer', UserContainer)
Vue.mixin({
computed: {
// `users` 是全局可用的
users () {
return this.$store.getters.users
},
}
})
// $sayHello 方法在组件中可用
Vue.prototype.$sayHello = function (name) {
return `Hello ${name}!`
}
}
}
// 使用的话也很简单
import Vue from 'vue'
Vue.use(Plugin)
new Vue({
//...
})
当我们多次进行复制粘贴时这绝对是一个不错的选择。可以了解一下 DRY ?
4. 使用 Vuex 管理状态
现代 Web 应用程序需要管理和更新大量的数据集。我见过很多方法都是只管理组件内的所有数据,在不需要跨组件共享状态时,这个方法没有任何问题。
将数据通过 prop
传递给组件并使用 Event Bus 更新数据是很诱人的,但是采用这种方法容易让项目变得臃肿并难以维护。
Vuex 在我们需要使用多个共享状态组件时变得十分突出。Vuex 可以存储整个状态并让所有组件都可以访问它,这样就不必将所有数据通过 props
传递给子组件了。
通过 Vuex 我们可以定义 state,getters,actions 和 mutations,这足以让我们做很多事情。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
movies: [],
actors: []
},
getters: {
movies: state => {
return state.movies
},
actors: state => {
return state.actors
}
},
actions: {
getMovies (context) {
axios.get('/api/movies')
.then((movies) => {
context.commit('setMovies', movies)
})
},
getActors (context) {
axios.get('/api/actors')
.then((actors) => {
context.commit('setActors', actors)
})
}
},
mutations: {
setMovies (state, movies) {
state.movies = movies
},
setActors (state, actors) {
state.actors = actors
}
}
})
new Vue({
el: '#app',
store,
render: h => h(App)
})
在组件中使用 Vuex:
<template lang="html">
<div>
<div v-for="m in movies">
<p>{{ m.name }}</p>
<p>{{ m.description }}</p>
</div>
<div v-for="a in actors">
<p>{{ a.firstName }} {{ a.lastName }}</p>
</div>
</div>
</template>
<script>
export default {
mounted () {
this.$store.dispatch('getMovies')
this.$store.dispatch('getActors')
},
computed: {
movies () {
this.$store.getters.movies
},
actors () {
this.$store.getters.actors
}
}
}
</script>
我们还可以定义其它 actions 和 mutations 去持续更新数据。另外,它保持了 Vue.js 的响应式。
总结
当你学习并实践了,你会发现 Vue.js 可以带来很多乐趣。
我目前在工作中很喜欢使用 Vue.js ,这并不是经常性的。 ?
可以在 Medium 和 Twitter 关注我,我会分享更多写作技巧和一些想法。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: