记录一下一些简单但是有用的关于vue和node的知识点和问题
vue-cli构建项目
安装vue-cli
1
npm install -g vue-cli
使用vue-cli初始化项目
1
vue init webpack [project-name] //项目名
vue-cli 3.0版本增加了一个新命令来初始化项目,依赖node>=8.91
vue create [project-name]
安装依赖模块
1
2cd [project-name]
npm install开始运行
1
npm run dev
npm run命令
在执行npm run xxx时,实际执行的是配置在package.json
中的脚本1
2
3
4
5"scripts": {
"dev": "node build/dev-server.js",
"server": "node build/server.js",
"build": "node build/build.js"
}
比如npm run dev
执行时运行的是dev-server.js
npm执行多个命令
对于一般的命令,可以使用&&
连接来顺序执行1
'start' : 'npm run dev && npm run server'
但是如果两条命令都是监听命令,第一个执行完之后便会停止,这时候可以使用concurrently
模块
首先需要安装npm install -g concurrently
1
"start":"concurrently \"npm run server\" \"npm run dev\""
更改调试地址端口号
在执行npm run dev
后,会在localhost以测试环境运行项目,上文提到实际执行的是dev-server.js
,查看之后发现以下代码1
2
3
4
5var config = require('../config')
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
var uri = 'http://localhost:' + port
可见地址端口号即port的值,取的是环境变量的PORT或者config中定义的port值,找到../config/index.js
,在module.exports的对象中的dev属性中,找到port的值,更改即可1
2
3
4
5
6
7dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
……
cssSourceMap: false
}
dependencies和devDependencies
dependences 是项目正常运行所需要的依赖,即生产环境,而devDependencies则是开发者开发时整个项目所需的依赖(如会有一些测试依赖之类的),及开发环境。1
npm install
会默认安装两种依赖。
如果只想要安装devDependencies,则运行:1
npm install name --save
如果只想要安装devDependencies,则运行:1
npm install name --save-dev
native原生事件
现在在组件上使用v-on只会监听自定义事件 (组件提供的事件)。如果要监听根元素的原生事件,可以使用 .native 修饰符,比如给router-link绑定点击事件,element-ui组件绑定原生事件,如下:1
2
3
4
5<router-link :to="path" @click.native="click">
<el-input type="textarea" :rows="3"
@keydown.enter.native="keydown">
</el-input>
动态组件
通过使用保留的<component>
元素,动态地绑定到它的is特性,我们让多个组件可以使用同一个挂载点,并动态切换:1
2
3
4
5
6
7
8
9
10
11
12<component v-bind:is="currentView">
<!-- 组件在 vm.currentview 变化时改变! -->
</component>
data: {
currentView: 'home'
},
components: {
home,
posts,
archive
}
可以通过切换绑定的属性,即currentView来切换不同的组件,或者动态的加载组件,currentView为null时组件会被销毁。
如果想把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数。
keep-alive
1 | <keep-alive> |
修改bol值切换组件加载时,这里的组件会被缓存起来,内容不会因为组件的切换而消失。
此外,还有include
和exclude
属性:1
2
3
4<keep-alive include="coma" exclude="comb">
<coma v-if="bol"></coma>
<comb v-else></comb>
</keep-alive>
将会缓存组件coma,不会缓存comb。
watch数组/对象
vue中使用watch可以监听数据的变化,但是对于数组或者对象内部的变化,直接watch是监听不到的,需要使用deep
深度监听1
2
3
4
5
6
7
8watch:{
data: {
handler : function(newVal){
//do something
},
deep : true
}
},
监听路由变化
$route 作为vue实例的一个响应式属性,是和data中定义的属性本质上是一样的,都可以通过this的方式拿到。既然可以使用watch监听data中的属性变化,同样也可以监听 $route 的变化。watch中监听的对象默认回调函数中的参数值就是newVal,oldVal,监听$route时的to,form
也是这样。1
2
3
4
5watch:{
'$route'(to, from){
//...
}
}
使用sass
安装依赖1
2
3npm install --save-dev sass-loader
//sass-loader依赖于node-sass
npm install --save-dev node-sass
修改配置项,找到build文件夹下的webpack.base.config.js
,修改其中的module.rules1
2
3
4
5
6
7
8
9module: {
rules: [
……
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}
]
}
在需要使用scss的地方,添加lang="scss"
1
<style lang='scss'></style>
dirname与filename
node.js中,在任何模块文件内部,可是使用__filename
变量获取当前模板文件的带有完整绝对路径的文件名,使用__dirname
可以获得当前文件所在目录的完整目录名。
举个栗子,在test录下的test.js中1
2console.log(__dirname);
console.log(__filename);
之后执行node test.js
1
2D:\test\test.js //__dirname
D:\test //__filename
mixins
mixins
选项接受一个混入对象的数组。这些混入实例对象可以像正常的实例对象一样包含选项,他们将在 Vue.extend()
里最终选择使用相同的选项合并逻辑合并。
这是官网对mixins的介绍,简单来讲,就是将对象合并进vue实例中,实现数据和方法的通用,举个栗子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// mixin.js
export default {
methods: {
sayHello () {
console.log(this.msg)
}
}
}
// vue
import mixin from './mixin'
export default {
data () {
return {
msg: 'Hello World'
}
},
mounted () {
this.sayHello(); // 'Hello World'
}
}
简单粗暴,通常用于通用逻辑的封装,相比引入函数方法,mixins
对数据和方法的调用更加方便。1
2
3
4
5
6
7Vue.mixin({
methods: {
sayHello () {
console.log(this.msg);
}
}
});
mixin
也支持全局混合方法,不需要在导入,可以所有vue文件中直接使用。
变量声明出错
1 | <div>{{ _msg }}</div> |
1 | data () { |
上面的代码在运行时会报错:1
[Vue warn]: Property or method "_msg" is not defined on the instance but referenced during render
万万没想到这种基本操作也会出错,于是几经波折后找到了这句话
以
_
或$
开头的属性或者方法不会被Vue实例代理,因为它们可能和 Vue 内置的属性、API 方法冲突。你可以使用例如vm.$data._property
的方式访问这些属性
以上面的代码为例,如果非要使用下划线,可以通过this.$data._msg
来获得属性值。
Vue.set
在Vue文档中有这样一段话。
Vue 不能检测到对象属性的添加或删除。
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
- 当你利用索引直接设置一个项时,例如:vm.arr[index] = newValue
- 当你修改数组的长度时,例如:vm.arr.length = newLength
1
<div>{{ user.age }}</div>
1 | data () { |
以上代码为user对象新增了age属性,但是会发现并没有触发dom的更新,页面显示的age依旧为空,这时候来看一下打印的结果:
对于js对象,Vue在初始化时会遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter,再在看到上面的打印结果后,会发现对象中name及sex都有get和set方法,但是在age并没有这两个方法,因此,设置了age值后vue并不会自动更新视图,这时候就需要用到Vue.set
方法。1
this.$set(data, key, value);
在以上的例子中,使用的方法为1
this.$set(this.user, 'age', 20);
打印结果如下:
错误路由页
当路由跳转错误的时候,我们通常需要一个友好的页面来提示错误路由1
2
3
4
5
6
7
8{
path :'*',
component: NotFound
},
{
path :'*',
redirect: '/'
}
可以选择在路由配置的最下面这样定义,选择显示404页面或者重定向到主页