vue init webpack project
複製代碼
npm install
複製代碼
npm run dev
複製代碼
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 測試。
複製代碼
進入到項目根目錄css
cd project
複製代碼
啓動項目html
npm run serve
複製代碼
npm i element-ui -S
複製代碼
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(Element)
複製代碼
首先,安裝 babel-plugin-componentvue
npm install babel-plugin-component -D
複製代碼
而後,將 .babelrc 修改成:java
{
"presets": [
["es2015", {
"modules": false
}]
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
複製代碼
接下來,若是你只但願引入部分組件,好比 Button 和 Select,那麼須要在 main.js 中寫入如下內容:node
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); 複製代碼
或寫爲webpack
- Vue.use(Button)
- Vue.use(Select)
複製代碼
npm i vuex -s
複製代碼
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 複製代碼
將 store 掛載到當前項目的 Vue 實例當中去ios
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) }) 複製代碼
<template>
<div id='app'>
name:
<h1>{{ $store.state.name }}</h1>
</div>
</template>
methods:{ add(){ console.log(this.\$store.state.name) } }, 複製代碼
更具體的學習文檔參考個人網站: 學習文檔git
npm install node-sass sass-loader --save-dev
複製代碼
{
test: /\.scss\$/,
loaders: ['style', 'css', 'sass']
}
複製代碼
github
<style lang='scss'>
複製代碼</style> 複製代碼
npm install sass-resources-loader --save-dev
複製代碼
將scss: generateLoaders('sass')
scss: generateLoaders('sass').concat({
loader: 'sass-resources-loader',
options: {
//你本身的 scss 全局文件的路徑
resources: path.resolve(\_\ _dirname, '../src/style/common.scss')
}
})
複製代碼
若是上面的不能正常編譯
//配置 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); } } 複製代碼
sass:generateSassResourceLoader(),//新加的
scss:generateSassResourceLoader(),//新加的
複製代碼
npm install --s node-sass sass-loader
複製代碼
1.首先你須要
npm install --s sass-resources-loader
複製代碼
2.在 build 目錄下找到 utils.js 文件
Module build failed: TypeError: this.getResolve is not a function at Object.loader 複製代碼
安裝 node-sass 運行報錯 vue 安裝 node-sass 編譯報錯 安裝node-scss報錯 安裝 node-scss 報錯
在搭建 vue 腳手架 或者是在 vue 項目中,想使用 sass 的功能,
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"的版本更換掉 就好了。
將 "sass-loader": "^8.0.0",更換成了 "sass-loader": "^7.3.1",
複製代碼
也能夠先卸載當前版本,而後安裝指定的版本
npm uninstall sass-loader
複製代碼
npm install sass-loader@7.3.1 --save-dev
複製代碼
npm install less less-loader --save
複製代碼
修改 webpack.base.config.js 文件,配置 loader 加載依賴,讓其支持外部的 less,在原來的代碼上添加
// 此種方法在控制檯中標籤樣式顯示的是style標籤樣式
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader",
}
複製代碼
// 能夠在控制檯中看到當前標籤樣式來自於哪一個less文件
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader",
options: {
sourceMap: true
}
}
複製代碼
在 vue 文件中的 style 標籤中添加 lang="less"便可在標籤中使用 less,或者外部引入 less
npm install font-awesome --save
複製代碼
而後在 main.js 引入 font-awesome/css/font-awesome.min.css 便可。
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
複製代碼
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 裏面引入公共樣式
import 'bootstrap/dist/css/bootstrap.css' //引入 bootstrap
import 'bootstrap-vue/dist/bootstrap-vue.css'
import '@/common/common.css'
import '@/common/index.css'
複製代碼
const port = () => import('@/pages/port') //入口頁面、
複製代碼
const router = new Router({
// mode: 'history',
routes: [
{
path: '/',
name: 'port',
component: resolve => require.ensure([], () => resolve(require('@/pages/port')), 'port'),
}]
})
複製代碼
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;
}
複製代碼
mounted: function() {
this.isMobile();
}
複製代碼
// 接口暴露在全局
import { server } from './config/api'
Vue.prototype.\$server = server;
複製代碼
//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: { getPageviews() { var that = this; let params = { pageId: that.pageId, pageUrl: that.pageUrl, }; that.\$server.getPageviews(params).then(response => {}) } } 複製代碼
import axios from 'axios';
axios.defaults.timeout = 5000; axios.defaults.baseURL =''; //填寫域名 //http request 攔截器 axios.interceptors.request.use( config => { config.data = JSON.stringify(config.data); config.headers = { 'Content-Type':'application/x-www-form-urlencoded' } return config; }, error => { return Promise.reject(err); } ); //響應攔截器即異常處理 axios.interceptors.response.use(response => { return response }, err => { if (err && err.response) { switch (err.response.status) { case 400: console.log('錯誤請求') break; case 401: console.log('未受權,請從新登陸') break; case 403: console.log('拒絕訪問') break; case 404: console.log('請求錯誤,未找到該資源') break; case 405: console.log('請求方法未容許') break; case 408: console.log('請求超時') break; case 500: console.log('服務器端出錯') break; case 501: console.log('網絡未實現') break; case 502: console.log('網絡錯誤') break; case 503: console.log('服務不可用') break; case 504: console.log('網絡超時') break; case 505: console.log('http版本不支持該請求') break; default: console.log(`鏈接錯誤${err.response.status}`) } } else { console.log('鏈接到服務器失敗') } return Promise.resolve(err.response) }) /** * 封裝get方法 * @param url * @param data * @returns {Promise} */ export function fetch(url,params={}){ return new Promise((resolve,reject) => { axios.get(url,{ params:params }) .then(response => { resolve(response.data); }) .catch(err => { reject(err) }) }) } /** * 封裝post請求 * @param url * @param data * @returns {Promise} */ export function post(url,data = {}){ return new Promise((resolve,reject) => { axios.post(url,data) .then(response => { resolve(response.data); },err => { reject(err) }) }) } /** * 官網接口請求封裝 * @param url * @param data * @returns {Promise} */ 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)//流量統計接口 } 複製代碼
原理:此方法使用的是 v-if 來控制 router-view 的顯示或隱藏,v-if 從 false 變爲 true 時,vue 會從新渲染 router-view 區域,因此當參數變化時,只需讓 v-if 從 true => false => true,就能實現頁面刷新。
//App.vue
<template> <div id="app"> <router-view v-if="isRouterAlive"/> </div> </template> <script> export default { name: 'App', provide() { return { reload: this.reload//調用reload方法 } }, data() { return { isRouterAlive: true//一開始router-view爲true } }, <span class="hljs-attr" style="line-height: 26px;">methods</span>: {
reload() {
<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">this</span>.isRouterAlive = <span class="hljs-literal" style="color: #008080; line-height: 26px;">false</span>
<span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">//在修改數據以後使用 $nextTick,則能夠在回調中獲取更新後的 DOM</span>
<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">this</span>.$nextTick(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-params" style="line-height: 26px;">()</span> =></span> {
<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">this</span>.isRouterAlive = <span class="hljs-literal" style="color: #008080; line-height: 26px;">true</span>
})
}
}
}
複製代碼
複製代碼<span class="hljs-attr" style="line-height: 26px;">methods</span>: {
reload() {
<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">this</span>.isRouterAlive = <span class="hljs-literal" style="color: #008080; line-height: 26px;">false</span>
<span class="hljs-comment" style="color: #998; font-style: italic; line-height: 26px;">//在修改數據以後使用 $nextTick,則能夠在回調中獲取更新後的 DOM</span>
<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">this</span>.$nextTick(<span class="hljs-function" style="line-height: 26px;"><span class="hljs-params" style="line-height: 26px;">()</span> =></span> {
<span class="hljs-keyword" style="color: #333; font-weight: bold; line-height: 26px;">this</span>.isRouterAlive = <span class="hljs-literal" style="color: #008080; line-height: 26px;">true</span>
})
}
}
}
複製代碼</script> 複製代碼
export default {
name: 'newproduct',
inject:['reload'],//在export default下面加上這一段
method:{
//調用App.vue下的this.reload()方法,來改變v-if的狀態
clickDiv(){//刷新按鈕調用的方法
this.reload()
}
}
複製代碼
參考文檔:如何實現 vue 中不跳轉不閃動頁面刷新?provide /inject 完美解決方案
:class="{ 'active': isActive }"
複製代碼
:class="{'active':isActive==-1}"
或者
:class="{'active':isActive==index}"
複製代碼
:class="{ 'active': isActive, 'sort': isSort }"
複製代碼
:class="classObject"
data() {
return {
classObject: {
active: true,
sort: false
}
}
}
複製代碼
:class="classObject"
data() {
return {
isActive: true,
isSort: false
}
},
computed: {
classObject: function() {
return {
active: this.isActive,
sort: this.isSort
}
}
}
複製代碼
:class="[isActive,isSort]"
複製代碼
data() {
return {
isActive: 'active',
isSort: 'sort'
}
}
複製代碼
數組與三元運算符結合判斷選擇須要的class 三元運算符後面的「:」兩邊的class須要加上單引號
:class="[isActive?'active':'']"
複製代碼
或者
:class="[isActive==1?'active':'']"
複製代碼
或者
:class="[isActive==index?'active':'']"
複製代碼
或者
:class="[isActive==index?'active':'otherActiveClass']"
複製代碼
//前面這個 active 在對象裏面能夠不加單引號,後面這個 sort 要加單引號
:class="[{ active: isActive }, 'sort']"
複製代碼
或者
:class="[{ active: isActive==1 }, 'sort']"
複製代碼
或者
:class="[{ active: isActive==index }, 'sort']"
複製代碼
應用於組件 若是直接在自定義組件中使用 class 或 :class,那麼樣式規則就會直接應在這個組件的根元素上。
<div id="app">
<text-component :class="{'isStrong':isStrong}"></text-component>
</div>
複製代碼
<script>
Vue.component('text-component', {
template: '<p class="content">不懂基因測序的學霸不是好的人工智能公司 CEO</p>'
});
var app = new Vue({
el: '#app',
data: {
isStrong: true
}
});
</script>
複製代碼
<span v-bind:style="{'display':config.isHaveSearch ? 'block':'none'}" >動態綁定樣式</span> 複製代碼
也可使用 v-bind:style 或 :style 直接給 HTML 元素綁定樣式,它也有對應的對象語法與數組語法。
<div id="app">
<div :style="border"></div>
</div>
複製代碼
<script>
var app = new Vue({
el: '#app',
data: {
border:{
border:'1px solid #00F',
textShadow:'0 0 .3em gray'
}
}
});
</script>
複製代碼
由於 JS 屬性不支持短橫分隔命名,因此咱們這裏使用 CSS 也支持的駝峯命名法。
<div id="app">
<p>原始字符串: {{ message }}</p>
<p>計算後反轉字符串: {{ reversedMessage }}</p>
</div>
複製代碼
<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 是所有渲染 區別:
computed 屬性默認只有 getter ,不過在須要時你也能夠提供一個 setter :
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]
}
}
}
})
複製代碼
// 調用 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 也會被對應更新。
class 與 style 是 HTML 元素的屬性,用於設置元素的樣式,咱們能夠用 v-bind 來設置樣式屬性。 Vue.js v-bind 在處理 class 和 style 時, 專門加強了它。表達式的結果類型除了字符串以外,還能夠是對象或數組。
咱們能夠爲 v-bind:class 設置一個對象,從而動態的切換 class:
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
</style>
複製代碼
<div id="app">
<div v-bind:class="{ active: isActive }"></div>
</div>
複製代碼
<script>
new Vue({
el: '#app',
data: {
isActive: true
}
})
</script> 複製代碼
例:text-danger 類背景顏色覆蓋了 active 類的背景色:
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
複製代碼
<div id="app">
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
</div>
複製代碼
<script>
new Vue({
el: '#app',
data: {
isActive: true,
hasError: true
}
})
</script> 複製代碼
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
複製代碼
<div id="app">
<div v-bind:class="classObject"></div>
</div>
複製代碼
<script>
new Vue({
el: '#app',
data: {
classObject: {
active: true,
'text-danger': true
}
}
})
</script> 複製代碼
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
複製代碼
<div id="app">
<div v-bind:class="classObject"></div>
</div>
複製代碼
<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> 複製代碼
<style>
.active {
width: 100px;
height: 100px;
background: green;
}
.text-danger {
background: red;
}
</style>
複製代碼
<div id="app">
<div v-bind:class="[activeClass, errorClass]"></div>
</div>
複製代碼
<script>
new Vue({
el: '#app',
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
})
</script> 複製代碼
還可使用三元表達式來切換列表中的 class : errorClass 是始終存在的,isActive 爲 true 時添加 activeClass 類:
<style>
.text-danger {
width: 100px;
height: 100px;
background: red;
}
.active {
width: 100px;
height: 100px;
background: green;
}
</style>
複製代碼
<div id="app">
<div v-bind:class="[errorClass ,isActive ? activeClass : '']"></div>
</div>
複製代碼
<script>
new Vue({
el: '#app',
data: {
isActive: true,
activeClass: 'active',
errorClass: 'text-danger'
}
})
</script> 複製代碼
v-bind:style直接設置樣式:
<div id="app">
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鳥教程</div>
</div>
複製代碼
<script>
new Vue({
el: '#app',
data: {
activeColor: 'green',
fontSize: 30
}
})
</script> 複製代碼
也能夠直接綁定到一個樣式對象:
<div id="app">
<div v-bind:style="styleObject">菜鳥教程</div>
</div>
複製代碼
<script>
new Vue({
el: '#app',
data: {
styleObject: {
color: 'green',
fontSize: '30px'
}
}
})
</script> 複製代碼
v-bind:style 可使用數組將多個樣式對象應用到一個元素上:
<div id="app">
<div v-bind:style="[baseStyles, overridingStyles]">菜鳥教程</div>
</div>
複製代碼
<script>
new Vue({
el: '#app',
data: {
baseStyles: {
color: 'green',
fontSize: '30px'
},
overridingStyles: {
'font-weight': 'bold'
}
}
})
</script> 複製代碼
Vue 組件間通訊包括:父子組件間通訊,兄弟組件間通訊以及模塊之間通訊等。Vue 是數據驅動視圖更新的框架, 因此對於 Vue 來講組件間的數據通訊很是重要。Vue 實現組件間通訊有不少方式,今天我來給你們講解一下父子組件間通訊:props 和$emit。
<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>
複製代碼
<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> 複製代碼
<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> 複製代碼
<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> 複製代碼
<template>
<div class="childB-wrapper"> 子組件B:{{sendBData}} </div>
</template>
<script> export default { data() { return {} }, created: function() {}, mounted() {}, methods: {}, props: { sendBData: String, required: true } } </script> 複製代碼
import Vue from 'vue'
export default new Vue()
複製代碼
<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> 複製代碼
##### 組件 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組件傳值方式
用到插件:cnpm install prerender-spa-plugin --save 腳手架 2.0:(本身的是 2.0)
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' // 可選;最好用 }) }), ] }) 複製代碼
mode:‘history’,
複製代碼
修改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')) } }) 複製代碼
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'
})
}),
],
};
}
}
複製代碼
new Vue({
router,
store,
render: h => h(App),
mounted() {
document.dispatchEvent(new Event('render-event'))
}
}).\$mount('#app')
複製代碼
其餘修改同 2.0;
vue-meta-info
複製代碼
官方地址: monkeyWangs/vue-meta-info
npm install vue-meta-info --save
複製代碼
import Vue from 'vue'
import MetaInfo from 'vue-meta-info'
Vue.use(MetaInfo) 複製代碼
<template>
...
</template> 複製代碼
<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> 複製代碼
<template>
...
</template> 複製代碼
<script>
export default {
name: 'async',
metaInfo () {
return {
title: this.pageName
}
},
data () {
return {
pageName: 'loading'
}
},
mounted () {
setTimeout(() => {
this.pageName = 'async'
}, 2000)
}
}
</script> 複製代碼
<meta name="參數" content="具體的描述">
複製代碼
<meta name="參數" content="具體的描述">
複製代碼
其中 name 屬性共有如下幾種參數。(A-C 爲經常使用屬性)
說明:用於告訴搜索引擎,你網頁的關鍵字。
<meta name="keywords" content="XX網,汽車,車主,評選">
複製代碼
說明:用於告訴搜索引擎,你網站的主要內容。
複製代碼
<meta name="description" content="汽車評選,XX網,評選,汽車">
複製代碼
說明:這個屬性經常使用於設計移動端網頁。
舉例
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
複製代碼
說明:robots 用來告訴爬蟲哪些頁面須要索引,哪些頁面不須要索引。
content 的參數有 all,none,index,noindex,follow,nofollow。默認是 all。
複製代碼
舉例:
<meta name="robots" content="none">
複製代碼
具體參數以下:
1.none : 搜索引擎將忽略此網頁,等價於 noindex,nofollow。
2.noindex : 搜索引擎不索引此網頁。
3.nofollow: 搜索引擎不繼續經過此網頁的連接索引搜索其它的網頁。
4.all : 搜索引擎將索引此網頁與繼續經過此網頁的連接索引,等價於 index,follow。
5.index : 搜索引擎索引此網頁。
6.follow : 搜索引擎繼續經過此網頁的連接索引搜索其它的網頁。
複製代碼
說明:用於標註網頁做者 舉例:
<meta name="author" content="Lxxyx,841380530@qq.com">
複製代碼
說明:用於標明網頁是什麼軟件作的 舉例: (不知道能不能這樣寫):
<meta name="generator" content="Sublime Text3">
複製代碼
說明:用於標註版權信息 舉例:
<meta name="copyright" content="Lxxyx"> //表明該網站爲Lxxyx我的版權全部。
複製代碼
說明:若是頁面不是常常更新,爲了減輕搜索引擎爬蟲對服務器帶來的壓力,能夠設置一個爬蟲的重訪時間。若是重訪時間太短,爬蟲將按它們定義的默認時間來訪問。 舉例:
<meta name="revisit-after" content="7 days" >
複製代碼
說明:renderer 是爲雙核瀏覽器準備的,用於指定雙核瀏覽器默認以何種方式渲染頁面。好比說 360 瀏覽器。 舉例:
<meta name="renderer" content="webkit"> //默認webkit內核
<meta name="renderer" content="ie-comp"> //默認IE兼容模式
<meta name="renderer" content="ie-stand"> //默認IE標準模式
複製代碼
http-equiv 至關於 HTTP 的做用,好比說定義些 HTTP 參數啥的。 meta 標籤中 http-equiv 屬性語法格式是:
<meta http-equiv="參數" content="具體的描述">
複製代碼
其中 http-equiv 屬性主要有如下幾種參數:
說明:用於設定網頁字符集,便於瀏覽器解析與渲染頁面 舉例:
<meta http-equiv="content-Type" content="text/html;charset=utf-8"> //舊的HTML,不推薦
<meta charset="utf-8"> //HTML5設定網頁字符集的方式,推薦使用UTF-8 複製代碼
說明:用於告知瀏覽器以何種版原本渲染頁面。(通常都設置爲最新模式,在各大框架中這個設置也很常見。) 舉例:
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> //指定IE和Chrome使用最新版本渲染當前頁面
複製代碼
用法 1.
說明:指導瀏覽器如何緩存某個響應以及緩存多長時間。這一段內容我在網上找了好久,但都沒有找到滿意的。 最後終於在 Google Developers 中發現了我想要的答案。
舉例:
<meta http-equiv="cache-control" content="no-cache">
複製代碼
共有如下幾種用法:
說明:用於禁止當前頁面在移動端瀏覽時,被百度自動轉碼。雖然百度的本意是好的,可是轉碼效果不少時候卻不盡人意。因此能夠在 head 中加入例子中的那句話,就能夠避免百度自動轉碼了。 舉例:
<meta http-equiv="Cache-Control" content="no-siteapp" />
複製代碼
說明:用於設定網頁的到期時間,過時後網頁必須到服務器上從新傳輸。 舉例:
<meta http-equiv="expires" content="Sunday 26 October 2016 01:00 GMT" />
複製代碼
說明:網頁將在設定的時間內,自動刷新並調向設定的網址。 舉例:
<meta http-equiv="refresh" content="2;URL=http://www.lxxyx.win/"> //意思是2秒後跳轉向個人博客
複製代碼
說明:若是網頁過時。那麼這個網頁存在本地的 cookies 也會被自動刪除。
<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"> //具體範例
複製代碼