Vue学习之九Vue计算属性与webpack
in with 0 comment

Vue学习之九Vue计算属性与webpack

in with 0 comment

10 watch和computed

computed计算属性

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。只在相关依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

computed: {
  now: function () {
    return Date.now()
  }
}

侦听属性

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。细想一下这个例子:

<div id="demo">{{ fullName }}</div>

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

上面代码是命令式且重复的。将它与计算属性的版本进行比较:

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

好得多了,不是吗?

计算属性默认只有 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]
    }
  }
}

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

11 安装webpack

安装webpack首先需要nodjs的环境

安装nodejs

1.下载地址

https://nodejs.org/en/

2.运行安装包,选择相关的路径,主要注意点如下选择add to path,因为这样会自动给你配置对应的环境变量,其余的都是直接下一步下一步然后install 在这里插入图片描述

3.检验是否安装成功,执行两个命令node -vnpm -v(这个主要高版本的nodejs会在安装的过程中自动帮你安装的,主要的作用是对Node.js依赖的包进行管理,也可以理解为用来安装/卸载Node.js需要装的东西) 分别查看版本信息 在这里插入图片描述 Nodejs使用前的准备工作

1.在安装目录D:\Program Files\nodejs下创建两个文件夹node_globalnode_cache,主要防止执行其他安装命令时候将东西安装在C盘里面,希望将全模块所在路径和缓存路径放在我node.js安装的文件夹中。 在这里插入图片描述 2.新建文件后在执行命令行cmd,然后执行下面两个语句

npm config set prefix "D:\Program Files\nodejs\node_global"

npm config set cache "D:\Program Files\nodejs\node_cache"

在这里插入图片描述 3.接下来设置环境变量,关闭cmd窗口,“我的电脑”-右键-“属性”-“高级系统设置”-“高级”-“环境变量”,系统变量下新建NODE_PATH,填写好对应的路径 在这里插入图片描述 修改默认的用户变量D:\Program Files\nodejs\node_global 在这里插入图片描述 测试一下

配置完后,安装个module测试下,我们就安装最常用的express模块,打开cmd窗口, 输入如下命令进行模块的全局安装:

npm install express -g     # -g是全局安装的意思

安装nrm命令

npm install nrm -g  

设置镜像地址为taobao镜像

nrm ls #查看镜像地址
nrm use taobao  #切换到淘宝镜像

安装webpack1.14.0版本

npm install webpack@1.14.0 -g

Webpack常用指令和wabpack.config.js配置文件

webpack 入口文件.js 输出文件.js
webpack //最基本的启动webpack的方法,默认查找名为webpack.config.js文件
webpack --config webpack.config.js //指定配置文件

webpack -p //对打包后的文件进行压缩
webpack -d //提供source.map,方便调试代码

src中存放需要打包的文件及入口js文件main.js,在入口文件中使用的文件会被打包

webpack.config.js文件

module.exports={
	entry:'./src/main.js',//指定打包的入口文件
	output:{//配置输出
		path:__dirname + '/dist',//注意:webpack1.14.0要求这个路径是一个绝对路径
		filename:'build.js'
	}
}

11.1 webpack相关配置

在使用loader之前需要在当前目录下打开cmd命令面板,输入:

nmp init

初始化一个package.json文件在存放相关的文件

11.1.1 打包css资源演示

wabpack中使用css-loader和style-loader这两个loader来处理css资源的打包工作,所以使用前必须在项目中安装这两个包:

npm i css-loader style-loader --save-dev

css-loader:只负责加载css模块,不会将加载的css样式应用到html style-loader:负责将css-loader加载到的css样式动态的添加到html-head-style标签中

在webpack.config.js中添加处理css文件的loader配置:

module.exports={
	entry:'./src/main.js',//指定打包的入口文件
	output:{//配置输出
		path:__dirname + '/dist',//注意:webpack1.14.0要求这个路径是一个绝对路径
		filename:'build.js'
	},
	module:{
		loaders:[
			{
				test:/\.css$/,//以css结尾的文件
				loader:'style-loader!css-loader'//使用!作为分隔符
			}
		]
	}
}

在执行webpack命令,重新打包输出文件,打包好以后css就被打包到了build.js文件中,只要引入build.js文件css样式就会生效

