前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue项目实战:实战技巧总结

vue项目实战:实战技巧总结

原创
作者头像
微芒不朽
发布2022-04-28 17:01:34
3.4K0
发布2022-04-28 17:01:34
举报
文章被收录于专栏:前端进阶-詹躲躲

一、创建项目及配置

1.1 vue cli2 创建项目

代码语言:javascript
复制
vue init webpack project
代码语言:javascript
复制
npm install
代码语言:javascript
复制
npm run dev

1.2 vue cli3 创建项目

代码语言:javascript
复制
 vue create project

选择配置,看个人项目需求

代码语言:javascript
复制
TypeScript 支持使用 TypeScript 书写源码
 Progressive Web App (PWA) Support PWA 支持。
 Router 支持 vue-router 。
 Vuex 支持 vuex 。
 CSS Pre-processors 支持 CSS 预处理器。
 Linter / Formatter 支持代码风格检查和格式化。
 Unit Testing 支持单元测试。
 E2E Testing 支持 E2E 测试。

进入到项目根目录

代码语言:javascript
复制
 cd  project

启动项目

代码语言:javascript
复制
 npm run serve

二、安装 element-UI

代码语言:javascript
复制
npm i element-ui -S
2.1main.js 引入
2.1.1 全局引入
代码语言:javascript
复制
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(Element)
2.1.2 按需引入

首先,安装 babel-plugin-component

代码语言:javascript
复制
npm install babel-plugin-component -D

然后,将 .babelrc 修改为:

代码语言:javascript
复制
{
	"presets": [
		["es2015", {
			"modules": false
		}]
	],
	"plugins": [
		[
			"component",
			{
				"libraryName": "element-ui",
				"styleLibraryName": "theme-chalk"
			}
		]
	]
}

接下来,如果你只希望引入部分组件,比如 ButtonSelect,那么需要在 main.js 中写入以下内容:

代码语言:javascript
复制
import Vue from 'vue';
import { Button, Select } from 'element-ui';
import App from './App.vue';

Vue.component(Button.name, Button);
Vue.component(Select.name, Select);

或写为

代码语言:javascript
复制
- Vue.use(Button)
- Vue.use(Select)

三、安装 vuex

代码语言:javascript
复制
npm i vuex -s
3.1 /src/store 下面的 index.js 中
代码语言:javascript
复制
import Vue from 'vue'
import Vuex from 'vuex'

//挂载 Vuex
Vue.use(Vuex)

//创建 VueX 对象
const store = new Vuex.Store({
state:{name: 'helloVueX',
},
mutations:{},
actions:{},
modules:{}
})

export default store
3.2 main.js 引入

store 挂载到当前项目的 Vue 实例当中去

代码语言:javascript
复制
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
el: '#app',
router,
store, //store:store 和 router 一样,将我们创建的 Vuex 实例挂载到这个 vue 实例中
render: h => h(App)
})
3.3 在组件中使用 Vuex
代码语言:html
复制
<template>
    <div id='app'>
      name:
      <h1>{{ $store.state.name }}</h1>
    </div>
</template>

methods:{
  add(){
      console.log(this.\$store.state.name)
    }
},

更具体的学习文档参考我的网站:

学习文档

四、配置scss环境

4.1.首先安装依赖
代码语言:javascript
复制
npm install node-sass sass-loader --save-dev 
4.2.找到 build 中 webpack.base.conf.js,在 rules 中添加 scss 规则
代码语言:javascript
复制
{
  test: /\.scss\$/,
  loaders: ['style', 'css', 'sass']
} 
4.3.在 vue 文件中使用
代码语言:html
复制
<style lang='scss'>
  
</style>

4.4 在 vue 项目全局中引入 scss

1.全局引用时需要安装 sass-resources-loader
代码语言:javascript
复制
npm install sass-resources-loader --save-dev 
2.修改 build 中的 utils.js

scss: generateLoaders('sass')

修改为
代码语言:javascript
复制
scss: generateLoaders('sass').concat({
	loader: 'sass-resources-loader',
	options: {
		//你自己的 scss 全局文件的路径
		resources: path.resolve(\_\ _dirname, '../src/style/common.scss')
	}
})

如果上面的不能正常编译

代码语言:javascript
复制
//配置 sass 编译路径

function generateSassResourceLoader() {
	let loaders = [
		cssLoader,
		'sass-loader',
		{
			loader: 'sass-resources-loader',
			options: {
				// 多个文件时用数组的形式传入,单个文件时可以直接使用 path.resolve(__dirname, '../static/style/common.scss'
				resources: path.resolve(__dirname, '../src/style/common.scss')
			}
		}
	];
	if (options.extract) {
		return ExtractTextPlugin.extract({
			use: loaders,
			fallback: 'vue-style-loader'
		});
	} else {
		return ['vue-style-loader'].concat(loaders);
	}
}
在 cssLoaders 里面引入
代码语言:javascript
复制
sass:generateSassResourceLoader(),//新加的
scss:generateSassResourceLoader(),//新加的

4.5 引入全局的 sass

代码语言:javascript
复制
npm install --s node-sass sass-loader

1.首先你需要

