Vue-进阶版

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

Vue进阶

一、搭建项目

1、vue-cli架构
	npm i -g vue-cli:				安装vue-cli模块
	vue init webpack my-project:	利用webpack创建一个项目文件,文件名为my-project.

	cd my-project:		进入my-project文件夹
	npm install:		安装依赖,npm会根据package.json中包的信息来装环境。
	npm run dev			运行服务,启动服务。
			默认在localhost:8080端口可以打开当前的index.html页面。

		(1)、执行完之后,修改App.vue和main.js,以及创建vue文件这些操作,来进行开发页面了。

		(2)、要开发vue文件,需要webpack进行配合,
		vue-cli可以提供一个webpack的压缩环境,不需要自己写webpack的文件,拿来就能用。

		(3)、默认端口是可以更改的,在config/index.js里面,dev的port即为端口号。
		
		tips:在vue init webpack my-project的过程中,将会要求对项目的基本信息进行配置,
		有两个需要注意的点,一是需不需要ESLint进行规范代码,二是需不需要单元测试的内容。
			若开启了ESLint,该项目将开启严格模式,vue代码将会标准化,多一个空格少一个空格将会报错。
		
2、CDN
	对于常用的包,可以通过cdn来减少本地的资源。
	jqueryCDN,
		谷歌CDN:https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
		百度CDN:http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js

3、生产环境
	npm run dev命令用于开发中的本地环境搭建,
	npm run build命令将开发环境的代码生成静态文件。
	
	(1)、npm run build后,生成dist文件夹,内有static文件夹和index.html。
	(2)、在服务器环境下,static和index.html放到根目录,监听配置好的端口,即可运行起该项目。
	(3)、static文件夹内有js文件和用到的css文件。

		tips:build指令对文件进行了压缩编译,若编译发生错误,
		即文件间引用错误,生成的静态文件将无法执行,build的过程将会报错。

项目基本配置更改

config

config文件夹核心内容为index.js

index.js
	
 // see http://vuejs-templates.github.io/webpack for documentation.
 var path = require('path')
 
 module.exports = {
     /**
      * [@desc](https://my.oschina.net/u/2009802) 1、build 为打包之后的vue文件配置,即生产环境的代码配置
      */
       build: {
         //1.1、env:环境变量
         env: require('./prod.env'),
         
         //1.2、配置压缩后代码的html文件的路径和文件名,作为html的入口文件
         index: path.resolve(__dirname, '../dist/index.html'),
         
         //1.3、配置压缩后代码的路径,默认配置为所有文件存放到dist文件夹
         assetsRoot: path.resolve(__dirname, '../dist'),
         
         //1.4、配置dist文件的二级目录,主要用于存放html文件需要用到的js和css,img等
         assetsSubDirectory: 'static',
         //1.5、资源的CDN路径,如果需要将资源和入口html分离,
               //可以配置资源的CDN路径,作为发布的路径
         assetsPublicPath: '/',
         
         //1.6、是否使用sourceMap,sourceMap是webpack的一项功能,
               //设置为true,控制台的source的webpack文件夹中可以看到源代码信息
               //设置为false,控制台将只能看到压缩后的代码的信息
         productionSourceMap: true,
         
         // Gzip off by default as many popular static hosts such as
         // Surge or Netlify already gzip all static assets for you.
         // Before setting to `true`, make sure to:
         // npm install --save-dev compression-webpack-plugin
         //1.7、是否开启GZIP压缩,如果要开启,要下载一个compression-webpack-plugin插件
         productionGzip: false,
         
         //1.8、在开启了GZIP压缩后,设置需要压缩的文件,以后缀名进行区分
         productionGzipExtensions: ['js', 'css'],
         
         // Run the build command with an extra argument to
         // View the bundle analyzer report after build finishes:
         // `npm run build --report`
         // Set to `true` or `false` to always turn it on or off
         //1.9、显示webpack代码压缩之后的分析报告
         bundleAnalyzerReport: process.env.npm_config_report
     },
         /**
          * [@desc](https://my.oschina.net/u/2009802) 2、dev为开发环境的基本配置
          */
     dev: {
         //2.1、dev的环境变量
         env: require('./dev.env'),
         
         //2.2、指定项目运行后的端口号
         port: 8123,
         
         //2.3、在项目环境搭建成功后是否自动打开浏览器
         autoOpenBrowser: true,
         
         //2.4、设置静态资源的文件夹,这里设置成了static
         assetsSubDirectory: 'static',
         
         //2.5、设置根目录,这里设置的根目录为项目index.html所在的目录
         assetsPublicPath: '/',
         
         //2.6、代理,这里可以配置响应的请求到相应的代理,可以用来解决跨域
         proxyTable: {
           '/login': {
                 target: 'http://10.0.1.17:9999',
                 changeOrigin: true,
                 pathRewrite: {
                    '^/login': '/login'
                 }
           },
           '/user': {
                 target: 'http://10.0.1.9:8081',
                 changeOrigin: true,
                 pathRewrite: {
                   '^/user': '/user'
                 }
           },
         },
         
         // CSS Sourcemaps off by default because relative paths are "buggy"
         // with this option, according to the CSS-Loader README
         // (https://github.com/webpack/css-loader#sourcemaps)
         // In our experience, they generally work as expected,
         // just be aware of this issue when enabling this option.
         //2.7、是否开启webpack的cssSourceMap
         cssSourceMap: false
       }
 }