11.2 打包less文件

安装lessless-loader

cnpm install less less-loader style-loader css-loader --save-dev

./statics/css/目录下新建一个less文件:site2.less

@color:green;
#res{
	border: 3px solid @color;
}

在入口文件main.js中导入less文件:

//导入less文件
require('../statics/css/site2.less')

使用webpack打包即可预览到效果

11.3webpack打包url()请求的资源

url-loader:打包通过url方式请求的资源

file-loader:url-loader的依赖loader
在项目根目录下打开cmd输入:
npm install url-loader file-loader --save-dev

{
    test: /\.(png|jpe?g|gif|svg|ttf|bmp)(\?.*)?$/,
        loader: 'url-loader',
            options: {
                limit: 1000,
                    name: 'img/[name].[hash:7].[ext]'
            }
}

在css文件中使用图片资源

#bg{
	width: 300px;
	height: 300px;
	background: url(../img/AIMP.png);
}

在webpack打包即可

11.4 利用webpack-dev-server实现热刷新配置

我们在修改了代码以后需要不断的重新执行webpack命令重新打包然后回到浏览器刷新页面查看,这种开发效率低下,所以这里使用weboack-dev-server当代码更新的时候自动刷新浏览器。

需要安装的node包有:

安装(前提有node环境):

cnpm install webpack@1.14.0 webpack-dev-server@1.16.0 html-webpack-plugin --save-dev

在package.json文件中配置webpack-dev-server命令

"script": {
    "dev":"webpack-dev-server --inline --hot --open --port 4009"
}

参数说明:

配置html-wabpack-plugin组件

webpack-dev-server要实现浏览器自动刷新,必须要利用html-webpack-plugin在内存中生成index.html页面才能实现,html-webpack-plugin配置步骤:

//导入html-webpack-plugin包获取到插件对象
var htmlwp = require('html-webpack-plugin');

plugins:[
    new htmlwp({
        title:'首页',//生成的页面标题
        filename:'index.html',//webpack-dev-server在内存中生成的文件名称,自动将build.js注入到这个页面底部
        template:'index1.html'//更具index1.html这个模板生成(这个文件由程序员自己定义)
    })
]

运行

在控制台执行:

npm run dev

就会开启webpack-dev-server服务器来运行vue项目,这时候随便修改一个css样式,就会自动刷新看到效果。

webpack.config.js完整示例配置:

var htmlwp = require('html-webpack-plugin');

module.exports={
	entry:'./src/main.js',//指定打包的入口文件
	output:{//配置输出
		path:__dirname + '/dist',//注意:webpack1.14.0要求这个路径是一个绝对路径
		filename:'build.js'
	},
	module:{
		loaders:[
			{
				test:/\.css$/,//以css结尾的文件
				loader:'style-loader!css-loader'//使用!作为分隔符
			},
			{
				test:/\.less$/,//以less结尾的文件
				loader:'style-loader!css-loader!less-loader'
			},
			{
                test: /\.(png|jpe?g|gif|svg|ttf|bmp)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 1000,
                    name: 'img/[name].[hash:7].[ext]'
                }
            }
		]
	},
	plugins:[
		new htmlwp({
			title:'首页',//生成的页面标题
			filename:'index.html',//webpack-dev-server在内存中生成的文件名称,自动将build.js注入到这个页面底部
			template:'index1.html'//更具index1.html这个模板生成(这个文件由程序员自己定义)
		})
	]
}

11.5ECMAScript6语法转ECMAScript5语法

需要安装的node包有:

在项目目录下打开cmd命令面板输入:

npm install babel-core babel-loader@6.4.1 babel-preset-es2015 babel-plugin-transform-runtime --save-dev

loaders:[{
    //将当前项目中所有的.js文件都要进行es6转es5操作,node_moudels除外
    test:/\.js$/,//表示当前打包的文件后缀的正则表达式
    //loader:'babel-loader?presets[]=es2015',//如果写到这里将来在打包.vue文件的时候会报错,表示先利用css-loader解析.css文件,在调用style-loader打包
    loader:'babel-loader',
    exclude:/node_modules/  //node_modules中的所有.js文件不去转换,提高打包性能
}],
babel:{
   presets:['es2015'],
   plugins:['transform-runtime']//这句代码就是为了解决打包.vue文件不报错
}