代码语言:javascript
复制
npm install --s sass-resources-loader 

2.在 build 目录下找到 utils.js 文件

代码语言:javascript
复制
Module build failed: TypeError: this.getResolve is not a function at Object.loader 

安装 node-sass 运行报错

vue 安装 node-sass 编译报错

代码语言:txt
复制
安装node-scss报错

安装 node-scss 报错

在搭建 vue 脚手架 或者是在 vue 项目中,想使用 sass 的功能,

代码语言:javascript
复制
npm install node-sass --save-dev //安装 node-sass
npm install sass-loader --save-dev //安装 sass-loader
npm install style-loader --save-dev //安装 style-loader

这是因为当前 sass 的版本太高,webpack 编译时出现了错误,这个时候只需要换成低版本的就行,下面说一下修改方法,很简单,如下,找到 package.json 文件,里面的 "sass-loader"的版本更换掉 就行了。

代码语言:javascript
复制
将 "sass-loader": "^8.0.0",更换成了 "sass-loader": "^7.3.1",

也可以先卸载当前版本,然后安装指定的版本

卸载当前版本
代码语言:javascript
复制
npm uninstall sass-loader
安装
代码语言:javascript
复制
npm install sass-loader@7.3.1 --save-dev

五、配置less环境

安装 lessless-loader
代码语言:javascript
复制
npm install less less-loader --save

修改 webpack.base.config.js 文件,配置 loader 加载依赖,让其支持外部的 less,在原来的代码上添加

代码语言:javascript
复制
// 此种方法在控制台中标签样式显示的是style标签样式
{
	test: /\.less$/,
	loader: "style-loader!css-loader!less-loader",
}
代码语言:javascript
复制
// 可以在控制台中看到当前标签样式来自于哪个less文件
{
	test: /\.less$/,
	loader: "style-loader!css-loader!less-loader",
	options: {
		sourceMap: true
	}
}

在 vue 文件中的 style 标签中添加 lang="less"即可在标签中使用 less,或者外部引入 less

参考文档

六、引入font-awesome

代码语言:javascript
复制
npm install font-awesome --save

然后在 main.js 引入 font-awesome/css/font-awesome.min.css 即可。

7、vue 配置网站的 ico

7.1方式一:
代码语言:txt
复制
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
7.2 方式二
代码语言:javascript
复制
webpack.dev.conf.js
new HtmlWebpackPlugin({
		filename: 'index.html',
		template: 'index.html',
		favicon: 'favicon.ico', // 新增
		inject: true
	}),

	webpack.prod.conf.js
new HtmlWebpackPlugin({
	filename: config.build.index,
	template: 'index.html',
	inject: true,
	minify: {
		removeComments: true,
		collapseWhitespace: true,
		removeAttributeQuotes: true
		// more options:
		// https://github.com/kangax/html-minifier#options-quick-reference
	},
	// necessary to consistently work with multiple chunks via CommonsChunkPlugin
	chunksSortMode: 'dependency',
	favicon: 'favicon.ico' // 新增
}),

八、引入自定义公共样式

router/index.js 里面引入公共样式

代码语言:javascript
复制
import 'bootstrap/dist/css/bootstrap.css' //引入 bootstrap
import 'bootstrap-vue/dist/bootstrap-vue.css'
import '@/common/common.css'
import '@/common/index.css'

九、路由按需加载

代码语言:javascript
复制
const port = () => import('@/pages/port') //入口页面、
代码语言:javascript
复制
const router = new Router({
  // mode: 'history',
  routes: [
    {
      path: '/',
      name: 'port',
      component: resolve => require.ensure([], () => resolve(require('@/pages/port')), 'port'),
    }]
})

参考文档

十、全局自定义方法

main.js 里面挂载方法到 vue.prototype
代码语言:javascript
复制
Vue.prototype.isMobile = function() {
	let flag = navigator.userAgent.match(
		/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
	)
	return flag;
}
组件里面使用
代码语言:javascript
复制
mounted: function() {
  this.isMobile();
}

十一、引入接口文件暴露到全局

11.1 在 main.js 里面引入接口暴露到全局'
代码语言:javascript
复制
// 接口暴露在全局
import { server } from './config/api'
Vue.prototype.\$server = server;
代码语言:javascript
复制
//api.js

export const server = {
getContentMenu: (paramObj)=>fetch('/content/menu',paramObj),//内容详情查询
getContentListPort: (paramObj)=>fetch('/content/list/'+paramObj),//入口页面接口
getContentList:(paramObj)=>fetch('/content/list/'+paramObj),//内容详情查询
getPageviews:(paramObj)=>fetch('/webpage/1/view',paramObj)//流量统计接口
}

组件里面使用:
```js

methods: {

代码语言:txt
复制
getPageviews() {
代码语言:txt
复制
	var that = this;
代码语言:txt
复制
	let params = {
代码语言:txt
复制
		pageId: that.pageId,
代码语言:txt
复制
		pageUrl: that.pageUrl,
代码语言:txt
复制
	};
代码语言:txt
复制
	that.\$server.getPageviews(params).then(response => {})
代码语言:txt
复制
}

}

代码语言:txt
复制
#####  11.2 **axios** 方法封装,整个 **api.js**

```js