build

1、dev-server.js
2、webpack.base.conf.js

反向代理配置

理论上跨域问题可以由后端一次性解决,但也有开发过程中需要用到前端解决跨域的场景。

vue-cli支持反向代理解决跨域问题。

index.js
dev: {
    env: require('./dev.env'),
    port: configData.config.port,
    autoOpenBrowser: true,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
      '/api': {
            target: 'https://api.douban.com/v2',
            changeOrigin: true,
            pathRewrite: {
                '^/api': '/'
            }
      },
},

1、/api为代理后的名称
2、target为目标的请求地址;
3、changeOrigin置为true,即开启了反向代理;
4、pathRewrite为地址重写,
	例如本例中,/api只做代理域名作用,因此只写'^/api':'/'
	请求的url:/api/book/1220562
		等同于:https://api.douban.com/v2/book/1220562

tips:若进行配置pathRewrite,例如'^/api':'/api'
	请求的url:/api/book/1220562
		等同于:https://api.douban.com/v2/api/book/1220562
	二者有区别。

二、细节技巧

父子组件传值

1、子组件传值给父组件
	(1)、在子组件中,进行$emit向父组件调用方法
		this.$emit("closeSignUpPop",'false');

	(2)、父组件中,假定子组件的名称为Signup
	首先在子组件的调用上接收这个方法
		
	接着在父组件的methods里写入这个function
		closeSignUpPop(){
			//这里写需要操作的内容,可以是改变父组件中变量的值,
			//也可以是调用其他方法
		}

2、父组件传值给子组件
	官方在2.0版本中停止了broadcast的使用,采用bind的方式来完成
	(1)在父组件中,定义一个变量,假定其名为isClose
		data:function(){
			return{
				isClose:""
			}
		}
	(2)假设在父组件中调用的子组件名称为Signup,将isClose绑入子组件的调用中即可。
		

	(3)接着到子组件中,使用props来接收这个变量,写在和data的平级属性中;
		export default{
			props:["isClose"]
			data:function(){
				return{
				
				}
			}
		}
		此时,在子组件中,就存在了isClose这个变量,可以在子组件中的methods操作这个变量。

		tips:需要注意的是,props传入的值,也绑入到了$data中,
		因此data里面无需重新定义一个变量名为isClose,重新定义将发生变量名冲突。

3、父组件$refs方式
	$refs可以调用子组件的方法

	(1)、在父组件调用子组件时,写入ref
		

	(2)、在子组件Signup中,假定有一个methods为close
		methods:{
			close(){
				//在子组件中执行的方法
			}
		}
	(3)、回到父组件,这时候的父组件,
	可以通过this.$refs.child_1.close()触发子组件的方法
		
		tips:父组件要调用$refs,不能写入mounted钩子函数中,否则将会undefined;
		正确调用:
		this.nextTick(() => { this.$refs.xxx })

变量扩展

在main.js中,扩展Vue的原型方法。

//1、main_config.vue
const cookie = {
	get:function(){},
	set:function(){},
	del:function(){}
}
export default
{
  cookie
}

//2、main.js
import global_ from './main_config/main_config.vue'
Vue.prototype.GLOBAL = global_

//3、然后在组件中间就可以调用main_config中的方法了
this.GLOBAL.cookie.get()

延迟加载组件

import Index from "./j_index/index.vue"
————————————————→
const Index = resolve => require([ './j_index/index.vue'],resolve);	