完整的配置为:

module.exports = {
	entry: './src/main.js', //指定打包的入口文件
	output: { //配置输出
		path: __dirname + '/dist', //注意:webpack1.14.0要求这个路径是一个绝对路径
		filename: 'build.js'
	},
	module: {
		loaders: [{
				test: /\.css$/, //以css结尾的文件
				loader: 'style-loader!css-loader' //使用!作为分隔符
			},
			{
				test: /\.less$/, //以less结尾的文件
				loader: 'style-loader!css-loader!less-loader'
			},
			{
				test: /\.(png|jpe?g|gif|svg|ttf|bmp)(\?.*)?$/,
				loader: 'url-loader',
				options: {
					limit: 1000,
					name: 'img/[name].[hash:7].[ext]'
				}
			},
			{
				//将当前项目中所有的.js文件都要进行es6转es5操作,node_moudels除外
				test: /\.js$/, //表示当前打包的文件后缀的正则表达式
				//loader:'babel-loader?presets[]=es2015',//如果写到这里将来在打包.vue文件的时候会报错,表示先利用css-loader解析.css文件,在调用style-loader打包
				loader: 'babel-loader',
				exclude: /node_modules/ //node_modules中的所有.js文件不去转换就是排除,提高打包性能
			}
		]
	},
	babel: {
		presets: ['es2015'],
		plugins: ['transform-runtime'] //这句代码就是为了解决打包.vue文件不报错
	},
	plugins: [
		new htmlwp({
			title: '首页', //生成的页面标题
			filename: 'index.html', //webpack-dev-server在内存中生成的文件名称,自动将build.js注入到这个页面底部
			template: 'index1.html' //更具index1.html这个模板生成(这个文件由程序员自己定义)
		})
	]
}

import '../statics/css/site.css'

各依赖版本:

"devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^6.4.1",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "css-loader": "^0.28.11",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.0.4",
    "less-loader": "^4.1.0",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.0"
  }

11.6利用webpack解析和打包.vue组件页面

Vue项目中的每个页面其实都是一个.vue的文件,这种文件,Vue称之为组件页面,必须借助于webpack的vue-loader才能使用

所以必须安装相关包:

vue : vuejs核心包

vue-loader : .vue文件编译loader

babel-plugin-transform-runtime : es6实时转成es5语法

1.在项目根目录下打开cmd命令面板,输入:

npm install vue-loader vue-template-compiler babel-plugin-transform-runtime --save-dev

npm install vue --save

2.在webpack.config.js中添加如下配置(只能在webpack1.0中使用):

babel:{
    presets:['es2015'],
    plugins:['transform-runtime']//这句话就是为了解决打包.vue文件不报错
}

在webpack2.0中在webpack.config.js文件中添加babel:{}是不认识的要改写如下方式:

在项目根目录下新建.babelrc文件,内容填写如下:

{
    presets:['es2015'],
    plugins:['transform-runtime']//这句话就是为了解决打包.vue文件不报错
}

3.在webpack.config.js的loader中增加

{
    //打包
    test:/\.vue$/,
    loader:'vue-loader'
}

12 搭建webpack1.14.0+Vue2.6.0的HelloWorld

App.vue文件

<!-- 以后项目的根组件 -->
<template>
	<!-- 主要放html页面结构 -->
	<div>
		<span v-text="message" class="red"></span>
	</div>
</template>

<script>
	// 负责到处.vue这个组件对象(它的本质是一个vue对象,所以vue中该定义的元素都可以使用)
	export default{
		data(){//等价于es5的data:function(){}c
			return {
				message:'Hello VueJs!!'
			}
		},
		methods: {
			
		},
		created(){
			
		}
	}
</script>

<style scoped>
	/* 当前页面的css样式写到这里,其中scoped表示这个里面的css代码只是在当前组件页面有效,不会去影响到其他组件页面 */
	.red{
		color:red;
	}
</style>

main.js文件

//导入vue核心包
import Vue from 'vue';

//导入App.vue的vue对象
import App from './App.vue';