import axios from 'axios';

axios.defaults.timeout = 5000;

axios.defaults.baseURL =''; //填写域名

//http request 拦截器

axios.interceptors.request.use(

config => {

代码语言:txt
复制
config.data = JSON.stringify(config.data);
代码语言:txt
复制
config.headers = {
代码语言:txt
复制
  'Content-Type':'application/x-www-form-urlencoded'
代码语言:txt
复制
}
代码语言:txt
复制
return config;

},

error => {

代码语言:txt
复制
return Promise.reject(err);

}

);

//响应拦截器即异常处理

axios.interceptors.response.use(response => {

代码语言:txt
复制
return response

}, err => {

代码语言:txt
复制
if (err && err.response) {
代码语言:txt
复制
  switch (err.response.status) {
代码语言:txt
复制
    case 400:
代码语言:txt
复制
        console.log('错误请求')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 401:
代码语言:txt
复制
        console.log('未授权,请重新登录')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 403:
代码语言:txt
复制
      console.log('拒绝访问')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 404:
代码语言:txt
复制
      console.log('请求错误,未找到该资源')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 405:
代码语言:txt
复制
      console.log('请求方法未允许')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 408:
代码语言:txt
复制
      console.log('请求超时')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 500:
代码语言:txt
复制
      console.log('服务器端出错')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 501:
代码语言:txt
复制
      console.log('网络未实现')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 502:
代码语言:txt
复制
      console.log('网络错误')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 503:
代码语言:txt
复制
      console.log('服务不可用')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 504:
代码语言:txt
复制
      console.log('网络超时')
代码语言:txt
复制
      break;
代码语言:txt
复制
    case 505:
代码语言:txt
复制
      console.log('http版本不支持该请求')
代码语言:txt
复制
      break;
代码语言:txt
复制
    default:
代码语言:txt
复制
      console.log(`连接错误${err.response.status}`)
代码语言:txt
复制
  }
代码语言:txt
复制
} else {
代码语言:txt
复制
  console.log('连接到服务器失败')
代码语言:txt
复制
}
代码语言:txt
复制
return Promise.resolve(err.response)

})

/**

  • 封装get方法
  • @param url
  • @param data
  • @returns {Promise} */

export function fetch(url,params={}){

return new Promise((resolve,reject) => {

代码语言:txt
复制
axios.get(url,{
代码语言:txt
复制
  params:params
代码语言:txt
复制
})
代码语言:txt
复制
.then(response => {
代码语言:txt
复制
  resolve(response.data);
代码语言:txt
复制
})
代码语言:txt
复制
.catch(err => {
代码语言:txt
复制
  reject(err)
代码语言:txt
复制
})

})

}

/**

  • 封装post请求
  • @param url
  • @param data
  • @returns {Promise} */

export function post(url,data = {}){

return new Promise((resolve,reject) => {

代码语言:txt
复制
 axios.post(url,data)
代码语言:txt
复制
      .then(response => {
代码语言:txt
复制
        resolve(response.data);
代码语言:txt
复制
      },err => {
代码语言:txt
复制
        reject(err)
代码语言:txt
复制
      })

})

}

/**

  • 官网接口请求封装
  • @param url
  • @param data
  • @returns {Promise} */

export const server = {

代码语言:txt
复制
getContentMenu: (paramObj)=>fetch('/content/menu',paramObj),//内容详情查询
代码语言:txt
复制
getContentListPort: (paramObj)=>fetch('/content/list/'+paramObj),//入口页面接口
代码语言:txt
复制
getContentList:(paramObj)=>fetch('/content/list/'+paramObj),//内容详情查询
代码语言:txt
复制
getPageviews:(paramObj)=>fetch('/webpage/1/view',paramObj)//流量统计接口

}

代码语言:txt
复制
## 十二、provide /inject 完美解决不跳转不闪动页面刷新

原理:此方法使用的是 v-if 来控制 router-view 的显示或隐藏,v-if 从 false 变为 true 时,vue 会重新渲染 router-view 区域,所以当参数变化时,只需让 v-if 从 true => false => true,就能实现页面刷新。