优化URL

router的history模式,可以去除#号
	mode:'history'

Vue拦截器

Vue.http.interceptors.push((request, next) ={
 // modify request
 //在每一次的请求之前,加上请求头header
  request.headers.set('Authorization',rsaEncrypt("userId","token"))
  //在请求之前可以进行一些预处理和配置
  next((response) ={return response;});
});

路由跳转拦截

router.beforeEach((to,from,next) ={
 	if(to.matched.some( m =m.meta.auth)){
        // 对路由进行验证
        if(global_.cookie.get('userId')) { // 已经登陆
            next()     // 正常跳转到你设置好的页面
        }else{
            // 未登录则跳转到登陆界面,query:{ Rurl: to.fullPath}表示把当前路由信息传递过去方便登录后跳转回来;
            var url = { Rurl: to.fullPath};
            if(url.Rurl.indexOf('company') 0){
               next({path:'/company_index'})
            }
            if(url.Rurl.indexOf('candidate') 0){
               next({path:'/'})
            }
		} 
	} else{ next() } 
})

{
      path: 'offline',
      name: 'EmployerOrderOffline',
      component: EmployerOrderOffline,
      meta:{auth:true}
}

指定路径显示对应组件


视图与数据不同步

由于 JavaScript 的限制, Vue 不能检测以下变动的数组:
    利用索引直接设置属性值,例如: vm.items[indexOfItem] = newValue
    修改数组的长度,例如: vm.items.length = newLength

手动更新视图

在手动操作了DOM元素的时候,可能会发生数据已经更新,而视图没有更新的情况。
这时可以使用$set手动更新视图。

	假设在当前组件的data中,有一个变量名为param_1
		data:function(){
			return{
				param_1:'xxx',
				param_2:{
					innerParam:'yyy'
				}
			}
		}			

		this.$set(this.$data,'param_1','zzz');
		this.$set(this.param_2,'innerParam','ccc');

		tips:$set接收三个参数,
			第一个参数是根变量,
			第二个参数为内部变量,
			第三个参数为需要赋值给内部变量的值,

		因此存在两种方式,第一种传入this.$data,第二种直接传入this.param_2;
		注意,第二个参数应该打上引号,否则报错undefined。

router-link传参



	query中的属性将会加到path的后缀中作为参数传递。

	结果:/candidate/job_moreinfo?jobId=xxx&type=type
	
	tips:手动跳转路由时的传参同理。

三、vuex

vuex的作用类似于全局变量,在页面刷新后,vuex内的数据将会被重置为初始值。

四、个人见解

1、vuex用于所有组件共同拥有同一个状态,
	(1)、组件A是组件B的前提,如果没有组件A的值的变化,组件B将不能进入;
	(2)、页面中有组件A和B,组件A中mounted进行操作state里的值,并存入state,
		在组件B中可以获取到这个state的变化,即完成了平行同级组件之间的相互数据交互
	(3)、某些情况下,高度的将methods提取写入到mutations和actions里面,data都用vuex来管理,
		代码的阅读性会被牺牲,因为产生了多个文件间的调用,
		因此,共通的方法可以用vuex来保管,私有方法写在组件内更为合适。

2、$refs的方式使用在router-view中,有可能会在控制台中报错undefined

3、safari浏览器在解析js时,简写语法将不会被识别,报错;
	例如,有一个文件名叫website.js,向外export时,简写成:
		module.exports = {
		    config,rsaEncrypt
		}

	谷歌和firefox可以识别,但是safari将会报错,同时,npm run build时也将报错。
	正确写法:
		module.exports = {
		    config:config,
			rsaEncrypt:rsaEncrypt,
		}

4、手动跳转路由,不建议使用location.href
	有时候需要在methods进行操作路由跳转,这时不建议用location.href,会增加代码维护的难度。
	
	推荐写法:
		this.$router.push({name:"EmployerOrderPrice"})

	采用name识别的方式,当指定路由路径更改时,只需要改router.js的path即可。

	tips:手动跳转路由的传参和router-link写法一样。

     5、重置component的data状态
            Object.assign(this.$data, this.$options.data())
            但是必须要注意在默认的样式中不应该取变量,例如i18n,abc:this.$t("xxx.xxx"),否则将会报错。

转载于:https://my.oschina.net/LinearLawX/blog/1542479

你可能感兴趣的:(webpack,python,javascript,ViewUI)