//利用vue对象进行渲染
new Vue({
	el:'#app',
// 	render:function(create){
// 		create(App)
// 	}es5写法
	render:create=>create(App) //es6箭头函数写法也称goes to 语法,左边参数右边方法体
});

index.html模板index1.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<title>首页</title>
	</head>
	<body>
		<div id="app">
			
		</div>
	</body>
</html>


web.config.js文件

var htmlwp = require('html-webpack-plugin');

module.exports = {
	entry: './src/main.js', //指定打包的入口文件
	output: { //配置输出
		path: __dirname + '/dist', //注意:webpack1.14.0要求这个路径是一个绝对路径
		filename: 'build.js'
	},
	module: {
		loaders: [{
				test: /\.css$/, //以css结尾的文件
				loader: 'style-loader!css-loader' //使用!作为分隔符
			},
			{
				test: /\.less$/, //以less结尾的文件
				loader: 'style-loader!css-loader!less-loader'
			},
			{
				test: /\.(png|jpe?g|gif|svg|ttf|bmp)(\?.*)?$/,
				loader: 'url-loader',
				options: {
					limit: 1000,
					name: 'img/[name].[hash:7].[ext]'
				}
			},
			{
				//将当前项目中所有的.js文件都要进行es6转es5操作,node_moudels除外
				test: /\.js$/, //表示当前打包的文件后缀的正则表达式
				//loader:'babel-loader?presets[]=es2015',//如果写到这里将来在打包.vue文件的时候会报错,表示先利用css-loader解析.css文件,在调用style-loader打包
				loader: 'babel-loader',
				exclude: /node_modules/ //node_modules中的所有.js文件不去转换就是排除,提高打包性能
			},
			{
				//打包
				test: /\.vue$/,
				loader: 'vue-loader'
			}
		]
	},
	babel: {
		presets: ['es2015'],
		plugins: ['transform-runtime'] //这句代码就是为了解决打包.vue文件不报错
	},
	plugins: [
		new htmlwp({
			title: '首页', //生成的页面标题
			filename: 'index.html', //webpack-dev-server在内存中生成的文件名称,自动将build.js注入到这个页面底部
			template: 'index1.html' //更具index1.html这个模板生成(这个文件由程序员自己定义)
		})
	]
}

package.json文件

{
  "name": "package",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "dev": "webpack-dev-server --inline --hot --open --port 4009"
  },
  "author": "guqing",
  "license": "ISC",
  "dependencies": {
    "vue": "^2.6.4"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^6.4.1",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "css-loader": "^0.28.11",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.0.4",
    "less-loader": "^4.1.0",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "vue-loader": "^10.0.2",
    "vue-template-compiler": "^2.6.4",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.0"
  }
}

13 项目中使用的ECMAScript6语法

es5中对象:
{
    add:add,
    substrict:substrict
}

es6中对象:
{
    add,
    substrict
}
注意这种写法的属性名和值变量是同一个名称才可以简写,否则要写成es5那样

es5中对象:
{
    add:function(){},
    substrict:function(){}
}

es6中对象:
{
    add(){},
    substrict(){}
}

3.对象的到出写法

es5两种形式:
module.exports = function(){}
exports.add = function(){}

es6中写法:
1.export defaut{
	add(){}
}
2.export function add(){}//相当于将add方法当作一个属性挂载到exports对象

4.对象的导入

es5:
var add = require('./calc.js');
es6:
如果导出的是:
export default{
    add(){}
}
那么可以通过
import obj from './calc.js'导入

如果到处的是:
export function add(){}
export function substrict(){}
export const PI=3.14
那么可以通过按需加载
import {add,substrict,PI} from './calc.js'

5.es6中的箭头函数的写法

箭头的演变过程:
[2,1,3].sort(function(x,y){return y-x;})

用箭头函数实现=>读 goes to
[2,1,3].sort((x,y)=>{return y-x});
[2,1,3].sort((x,y)=>{return x++;y++;y-x});
[2,1,3].forEach(x=>{console.log(x)});

14 webpack项目中集成vue-router步骤

1.安装vue-router:

npm install vue-router --save

2.在webpack打包入口js文件中(entry指定的哪个文件main.js)配置如下:

//1.导入vue核心包
import Vue from 'vue';