##### 12.1 找到route-view
```js

//App.vue

<template>

代码语言:txt
复制
  <div id="app">
代码语言:txt
复制
    <router-view v-if="isRouterAlive"/>
代码语言:txt
复制
  </div>

</template>

<script>

代码语言:txt
复制
export default {
代码语言:txt
复制
  name: 'App',
代码语言:txt
复制
  provide() {
代码语言:txt
复制
    return {
代码语言:txt
复制
      reload: this.reload//调用reload方法
代码语言:txt
复制
    }
代码语言:txt
复制
  },
代码语言:txt
复制
  data() {
代码语言:txt
复制
    return {
代码语言:txt
复制
      isRouterAlive: true//一开始router-view为true
代码语言:txt
复制
    }
代码语言:txt
复制
  },
代码语言:txt
复制
  methods: {
代码语言:txt
复制
    reload() {
代码语言:txt
复制
      this.isRouterAlive = false
代码语言:txt
复制
         //在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
代码语言:txt
复制
      this.$nextTick(() => {
代码语言:txt
复制
        this.isRouterAlive = true
代码语言:txt
复制
      })
代码语言:txt
复制
    }
代码语言:txt
复制
  }
代码语言:txt
复制
}

</script>

代码语言:txt
复制
#####  12.2在页面操作
```js
代码语言:txt
复制
export default {
代码语言:txt
复制
  name: 'newproduct',
代码语言:txt
复制
  inject:['reload'],//在export default下面加上这一段
代码语言:txt
复制
  method:{
代码语言:txt
复制
    //调用App.vue下的this.reload()方法,来改变v-if的状态
代码语言:txt
复制
    clickDiv(){//刷新按钮调用的方法
代码语言:txt
复制
      this.reload()
代码语言:txt
复制
    }
代码语言:txt
复制
  }
代码语言:txt
复制
[参考文档:如何实现 vue 中不跳转不闪动页面刷新?provide /inject 完美解决方案](https://segmentfault.com/a/1190000018875444)

## 十三、vue动态绑定 class

#####  13.1 对象方法
```js

:class="{ 'active': isActive }"

代码语言:txt
复制
  
#### 13.2 判断是否绑定一个active
```js

:class="{'active':isActive==-1}"

或者

:class="{'active':isActive==index}"

代码语言:txt
复制
13.3绑定并判断多个
第一种(用逗号隔开)
代码语言:javascript
复制
:class="{ 'active': isActive, 'sort': isSort }"
第二种(放在 data 里面)
代码语言:javascript
复制
:class="classObject"
data() {
	return {
		classObject: {
			active: true,
			sort: false
		}
	}
}
第三种(使用 computed 属性)
代码语言:javascript
复制
:class="classObject"
data() {
		return {
			isActive: true,
			isSort: false
		}
	},
	computed: {
		classObject: function() {
			return {
				active: this.isActive,
				sort: this.isSort
			}
		}
	}
13.4数组方法
1.单纯数组
代码语言:javascript
复制
:class="[isActive,isSort]"
代码语言:javascript
复制
data() {
	return {
		isActive: 'active',
		isSort: 'sort'
	}
}

数组与三元运算符结合判断选择需要的class

三元运算符后面的“:”两边的class需要加上单引号

代码语言:javascript
复制
:class="[isActive?'active':'']"

或者

代码语言:javascript
复制
:class="[isActive==1?'active':'']"

或者

代码语言:javascript
复制
:class="[isActive==index?'active':'']"

或者

代码语言:javascript
复制
:class="[isActive==index?'active':'otherActiveClass']"
13.5 数组对象结合动态判断

//前面这个 active 在对象里面可以不加单引号,后面这个 sort 要加单引号

代码语言:javascript
复制
:class="[{ active: isActive }, 'sort']"

或者

代码语言:javascript
复制
:class="[{ active: isActive==1 }, 'sort']"

或者

代码语言:javascript
复制
:class="[{ active: isActive==index }, 'sort']"

应用于组件

如果直接在自定义组件中使用 class 或 :class,那么样式规则就会直接应在这个组件的根元素上。

代码语言:javascript
复制
<div id="app">
    <text-component :class="{'isStrong':isStrong}"></text-component>
</div>
代码语言:javascript
复制
<script>
    Vue.component('text-component', {
        template: '<p class="content">不懂基因测序的学霸不是好的人工智能公司 CEO</p>'
    });
    var app = new Vue({
        el: '#app',
        data: {
            isStrong: true
        }
    });
</script>

参考文档01

参考文档02

style三元表达式

代码语言:javascript
复制
<span v-bind:style="{'display':config.isHaveSearch ? 'block':'none'}" >动态绑定样式</span>

参考文档

也可以使用 v-bind:style 或 :style 直接给 HTML 元素绑定样式,它也有对应的对象语法与数组语法。

代码语言:javascript
复制
<div id="app">
    <div :style="border"></div>
</div>
代码语言:javascript
复制
<script>
    var app = new Vue({
        el: '#app',
        data: {
            border:{
                border:'1px solid #00F',
                textShadow:'0 0 .3em gray'
            }
        }
    });
</script>

因为 JS 属性不支持短横分隔命名,所以我们这里使用 CSS 也支持的驼峰命名法。

参考文档

计算属性computed

例:反转字符串:
代码语言:javascript
复制
<div id="app">
  <p>原始字符串: {{ message }}</p>
  <p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
代码语言:javascript
复制
<script>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
</script>

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。。换句话说,computed 是局部渲染,而 methods 是全部渲染

区别:

  • 1.methods是个方法,比如你点击事件要执行一个方法,这时候就用methods,
  • 2.computed是计算属性,实时响应的,比如你要根据data里一个值随时变化做出一些处理,就用computed。
  • 3.我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
  • 4.methods必须需要一定的条件去触发,而computed则不需要.
  • 5.computed依赖缓存,如果不需要经常变动的用computed,需要经常变动的用methods。如果你需要传参数,就用methods。

computed

computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :

代码语言:javascript
复制
var vm = new Vue({
	el: '#app',
	data: {
		name: 'Google',
		url: 'http://www.google.com'
	},
	computed: {
		site: {
			// getter
			get: function() {
				return this.name + ' ' + this.url
			},
			// setter
			set: function(newValue) {
				var names = newValue.split(' ')
				this.name = names[0]
				this.url = names[names.length - 1]
			}
		}
	}
})
代码语言:javascript
复制
// 调用 setter, vm.name 和 vm.url 也会被对应更新
vm.site = 'http://www.runoob.com';
document.write('name: ' + vm.name);
document.write('<br>');
document.write('url: ' + vm.url);

从实例运行结果看在运行 vm.site = 'http://www.runoob.com'; 时,setter 会被调用, vm.name 和 vm.url 也会被对应更新。

十四、style样式绑定

class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。

Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。

14.1 class 属性绑定

我们可以为 v-bind:class 设置一个对象,从而动态的切换 class:

代码语言:css
复制
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
</style>
代码语言:html
复制
<div id="app">
  <div v-bind:class="{ active: isActive }"></div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
    isActive: true
  }
})
</script>

例:text-danger 类背景颜色覆盖了 active 类的背景色:

方法一:在对象中传入更多属性用来动态切换多个 class 。
代码语言:css
复制
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
代码语言:html
复制
<div id="app">
  <div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
  </div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
    isActive: true,
    hasError: true
  }
})
</script>
方法二:直接绑定数据里的一个对象:
代码语言:css
复制
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
代码语言:html
复制
<div id="app">
  <div v-bind:class="classObject"></div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
    classObject: {
      active: true,
      'text-danger': true
    }
  }
})
</script>
方法三:绑定返回对象的计算属性:
代码语言:css
复制
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
代码语言:html
复制
<div id="app">
  <div v-bind:class="classObject"></div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
  isActive: true,
  error: null
  },
  computed: {
    classObject: function () {
      return {
        active: this.isActive && !this.error,
        'text-danger': this.error && this.error.type === 'fatal',
      }
    }
  }
})
</script>
方法四:数组语法
代码语言:css
复制
<style>
.active {
    width: 100px;
    height: 100px;
    background: green;
}
.text-danger {
    background: red;
}
</style>
代码语言:html
复制
<div id="app">
    <div v-bind:class="[activeClass, errorClass]"></div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
})
</script>

还可以使用三元表达式来切换列表中的 class :

errorClass 是始终存在的,isActive 为 true 时添加 activeClass 类:

代码语言:css
复制
<style>
.text-danger {
    width: 100px;
    height: 100px;
    background: red;
}
.active {
    width: 100px;
    height: 100px;
    background: green;
}
</style>
代码语言:html
复制
<div id="app">
    <div v-bind:class="[errorClass ,isActive ? activeClass : '']"></div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
    isActive: true,
    activeClass: 'active',
    errorClass: 'text-danger'
  }
})
</script>

style样式邦定

v-bind:style直接设置样式:

代码语言:html
复制
<div id="app">
    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
    activeColor: 'green',
    fontSize: 30
  }
})
</script>

也可以直接绑定到一个样式对象:

代码语言:html
复制
<div id="app">
  <div v-bind:style="styleObject">菜鸟教程</div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
    styleObject: {
      color: 'green',
      fontSize: '30px'
    }
  }
})
</script>

v-bind:style 可以使用数组将多个样式对象应用到一个元素上:

代码语言:html
复制
<div id="app">
  <div v-bind:style="[baseStyles, overridingStyles]">菜鸟教程</div>
</div>
代码语言:javascript
复制
<script>
new Vue({
  el: '#app',
  data: {
    baseStyles: {
      color: 'green',
      fontSize: '30px'
    },
    overridingStyles: {
      'font-weight': 'bold'
    }
  }
})
</script>

参考文档

十五、vue组件参数传递:

Vue 组件间通信包括:父子组件间通信,兄弟组件间通信以及模块之间通信等。Vue 是数据驱动视图更新的框架, 所以对于 Vue 来说组件间的数据通信非常重要。Vue 实现组件间通信有很多方式,今天我来给大家讲解一下父子组件间通信:props 和\$emit。

15.1.子组件向父组件传递参数;

子组件 A:

代码语言:javascript
复制
    <template>
      <div class="childA-wrapper">
        子组件A
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          childA: '我是组件A传过来的值'
        }
      },
      created: function() {},
      mounted() {
        this.sendDataParent()
      },
      methods: {
        sendDataParent() {
          // getChildDataA是在父组件on监听的方法
          // 第二个参数this.childA是需要传的值
          this.$emit('getChildDataA', this.childA)
        }
      }
    }
    </script>

子组件 B:

代码语言:javascript
复制
  <template>
  <div class="childB-wrapper">
    子组件B
  </div>
</template>

<script>
export default {
  data() {
    return {
      childB:'我是组件B传过来的值'
    }
  },
  created:function() {
  },
  mounted(){
    this.sendDataParent()
  },
  methods: {
   sendDataParent() {
        // getChildDataB是在父组件on监听的方法
        // 第二个参数this.childB是需要传的值
        this.$emit('getChildDataB', this.childB)
      }
  }
}
</script>