//2.导入App.vue的vue对象
import App from './App.vue';

//3.导入路由vue-router
import VueRouter from 'vue-router';

//4.将VueRouter绑定到Vue对象上
Vue.use(VueRouter);

//6.导入路由规则需要的组件对象
import login from './components/account/login.vue';
import regist from './components/account/regist.vue';

//5.定义路由规则
var router = new VueRouter({
	routes:[//重点在这里是routes而不是routers没有r,否则<router-view>标签是真的不会显示的
		{path:'/login',component:login},
		{path:'/regist',component:regist}
	]
})

//利用vue对象进行渲染
new Vue({
	el:'#app',
	//使用路由对象实例
	router,
// 	render:function(create){
// 		create(App)
// 	}es5写法
	render:create=>create(App) //es6箭头函数写法也称goes to 语法,左边参数右边方法体
});

App.vue文件

<!-- 以后项目的根组件 -->
<template>
	<!-- 主要放html页面结构 -->
	<div>
		<!-- <span v-text="message" class="red"></span> -->
		<router-link to="/login">登陆</router-link>
		<span>|</span>
		<router-link to="/regist">|注册</router-link>
		
		<!-- 路由占位符 -->
		<router-view></router-view>
	</div>
</template>

<script>
	// 负责到处.vue这个组件对象(它的本质是一个vue对象,所以vue中该定义的元素都可以使用)
	export default{
		data(){//等价于es5的data:function(){}c
			return {
				message:'Hello VueJs!!'
			}
		},
		methods: {
			show
		},
		created(){
			
		}
	}
	function show(){
		alert("你看见我了");
	}
</script>

<style scoped>
	/* 当前页面的css样式写到这里,其中scoped表示这个里面的css代码只是在当前组件页面有效,不会去影响到其他组件页面 */
	.red{
		color:red;
	}
</style>


在component/account/下写login.vue文件

<template>
	<div>
		<h1>登陆组件页面</h1>
	</div>
</template>

<script>
	export default{
		
	}
</script>

<style scoped>
	
</style>


在component/account/下写regist.vue文件

<template>
	<div>
		<h1>注册组件页面</h1>
	</div>
</template>

<script>
	export default{
		
	}
</script>

<style scoped="scoped">
	
</style>


15Vue移动组件mint-ui使用

vue拥有很多的第三方开发的PC端或者移动端UI组件,此项目中主要用到了Vue移动端组件:mint-ui

类似的移动端组件还有:

PC端组件:

http://element-cn.eleme.io/#/zh-CN/component/collapse

mint-ui资源介绍

下载地址:

https://github.com/ElemeFE/mint-ui

2.官网:

http://mint-ui.github.io/#!/zh-cn

3.文档地址:

http://mint-ui.github.io/docs/#/

安装mint-ui集成到项目中

1.安装:

cnpm install mint-ui --save #命令将mint-ui安装到项目中

2.在main.js中全局导入mint-ui和它的css后即可在任何组件中使用mint-ui组件了

//6导入mint-ui的css文件
import 'mint-ui/lib/style.min.css'

//7.导入mint-ui组件对象
import Mint from 'mint-ui'

//8在Vue中使用Mint
Vue.use(Mint)

16.MUI介绍

官网

http://dev.dcloud.net.cn/mui/

文档地址

http://dev.dcloud.net.cn/mui/ui/

github地址

https://github.com/dcloudio/mui

直接使用git克隆项目到本地然后查看

mui/examples/hello-mui

目录中的实例,复制代码使用,dist目录中是需要的js和css

使用时在入口文件中导入

import '../statics/mui/css/mui.css';

使用:例如使用mui的九宫格样式

<!-- 九宫格 -->
<div class="mui-content gridview">
	<ul class="mui-table-view mui-grid-view mui-grid-9">
		<li class="mui-table-view-cell mui-media mui-col-xs-2 mui-col-sm-5" v-for="item in gridviews" :key="item.id">
			<a href="#">
				<!-- <span class="mui-icon mui-icon-home"></span> -->
				<img class="gridIcon" :src="item.icon" width="34px" height="34px">
				<div class="mui-media-body">{{item.title}}</div>
			</a>
		</li>
	</ul>
</div>