父组件:

代码语言:javascript
复制
  <template>
        <div>
            <v-childA v-on:getChildDataA="getChildDataA"></v-childA>
            <v-childB v-on:getChildDataB="getChildDataB"></v-childB>
            <div>获取组件A传过来的值:{{childAValue}}</div>
            <div>获取组件B传过来的值:{{childBValue}}</div>
        </div>
    </template>

    <script>
    import childA from '@/components/childA.vue'
    import childB from '@/components/childB.vue'
    export default {
      data() {
        return {
            childAValue:'',
            childBValue:'',
        }
      },
      methods: {
       getChildDataA(childA){
        console.log(childA)
        this.childAValue=childA
       },
       getChildDataB(childB){
        console.log(childB)
        this.childBValue=childB
       }
      },
      components: { 'v-childA': childA, 'v-childB': childB}
    }
    </script>

15.2、父组件向子组件传递参数

父组件:
代码语言:javascript
复制
<template>
        <div>
            <v-childA></v-childA>
            <v-childB  :sendBData="sendB"></v-childB>
        </div>
    </template>

    <script>
    import childA from '@/components/childA.vue'
    import childB from '@/components/childB.vue'
    export default {
      data() {
        return {
            sendB:'父组件向B组件传递的参数'
        }
      },
      methods: {
      },
      components: { 'v-childA': childA, 'v-childB': childB}
    }
    </script>
子组件 B:
代码语言:javascript
复制
<template>
  <div class="childB-wrapper">
    子组件B:{{sendBData}}
  </div>
</template>
<script>
export default {
  data() {
    return {}
  },
  created: function() {},
  mounted() {},
  methods: {},
  props: {
    sendBData: String,
    required: true
  }
}

</script>

15.3、非父子组件进行传值;

bus.js
代码语言:javascript
复制
  import Vue from 'vue'
  export default new Vue()
组件 childB:
代码语言:javascript
复制
<template>
    <div class="childB-wrapper">
    </div>
  </template>
  <script>
  import Bus from '@/common/bus.js'
  export default {
    data() {
      return {
        childB: '我是组件B的内容'
      }
    },
    created: function() {},
    mounted() {
      this.elementByValue()
    },
    methods: {
      elementByValue: function () {
          Bus.$emit('val', this.childB)
        }
    }
  }

  </script>
代码语言:javascript
复制
##### 组件 childA:

  <template>
      <div class="childA-wrapper">
        A组件:<span>{{childB}}</span>
      </div>
    </template>
    <script>
    import Bus from '@/common/bus.js'
    export default {
      data() {
        return {
          childB: ''
        }
      },
      created: function() {},
      mounted() {
        var that = this
        // 用 $on事件来接收参数
        Bus.$on('val', (data) => {
          console.log(data)
          that.childB = data
        })
      }
    }

    </script>

更多请查看:你不知道的vue组件传值方式

16.vue脚手架配置预渲染,prerender-spa-plugin 配置

用到插件:cnpm install prerender-spa-plugin --save

脚手架 2.0:(自己的是 2.0)

16.1 build/webpack.prod.conf.js 配置
代码语言:javascript
复制
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const webpackConfig = merge(baseWebpackConfig, {
	plugins: [
		// vue-cli 生成的配置就有了
		new HtmlWebpackPlugin({
			filename: config.build.index,
			template: 'index.html',
			inject: true,
			minify: {
				removeComments: true,
				collapseWhitespace: true,
				removeAttributeQuotes: true
			},
			chunksSortMode: 'dependency'
		}),
		// 配置 PrerenderSPAPlugin
		new PrerenderSPAPlugin({
			// 生成文件的路径,也可以与 webpakc 打包的一致。
			staticDir: path.join(\_\ _dirname, '../dist'),

			// 对应自己的所有路由文件,比如 index 有参数,就需要写成 /index/param1。这个其实不需要;千万不要加'/'这个 嵌套路由得 commonquestion 直接写即可
			routes: ['index', '...', '/commonQuestion', '/commonQuestion/questionList', '/commonQuestion/questionDetailInfo'],
			// ;
			renderer: new Renderer({
				inject: { // 可选;最好还是用
					foo: 'bar'
				},
				headless: false, // 可选;最好用
				renderAfterTime: 5000, // 通过实践是必选 官网说可选有误 一定要必选
				renderAfterDocumentEvent: 'render-event' // 可选;最好用
			})
		}),
	]
})
16.2.路由得 index.js 添加属性:
代码语言:javascript
复制
 mode:‘history’,
代码语言:javascript
复制
    修改config/index.js 中的build的 assetsPublicPath: ‘/’ ;不然会导致刷新页面路径错乱导致样式或者js丢失;

    修改main.js

    new Vue({
      el: '#app',
      router,
      store,				// 如果需要了切记引入啊   切记需要挂载的全部挂载上去
      render: h => h(App),
      mounted () {
        document.dispatchEvent(new Event('render-event'))
      }
    })
16.3.build/webpack.prod.conf.js 配置
代码语言:javascript
复制
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require('path');
module.exports = {
	configureWebpack: config => {
		if (process.env.NODE_ENV !== 'production') return;
		return {
			plugins: [
				new PrerenderSPAPlugin({
					// 生成文件的路径,也可以与 webpakc 打包的一致。
					// 下面这句话非常重要!!!
					// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
					staticDir: path.join(\_\ _dirname, 'dist'),
					// 对应自己的路由文件,比如 a 有参数,就需要写成 /a/param1。
					routes: ['/', '/product', '/about'],
					// 这个很重要,如果没有配置这段,也不会进行预编译
					renderer: new Renderer({
						inject: {
							foo: 'bar'
						},
						headless: false,
						renderAfterTime: 5000, // 必选哈
						// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
						renderAfterDocumentEvent: 'render-event'
					})
				}),
			],
		};
	}
}
16.4 main.js 配置
代码语言:javascript
复制
new Vue({
	router,
	store,
	render: h => h(App),
	mounted() {
		document.dispatchEvent(new Event('render-event'))
	}
}).\$mount('#app')

其他修改同 2.0;

参考文档

十六、vue SPA单页面的 SEO 优化

代码语言:javascript
复制
vue-meta-info 

官方地址: monkeyWangs/vue-meta-info

1.安装
代码语言:javascript
复制
npm install vue-meta-info --save
2.全局引入 vue-meta-info
代码语言:javascript
复制
import Vue from 'vue'
import MetaInfo from 'vue-meta-info'

Vue.use(MetaInfo)
3.组件内静态使用 metaInfo
代码语言:javascript
复制
<template>
  ...
</template>
代码语言:javascript
复制
<script>
  export default {
    metaInfo: {
      title: 'My Example App', // set a title
      meta: [{                 // set meta
        name: 'keyWords',
        content: 'My Example App'
      }]
      link: [{                 // set link
        rel: 'asstes',
        href: 'https://assets-cdn.github.com/'
      }]
    }
  }
</script>
4.如果你的 title 或者 meta 是异步加载的,那么你可能需要这样使用
代码语言:javascript
复制
<template>
  ...
</template>
代码语言:javascript
复制
<script>
  export default {
    name: 'async',
    metaInfo () {
      return {
        title: this.pageName
      }
    },
    data () {
      return {
        pageName: 'loading'
      }
    },
    mounted () {
      setTimeout(() => {
        this.pageName = 'async'
      }, 2000)
    }
  }
</script>
代码语言:javascript
复制
<meta name="参数" content="具体的描述">
5.meta标签共有两个属性,分别是http-equiv属性和name属性
  1. name 属性 name 属性主要用于描述网页,比如网页的关键词,叙述等。与之对应的属性值为 content,content 中的内容是对 name 填入类型的具体描述,便于搜索引擎抓取。 meta 标签中 name 属性语法格式是:<meta name="参数" content="具体的描述">

其中 name 属性共有以下几种参数。(A-C 为常用属性)

A. keywords(关键字)

说明:用于告诉搜索引擎,你网页的关键字。

代码语言:javascript
复制
<meta name="keywords" content="XX网,汽车,车主,评选">
B. description(网站内容的描述)
代码语言:javascript
复制
说明:用于告诉搜索引擎,你网站的主要内容。
代码语言:javascript
复制
<meta name="description" content="汽车评选,XX网,评选,汽车">
C.viewport(移动端的视口)

说明:这个属性常用于设计移动端网页。

举例

代码语言:javascript
复制
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
D. robots(定义搜索引擎爬虫的索引方式)
代码语言:javascript
复制
说明:robots 用来告诉爬虫哪些页面需要索引,哪些页面不需要索引。
content 的参数有 all,none,index,noindex,follow,nofollow。默认是 all。

举例:

代码语言:javascript
复制
<meta name="robots" content="none">

具体参数如下:

代码语言:javascript
复制
1.none : 搜索引擎将忽略此网页,等价于 noindex,nofollow。
2.noindex : 搜索引擎不索引此网页。
3.nofollow: 搜索引擎不继续通过此网页的链接索引搜索其它的网页。
4.all : 搜索引擎将索引此网页与继续通过此网页的链接索引,等价于 index,follow。
5.index : 搜索引擎索引此网页。
6.follow : 搜索引擎继续通过此网页的链接索引搜索其它的网页。
E. author(作者)

说明:用于标注网页作者

举例:

代码语言:txt
复制
<meta name="author" content="Lxxyx,841380530@qq.com">
F. generator(网页制作软件)

说明:用于标明网页是什么软件做的

举例: (不知道能不能这样写):

代码语言:txt
复制
<meta name="generator" content="Sublime Text3">
G. copyright(版权)

说明:用于标注版权信息

举例:

代码语言:txt
复制
<meta name="copyright" content="Lxxyx"> //代表该网站为Lxxyx个人版权所有。
H. revisit-after(搜索引擎爬虫重访时间)

说明:如果页面不是经常更新,为了减轻搜索引擎爬虫对服务器带来的压力,可以设置一个爬虫的重访时间。如果重访时间过短,爬虫将按它们定义的默认时间来访问。

举例:

代码语言:txt
复制
<meta name="revisit-after" content="7 days" >
I. renderer(双核浏览器渲染方式)

说明:renderer 是为双核浏览器准备的,用于指定双核浏览器默认以何种方式渲染页面。比如说 360 浏览器。

举例:

代码语言:javascript
复制
<meta name="renderer" content="webkit"> //默认webkit内核
<meta name="renderer" content="ie-comp"> //默认IE兼容模式
<meta name="renderer" content="ie-stand"> //默认IE标准模式
6. http-equiv 属性

http-equiv 相当于 HTTP 的作用,比如说定义些 HTTP 参数啥的。

meta 标签中 http-equiv 属性语法格式是:

代码语言:javascript
复制
<meta http-equiv="参数" content="具体的描述">

其中 http-equiv 属性主要有以下几种参数:

A. content-Type(设定网页字符集)(推荐使用 HTML5 的方式)

说明:用于设定网页字符集,便于浏览器解析与渲染页面

举例:

代码语言:javascript
复制
<meta http-equiv="content-Type" content="text/html;charset=utf-8">  //旧的HTML,不推荐
<meta charset="utf-8"> //HTML5设定网页字符集的方式,推荐使用UTF-8
B. X-UA-Compatible(浏览器采取何种版本渲染当前页面)

说明:用于告知浏览器以何种版本来渲染页面。(一般都设置为最新模式,在各大框架中这个设置也很常见。)

举例:

代码语言:javascript
复制
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> //指定IE和Chrome使用最新版本渲染当前页面
C. cache-control(指定请求和响应遵循的缓存机制)

用法 1.

说明:指导浏览器如何缓存某个响应以及缓存多长时间。这一段内容我在网上找了很久,但都没有找到满意的。

最后终于在 Google Developers 中发现了我想要的答案。

举例:

代码语言:txt
复制
<meta http-equiv="cache-control" content="no-cache">

共有以下几种用法:

  • no-cache: 先发送请求,与服务器确认该资源是否被更改,如果未被更改,则使用缓存。
  • no-store: 不允许缓存,每次都要去服务器上,下载完整的响应。(安全措施)
  • public : 缓存所有响应,但并非必须。因为 max-age 也可以做到相同效果
  • private : 只为单个用户缓存,因此不允许任何中继进行缓存。(比如说 CDN 就不允许缓存 private 的响应)
  • maxage : 表示当前请求开始,该响应在多久内能被缓存和重用,而不去服务器重新请求。例如:max-age=60 表示响应可以再缓存和重用 60 秒。 参考链接:HTTP 缓存 用法 2.(禁止百度自动转码)

说明:用于禁止当前页面在移动端浏览时,被百度自动转码。虽然百度的本意是好的,但是转码效果很多时候却不尽人意。所以可以在 head 中加入例子中的那句话,就可以避免百度自动转码了。

举例:

代码语言:txt
复制
<meta http-equiv="Cache-Control" content="no-siteapp" />
D. expires(网页到期时间)

说明:用于设定网页的到期时间,过期后网页必须到服务器上重新传输。

举例:

代码语言:txt
复制
<meta http-equiv="expires" content="Sunday 26 October 2016 01:00 GMT" />
E. refresh(自动刷新并指向某页面)

说明:网页将在设定的时间内,自动刷新并调向设定的网址。

举例:

代码语言:txt
复制
<meta http-equiv="refresh" content="2;URL=http://www.lxxyx.win/"> //意思是2秒后跳转向我的博客
F. Set-Cookie(cookie 设定)

说明:如果网页过期。那么这个网页存在本地的 cookies 也会被自动删除。

代码语言:txt
复制
<meta http-equiv="Set-Cookie" content="name, date"> //格式
<meta http-equiv="Set-Cookie" content="User=Lxxyx; path=/; expires=Sunday, 10-Jan-16 10:00:00 GMT"> //具体范例

更详细更具体的 vue 学习文档访问

vue学习文档01

vue学习文档02

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、创建项目及配置
    • 1.1 vue cli2 创建项目
      • 1.2 vue cli3 创建项目
        • 2.1main.js 引入
    • 二、安装 element-UI
    • 三、安装 vuex
    • 四、配置scss环境
      • 4.4 在 vue 项目全局中引入 scss
        • 4.5 引入全局的 sass
        • 五、配置less环境
        • 六、引入font-awesome
        • 7、vue 配置网站的 ico
        • 八、引入自定义公共样式
          • 九、路由按需加载
            • 十、全局自定义方法
            • 十一、引入接口文件暴露到全局
              • style三元表达式
                • 计算属性computed
                  • computed
                  • 十四、style样式绑定
                    • style样式邦定
                    • 十五、vue组件参数传递:
                      • 15.1.子组件向父组件传递参数;
                        • 子组件 A:
                          • 子组件 B:
                            • 父组件:
                              • 15.2、父组件向子组件传递参数
                                • 15.3、非父子组件进行传值;
                                  • 16.vue脚手架配置预渲染,prerender-spa-plugin 配置
                                    • 十六、vue SPA单页面的 SEO 优化
                                    相关产品与服务
                                    内容分发网络 CDN
                                    内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档