vue相關的知識

1. 組件的data為什么必須是函數(shù)巷疼?

組件中的 data 寫成一個函數(shù)抱婉,數(shù)據(jù)以函數(shù)返回值形式定義寻拂,這樣每復用一次組件,就會返回一份新的 data 逢艘,類似于給每個組件實例創(chuàng)建一個私有的數(shù)據(jù)空間旦袋,讓各個組件實例維護各自的數(shù)據(jù)。而單純的寫成對象形式它改,就使得所有組件實例共用了一份data疤孕,就會造成一個組件的值發(fā)生改變,全部組件都會變的結果央拖。

這樣的好處就是每各個組件可以維護各自的數(shù)據(jù)祭阀,如果 data 是一個對象則會影響到其他組件鹉戚。
2. 問 v-if 和 v-show 有什么區(qū)別?

相同點:v-if與v-show都可以動態(tài)控制dom元素顯示隱藏

不同點:v-if隱藏是將dom元素整個刪除,而v-show隱藏則是為該元素添加css--display:none专控,dom元素還在抹凳。

3. vue幾種常用的指令

v-text:元素的innerText屬性(不帶標簽)
v-html:元素的innerHTML屬性(帶標簽)
v-bind:綁定屬性
v-on:綁定事件,綁定的事件從methods中獲取

事件修飾符
.stop:阻止冒泡伦腐,調(diào)用 event.stopPropagation()
.prevent:阻止默認事件赢底,調(diào)用 event.preventDefault()
.capture:添加事件偵聽器時使用事件捕獲模式

v-model
作用:在表單元素上創(chuàng)建雙向數(shù)據(jù)綁定
說明:監(jiān)聽用戶的輸入事件以更新數(shù)據(jù)

所謂的雙向綁定,就是你在view視圖層里面改變了值柏蘑,vue里面對應的值也會改變幸冻。只能給具備value屬性的元素進行雙向數(shù)據(jù)綁定。

v-if 和 v-show
條件渲染
v-if:根據(jù)表達式的值的真假條件咳焚,銷毀或重建DOM元素
v-show:根據(jù)表達式之真假值洽损,切換元素的 display: block/none 屬性

v-for
作用:基于源數(shù)據(jù)多次渲染元素或模板塊,使用 v-for 的時候提供 key 屬性革半,可以提高列表渲染的效率趁啸,提高頁面的性能。

v-once 提升性能
說明:只渲染元素和組件一次督惰。隨后的重新渲染,元素/組件及其所有的子節(jié)點將被視為靜態(tài)內(nèi)容并跳過旅掂。這可以用于優(yōu)化更新性能赏胚。

4. 對于Vue是一套漸進式框架的理解

Vue.js是一個漸進式框架,只需要具備基本的HTML/CSS/JavaScript基礎就可以快速上手商虐。在用Vue.js構建大型應用時推薦使用NPM安裝觉阅,但是需要注意npm的版本需要大于3.0。

在通過npm安裝項目后秘车,我們需要對其目錄進行解析:
(1) build:項目構建(webpack)相關代碼;
(2) config:配置目錄典勇,包括端口號等。
(3) node_modules:npm加載的項目依賴模塊
(4) src:這個目錄當中的內(nèi)容包含了我們基本上要做的事情叮趴,這里包含了幾個文件:
(一)assets:存放圖片
(二)components:存放組件文件
(三)App.vue:項目入口文件割笙,組件也可以直接寫在這里不適用components
(四)main.js:核心文件
(5) static:靜態(tài)資源目錄
(6) test:初始測試目錄
(7) .xxxx:配置文件,包括git配置和語法配置等
(8) index.html:首頁
(9) package.json:項目配置文件
(10) README.md:說明文檔

Vue的mvvm框架給了前端一種思路:完全基于數(shù)據(jù)驅動眯亦,幫助你從繁雜的dom操作中解脫出來

使用Vue的過程就是定義MVVM各個組成部分過程的過程:
(1) 定義View
(2) 定義Model
(3) 創(chuàng)建一個Vue實例或“ViewModel”

在創(chuàng)建Vue實例的時候伤溉,需要傳入選項對象,可以包含掛載元素妻率、數(shù)據(jù)等乱顾。

Vue實例被創(chuàng)建前會經(jīng)過初始化,然后在數(shù)據(jù)變化時更新DOM宫静,在這個期間也會調(diào)用一些生命周期鉤子走净,從而我們可以自定義邏輯券时。總共可以分為8個段:

(1) beforeCreate 初始化實例后 數(shù)據(jù)觀測和事件配置之前調(diào)用
(2) created 實例創(chuàng)建完成后調(diào)用
(3) beforeMount 掛載開始前被用
(4) mounted el被新建vm.$el替換并掛在到實例上之后調(diào)用
(5) beforeUpdate 數(shù)據(jù)更新時調(diào)用
(6) updated 數(shù)據(jù)更改導致的DOM重新渲染后調(diào)用
(7) beforeDestory 實例被銷毀前調(diào)用
(8) destoryed 實例銷毀后調(diào)用

需要注意的是created和mounted的區(qū)別伏伯,created是實例已經(jīng)創(chuàng)建但未掛載骄崩,所以一些dom操作要放在mounted中。

Vue組件的API來自props(允許外部環(huán)境傳遞數(shù)據(jù)給組件)屈扎、events(允許組件觸發(fā)外部環(huán)境副作用)和slots(允許外部環(huán)境將額外的內(nèi)容組合在組件中)三個部分狡孔,組件的data屬性必須是函數(shù)。

漸進的理解:vue只是個輕量視圖而已蜓堕,只做自己該做的事抛虏,不做不該做的事。

5. vue中使用 v-for 時套才,綁定key的作用

可以提高列表渲染的效率迂猴,提升頁面的性能。

6. v-for 與 v-if 的優(yōu)先級

當 v-if 與 v-for 一起使用時背伴,v-for 具有比 v-if 更高的優(yōu)先級沸毁,這意味著 v-if 將分別重復運行于每個 v-for 循環(huán)中,所以傻寂,不推薦v-if和v-for同時使用息尺。

7. axios 解決跨域問題

一、使用腳手架創(chuàng)建好項目
全局安裝 vue-cli
npm install --global vue-cli
創(chuàng)建一個基于 webpack 模板的新項目
vue init webpack vue-demo
進入項目疾掰,安裝依賴搂誉,啟動項目
cd vue-demo
npm install
npm run dev
二、安裝axios静檬,并配置相應文件炭懊。這里跨域請求的接口來自豆瓣的api
安裝 npm install axios --save
配置:
1、在 src/main.js 中引入使用
import axios from 'axios';
Vue.prototype.$axios=axios;
2拂檩、在 config/index.js 中的 的dev 添加以下代碼侮腹,設置一下proxyTable;

proxyTable:{
    '/api': {
          target : 'https://movie.douban.com/',    //設置你調(diào)用的接口域名和端口號.別忘了加http
          changeOrigin : true,   //允許跨域
          pathRewrite : {
               '^/api': ''
               // '/'這里理解成用‘/api’代替target里面的地址稻励,后面組件中我們掉接口時直接用api代替父阻。比如我要調(diào)用'https://movie.douban.com/v2/movie/top250',直接寫‘/api/v2/movie/top250’即可.
          }
    }
},

3钉迷、在 config/dev.env.js 中設置以下代碼

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',  //開發(fā)環(huán)境
  API_HOST: "/api/"
})

4至非、在 config/prod.env.js 中設置以下代碼

module.exports = {
  NODE_ENV: '"production"',//生產(chǎn)環(huán)境
  API_HOST: '"https://movie.douban.com/"'
}

5、修改 src/components/HelloWorld.vue 文件

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <ul>
      <li v-for="item in movieArr">
        <span>{{item.title}}</span>
      </li>
    </ul>
    <button @click="sayOut">渲染</button>
  </div>
</template>

<script>
import axios from 'axios';
export default {
  name: 'HelloWorld',
  data() {
    return {
      msg: '調(diào)用豆瓣api',
      movieArr : []
    }
  },
  methods:{
    sayOut () {
      this.$axios.get('/').then((res) => {
        console.log(res)
        if (res.status == 200){
          console.log(res.data)
          // this.movieArr = res.data.subjects
        }
        // 這里要強調(diào)一下這個 this 箭頭函數(shù)指的是它的父級也就是vue實例  然后不用箭頭函數(shù)的話 this是一個undefined糠聪,無法給movieArr來賦值荒椭。
      })
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
</style>

到此 axios 跨域成功解決。

8. axios 封裝http請求
  1. 在main.js 中引入
import axios from 'axios'
import {get, post, patch, put} from './config/http'
// 定義全局變量
Vue.prototype.$get=get;
Vue.prototype.$post=post;
Vue.prototype.$patch=patch;
Vue.prototype.$put=put;

2.src目錄下創(chuàng)建config文件夾舰蟆,config文件夾創(chuàng)建http.js

import axios from 'axios';

axios.defaults.timeout = 5000;
axios.defaults.baseURL ='';


//http request 攔截器
axios.interceptors.request.use(
  config => {
    // const token = getCookie('名稱');注意使用的時候需要引入cookie方法趣惠,推薦js-cookie
    config.data = JSON.stringify(config.data);
    config.headers = {
      'Content-Type':'application/json;charset=UTF-8'         // 處理json
      // 'Content-Type':'application/x-www-form-urlencoded'   // 處理hash
    }
    // if(token){
    //   config.params = {'token':token}
    // }
    return config;
  },
  error => {
    return Promise.reject(err);
  }
);


//http response 攔截器
axios.interceptors.response.use(
  response => {
    if(response.data.errCode ==2){
      router.push({
        path:"/login",
        querry:{redirect:router.currentRoute.fullPath}//從哪個頁面跳轉
      })
    }
    return response;
  },
  error => {
    return Promise.reject(error)
  }
)


/**
 * 封裝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)
          })
   })
 }

 /**
 * 封裝patch請求
 * @param url
 * @param data
 * @returns {Promise}
 */

export function patch(url,data = {}){
  return new Promise((resolve,reject) => {
    axios.patch(url,data)
         .then(response => {
           resolve(response.data);
         },err => {
           reject(err)
         })
  })
}

 /**
 * 封裝put請求
 * @param url
 * @param data
 * @returns {Promise}
 */

export function put(url,data = {}){
  return new Promise((resolve,reject) => {
    axios.put(url,data)
         .then(response => {
           resolve(response.data);
         },err => {
           reject(err)
         })
  })
}
  1. 在項目的 config/index.js 解決跨域請求
proxyTable: {
    '/apis': {
        // target: 'http://39.105.189.51:8052',
        target: 'http://api.edgvip.cn',
        changeOrigin: true,
        pathRewrite: {
          '^/apis': ''
        }
    }
},
  1. 組件中引入使用
    eg: 接口文檔為下圖


    image.png
methods: {
    login() {
      this.$post('apis/api/user/login1',{mobilePhone: this.mobilePhone, password: this.password}).then((res) => {
        // console.log(res)
        if(res.rs == 1){
          this.$toast(res.info);
          this.$router.push('/home');  // 路由跳轉
        }else{
          this.$toast(res.info); 
        }
      })
    },
  },

此時狸棍,完成axios的封裝。

9. vue 實現(xiàn)tab切換

其實就是路由的使用

  1. src下創(chuàng)建router文件夾味悄,內(nèi)部包含index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import News from '@/components/News'

Vue.use(Router)

export default new Router({
  routes: [
        {
            path: '/',
            component: Home
        },
        {
            path: '/home',
            name: 'Home',
            component: Home
        },
        {
            path: '/news',
            name: 'News',
            component: News
        }
    ]
})
  1. 在main.js 中引入router
import router from './router'

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
  1. 在App.vue中使用
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div>
      <router-link to="/home">主頁</router-link>
      <router-link to="/news">新聞</router-link>
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style scoped>
</style>
10. 如何配置 vue 打包生成文件的路徑草戈?
  1. 將 config.js 文件下index.js中的assersPublishPath,改為‘./’
build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
 // 將 build 中的 assetsPublicPath 改為 './'侍瑟, 修改dev唐片,無效
    assetsPublicPath: './',

    /**
     * Source Maps
     */

    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // 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
    productionGzip: false,
    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
    bundleAnalyzerReport: process.env.npm_config_report
  }
  1. 將build/utils.js 加入 publicPath: '../../'
// Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader',  
        // 在 utils.js 的此處加上下面代碼,即可
        publicPath: '../../'
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
11. vue如何適配移動端涨颜?

在 main.js 引入 rem.js

import './config/rem'

rem.js 代碼如下:

window.onload = function() {
    getRem(750, 100);
}

window.onresize = function() {
    getRem(750, 100);
}

function getRem(pwidth, prem) {
    var html = document.documentElement;
    var oWidth = document.body.clientWidth || document.documentElement.clientWidth;
    html.style.fontSize = oWidth/pwidth*prem + 'px';
}
12. vue如何優(yōu)化首屏加載速度费韭?
  1. 使用CDN資源,減小服務器帶寬壓力庭瑰;
  2. 將靜態(tài)js css放到其他地方(如OSS)星持,減小服務器壓力;
  3. 按需加載第三方UI資源弹灭;
  4. 服務端開啟gzip督暂,減小網(wǎng)絡傳輸?shù)牧髁看笮。?/li>
  5. 按照頁面或者組件分塊懶加載
13. vue.js的兩個核心思想

數(shù)據(jù)驅動 和 組件系統(tǒng)

14. vue數(shù)據(jù)的雙向綁定

在vue.js里面只需要改變數(shù)據(jù)穷吮,Vue.js通過directives指令去操作DOM元素逻翁,當數(shù)據(jù)發(fā)生變化,會通知指令去修改對應的DOM捡鱼,數(shù)據(jù)的變化驅動DOM的變化卢未,DOM是數(shù)據(jù)的一種映射。vue.js還會對DOM做一些監(jiān)聽(DOM Listener)堰汉,當我們修改視圖的時候,vue.js監(jiān)聽到這些變化伟墙,從而改變數(shù)據(jù)翘鸭。這樣就形成了數(shù)據(jù)的雙向綁定。

15. MVVM框架的理解

MVVM 由 Model戳葵、View就乓、ViewModel 三部分構成,Model 代表數(shù)據(jù)層拱烁;View 代表視圖層生蚁,它負責將數(shù)據(jù)模型轉化成UI 展現(xiàn)出來;ViewModel 是一個同步View 和 Model的實例對象戏自。

【model模型】指的是后端傳遞的數(shù)據(jù)邦投。【view視圖】指的是所看到的頁面擅笔≈疽拢【viewmodel視圖模型】是mvvm模式的核心屯援,它是連接view和model的橋梁。它有兩個方向:一是將【模型】轉化成【視圖】念脯,即將后端傳遞的數(shù)據(jù)轉化成所看到的頁面狞洋。實現(xiàn)的方式是:數(shù)據(jù)綁定。二是將【視圖】轉化成【模型】绿店,即將所看到的頁面轉化成后端的數(shù)據(jù)吉懊。實現(xiàn)的方式是:DOM 事件監(jiān)聽。這兩個方向都實現(xiàn)的假勿,我們稱之為數(shù)據(jù)的雙向綁定借嗽。

在MVVM模式下,View 和 Model 之間并沒有直接的聯(lián)系废登,而是通過ViewModel進行交互淹魄,Model 和 ViewModel 之間的交互是雙向的, 因此View 數(shù)據(jù)的變化會同步到Model中堡距,而Model 數(shù)據(jù)的變化也會立即反應到View 上甲锡。


image.png
15. 自定義指令和自定義過濾器

自定義指令

自定義指令的參數(shù)有:
el: 指令所綁定的元素,可以用來直接操作 DOM 羽戒。
binding: 一個對象缤沦,包含以下屬性:
name: 指令名,不包括 v- 前綴易稠。
value: 指令的綁定值缸废, 例如: v-my-directive="1 + 1", value 的值是 2。
oldValue: 指令綁定的前一個值驶社,僅在 update 和 componentUpdated 鉤子中可用企量。無論值是否改變都可用。
expression: 綁定值的字符串形式亡电。 例如 v-my-directive="1 + 1" 届巩, expression 的值是 "1 + 1"。
arg: 傳給指令的參數(shù)份乒。例如 v-my-directive:foo恕汇, arg 的值是 "foo"。
modifiers: 一個包含修飾符的對象或辖。 例如: v-my-directive.foo.bar, 修飾符對象 modifiers 的值是 { foo: true, bar: true }瘾英。

eg:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>自定義指令</title>
    <script src="https://cdn.bootcss.com/vue/2.6.6/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <div class="box" v-pos:red.left.top="true">自定義指令,背景色為紅色颂暇,固定在左上角</div>
        <div class="box" v-pos.right.bottom="true">自定義指令缺谴,固定在右下角</div>
    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {

        },
        directives: {
            pos (el, binding){
                console.log(el, binding);
                // 修飾符 .left.top
                var position = binding.modifiers;
                // position = {left: true, top: true}
                // 綁定的參數(shù) :red
                var color = binding.arg;
                if (binding.value){
                    el.style.position = 'fixed';
                    el.style.background = color;
                    for(let val in position){
                        el.style[val] = '10px'
                    } 
                }
            }
        }
    })
</script>
</html>

自定義過濾器

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>自定義指令</title>
    <script src="https://cdn.bootcss.com/vue/2.6.6/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <div><span>{{length}}m</span>=<span>{{length | meter("cm")}}</span></div>
        <div>{{price | myCurrency('$')}}</div>
    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            length: 1,
            price: 120
        },
        filters: {
            meter (val, unit){
                console.log(val, unit);
                return val*100 + unit
            },
            myCurrency(val, unit) {
                console.log(val, unit);
                return unit + val
            }
        }
    })
</script>
</html>
16. vue-cli 工程常用的 npm 命令有哪些?

下載 node_modules 資源包的命令:

npm install

// 安裝模塊耳鸯;
// -save-dev(-D) 是指將包信息添加到 package.json 里的 devDependencies節(jié)點瓣赂,表示開發(fā)時依賴的包榆骚。
npm install 模塊名 --save-dev(-D)

// -save(-S) 是指將包信息添加到 package.json 里的dependencies節(jié)點,表示發(fā)布時依賴的包煌集。
npm install 模塊名 --save(-S)

啟動 vue-cli 開發(fā)環(huán)境的 npm命令:

npm run dev 

vue-cli 生成 生產(chǎn)環(huán)境部署資源 的 npm命令:

npm run build 

用于查看 vue-cli 生產(chǎn)環(huán)境部署資源文件大小的 npm命令:

npm run build --report
17. vue常用的修飾符
<!-- 阻止單擊事件繼續(xù)傳播(阻止冒泡)-->
<div onclick="alert(2)">
    <button class="btn" onclick="someEvents()">按鈕</button>
</div>
<script>
    function someEvents(event) {
        alert(1);
        var event = event || window.event;
        event.stopPropagation();
    }
</script>
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重載頁面 (默認事件) -->
//  event.preventDefault();  //取消默認事件
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修飾符可以串聯(lián) -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件監(jiān)聽器時使用事件捕獲模式 -->
<!-- 即元素自身觸發(fā)的事件先在此處處理妓肢,然后才交由內(nèi)部元素進行處理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只當在 event.target 是當前元素自身時觸發(fā)處理函數(shù) -->
<!-- 即事件不是從內(nèi)部元素觸發(fā)的 -->
<div v-on:click.self="doThat">...</div>

<!-- 在默認情況下,v-model 在每次 input 事件觸發(fā)后將輸入框的值與數(shù)據(jù)進行同步 苫纤。-->
<input v-model.lazy="msg" >

<!-- 自動將用戶的輸入值轉為數(shù)值類型碉钠,可以給 v-model 添加 number 修飾符 -->
<input v-model.number="num" >

<!-- 自動過濾用戶輸入的首尾空格 -->
<input v-model.trim="msg" />
18. vue事件中如何使用event對象?
<div>
    <button id="btn" @click="click">click me</button>
    <button @click="click()">click you</button>
    <button @click="click($event)">click us</button><br/>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        methods: {
            click() {
                // 獲取當前 DOM 元素
                var el = event.currentTarget;
                // docuemnt.getElementById('btn') == event.currentTarget;
                console.log(el.innerHTML);
            }
        }
    })
</script>

// 三種寫法
1.  DOM 事件 click 上卷拘,不加()喊废,methods 方法中 click,可加可不加 event栗弟;
2.  DOM 事件 click 上污筷,加(),methods 方法中 click乍赫,不能加 event瓣蛀;
3.  DOM 事件 click 上,加($event)雷厂,并傳入 $event惋增,methods 方法中 click,可加可不加 event改鲫;
19. nextTick的使用
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>nextTick</title>
    <script src="https://cdn.bootcss.com/vue/2.6.6/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <p ref="txt" id="p1" v-if="show">{{message}}</p>
        <p>{{msg}}</p>
        <button @click="getTxt">點擊</button>
    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            show: true,
            message: '原文本',
            msg: ''
        },
        methods: {
            getTxt () {
                this.show = true;
                // 箭頭函數(shù)寫法
                this.$nextTick(() => {
                    console.log(this.$refs.txt);                // <p id="p1">原文本</p>
                    console.log(document.getElementById('p1')); // <p id="p1">原文本</p>               
                    this.msg = this.$refs.txt.innerHTML +' + '+ '新文本內(nèi)容';
                    console.log('原文本內(nèi)容:', this.$refs.txt.innerHTML);
                })
                // this異步綁定 .bind(this)
                // this.$nextTick().then(function() {
                //  this.msg = this.$refs.txt.innerHTML +' + '+ '新文本內(nèi)容';
                //      console.log('原始文本內(nèi)容:', this.$refs.txt.innerHTML);
                // }.bind(this));
            }
        }
    })
</script>
</html>

解析:使用v-show進行顯示隱藏诈皿,methods里面是直接可以獲取到文本值,如果用v-if像棘,是不能獲取的文本值的稽亏。

this.$nextTick的作用是在下次dom更新循環(huán)完成之后進行調(diào)用
ref 被用來給元素或子組件注冊引用信息。引用信息將會注冊在父組件的 $refs 對象上缕题。

元素上綁定 ref (eg: ref='txt') 屬性措左,獲取該元素使用 this.$refs.txt 即可。也可使用事件(event)獲取當前元素(var el = event.currentTarget)避除。

20. vue中 keep-alive 組件的作用
<!-- App.vue -->
<template>
  <div id="app">
      <router-link to="/home">主頁</router-link>
      <router-link to="/news">新聞</router-link>
      
      <keep-alive include="keep_alive">
          <router-view v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
      <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {
      include: "keep_alive"
    }
  }
}
</script>

<!-- 哪個組件需要緩存 該組件 name 就需要綁定App.vue的 include 屬性,并在 routes 上綁定 meta: { keepAlive: true } -->
<!-- // true表示需要使用緩存  false表示不需要被緩存 -->
<!-- Home.vue -->
<template>
    <div id="home">
        <input type="text" placeholder="" name="">
    </div>
</template>
<script>
    export default {
        // 此時綁定的 name 是 App.vue 的 include 屬性值
        name: 'keep_alive',
        data() {
            return {}
        }
    }
</script>


<!-- News.vue -->
<template>
    <div id="news">
        <input placeholder="輸入框"></input>
    </div>
</template>
<script>
    export default {
        // 同 Home
        name: 'keep_alive',
        data() {
            return {}
        }
    }
</script>
<style scoped>
    
</style>

<!-- router/index.js -->
<script>
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import News from '@/components/News'
Vue.use(Router)
var routes = [
    {
        path: '/',
        component: Home
    },
    {
        path: '/home',
        name: 'Home',
        component: Home,
        meta: {
            keepAlive: true  // true表示需要使用緩存  false表示不需要被緩存
        }
    },
    {
        path: '/news',
        name: 'News',
        component: News,
        meta: {
            keepAlive: true
        }
    }
]
export default new Router({routes})
</script>

說明: 
(1) 在Home頁面輸入框輸入“home”胸嘁,然后通過路由跳轉到News頁面瓶摆;
(2) 回到Home頁面發(fā)現(xiàn) input 之前輸入的"home"依然保留,說明頁面信息成功保存在內(nèi)存中性宏;

keep-alive的作用:keep-alive 是Vue的內(nèi)置組件群井,能在組件切換過程中將狀態(tài)保留在內(nèi)存中,防止重復渲染DOM毫胜。

keep-alive的屬性:
include: 字符串或正則表達式书斜。只有匹配的組件會被緩存诬辈。
exclude: 字符串或正則表達式。任何匹配的組件都不會被緩存荐吉。

21. vue等單頁面應用及其優(yōu)缺點

優(yōu)點:

Vue 的目標是通過盡可能簡單的 API 實現(xiàn)響應的數(shù)據(jù)綁定和組合的視圖組件焙糟,核心是一個響應的數(shù)據(jù)綁定系統(tǒng)。MVVM样屠、數(shù)據(jù)驅動穿撮、組件化、輕量痪欲、簡潔悦穿、高效、快速业踢、模塊友好栗柒。

1、具有桌面應用的即時性知举、網(wǎng)站的可移植性和可訪問性瞬沦。
2、用戶體驗好负蠕、快,內(nèi)容的改變不需要重新加載整個頁面。
3屡江、基于上面一點赛不,SPA相對對服務器壓力小文黎。
4、良好的前后端分離。SPA和RESTful架構一起使用业汰,后端不再負責模板渲染、輸出頁面工作氛濒,web前端和各種移動終端地位對等窿冯,后端API通用化。
5仰挣、同一套后端程序代碼洲愤,不用修改就可以用于Web界面、手機州藕、平板等多種客戶端;

缺點:

不支持低版本的瀏覽器馅精,最低只支持到IE9茄蚯;
不利于SEO的優(yōu)化(如果要支持SEO,建議通過服務端來進行渲染組件);
第一次加載首頁耗時相對長一些;
不可以使用瀏覽器的導航按鈕都办,需自行實現(xiàn)前進、后退歼培。

22. vue中子組件調(diào)用父組件的方法

Vue中子組件調(diào)用父組件的方法震蒋,這里有三種方法提供參考

第一種方法是直接在子組件中通過this.$parent.event來調(diào)用父組件的方法

<!-- App.vue -->
<template>
  <div id="app">
    <Child />
  </div>
</template>
<script>
import Child from '@/components/Child'
export default {
  name: 'App',
  components: {
    Child
  },
  methods: {
    fatherMethod() {
      console.log('測試');
    }
}
</script>
<!-- Child.vue -->
<template>
    <div id="child">
        <button @click="childMethod()">點擊</button>
    </div>
</template>
<script>
    export default {
        name: 'child',
        data() {
            return {
                msg: '子組件child'
            }
        },
        methods: {
            childMethod() {
                this.$parent.fatherMethod()
            }
        }
    }
</script>

第二種方法是在子組件里用$emit向父組件觸發(fā)一個事件查剖,父組件監(jiān)聽這個事件就行了菌仁。

<!-- App.vue -->
<template>
  <div id="app">
    <Child @fatherMethod="fatherMethod" />
  </div>
</template>
<script>
import Child from '@/components/Child'
export default {
  name: 'App',
  components: {
    Child
  },
  methods: {
    fatherMethod() {
      console.log('測試');
    }
}
</script>
<!-- Child.vue -->
<template>
    <div id="child">
        <button @click="childMethod()">點擊</button>
    </div>
</template>
<script>
    export default {
        name: 'child',
        data() {
            return {
                msg: '子組件child'
            }
        },
        methods: {
            childMethod() {
                this.$emit('fatherMethod');
            }
        }
    }
</script>

第三種是父組件把方法傳入子組件中峡碉,在子組件里直接調(diào)用這個方法

<!-- App.vue -->
<template>
  <div id="app">
    <Child :fatherMethod="fatherMethod" />
  </div>
</template>
<script>
import Child from '@/components/Child'
export default {
  name: 'App',
  components: {
    Child
  },
  methods: {
    fatherMethod() {
      console.log('測試');
    }
}
</script>
<!-- Child.vue -->
<template>
    <div id="child">
        <button @click="childMethod()">點擊</button>
    </div>
</template>
<script>
    export default {
        name: 'child',
        data() {
            return {
                msg: '子組件child'
            }
        },
        props: {
            fatherMethod: Function,
            default: null
        },
        methods: {
            childMethod() {
                if (this.fatherMethod){
                    this.fatherMethod();
                }
            }
        }
    }
</script>
23. package.json的文件解析

name:項目名稱
version:項目版本號
description:描述信息,有助于搜索
scripts:支持的腳本头岔,默認是一個空的 test
private:公有私有
keywords:關鍵字塔拳,有助于在人們使用 npm search 搜索時發(fā)現(xiàn)你的項目
author:作者信息
license:證書信息(默認是 MIT)
dependencies:在生產(chǎn)環(huán)境中需要用到的依賴
devDependencies:在開發(fā)環(huán)境中用到的依賴,上線打包后的代碼是不存在的
engines:node和npm的版本要求
browserslist:瀏覽器要求

24. vue 全局變量和函數(shù)的使用
  1. 首先在src下創(chuàng)建global文件夾峡竣,創(chuàng)建global_data.js
const url = 'http://www.baicu.com'
const name = 'zhangsan'

// 暴露變量
export default {
  url,
  name
}
//或者
// module.exports = {
//  url,
//  name
// }
  1. 引用(局部引用靠抑,全局引用)
// 全局變量的局部全局引入
// App.vue引用   哪個頁面需要哪個頁面引入(局部)
import GLOBAL from '@/global/global_data'
export default {
  name: 'App',
  data() {
    return {
      url: GLOBAL.url,
    }
  }
}

// main.js 引入 (全局)
import globalData from '@/global/global_data'
// 掛載vue原型
Vue.prototype.GLOBAL = globalData 

// App.vue 使用
export default {
  name: 'App',
  data() {
    return {
      url: this.GLOBAL.url,
    }
  }
}

// 全局函數(shù)的引入
// 第一種方法
// main.js 直接綁定
Vue.prototype.global_fun1 = function() {
  return console.log('fun1');
}
// App.vue 頁面輸出
export default {
  name: 'App',
  mounted() {
    this.global_fun1();   // 打印 fun1
  }
}

// 第二種方法
// global/新建global_fun.js
import Vue from 'vue'
function fun11(params){
  console.log(params);
}
export default {
  Vue.prototype.global_fun11 = (params) => fun11(params);
}
// next main.js 引入
import globalFun from '@/global/global_fun'
Vue.use(globalFun);
// App.vue 使用
export default {
  name: 'App',
  mounted() {
    this.global_fun11('zhangsan');   // 打印 zhangsan
  }
}
25. vue彈出窗口之后禁止頁面滑動

先阻止默認時間,然后給body添加overflow:hidden;

export default {
  methods: {
    stop() {
      var stop = function(event) {
        event.preventDefault();
      }
      document.body.style.overflow = 'hidden';
      document.addEventListener('touchmove', stop, false);  // 禁止頁面滑動
    }
    move() {
      var move = function(event) {
        event.preventDefault();
      };
      document.body.style.overflow = '';  //出現(xiàn)滾動條
      document.removeEventListener("touchmove", move, false); //開啟頁面滑動
    }
  }
}
26. v-for產(chǎn)生的列表适掰,實現(xiàn)active的切換颂碧?
<template>
  <ul>
    <li v-for="(item, index) in movieArr" @click="curIndex = index" :class="{actived: index == curIndex}">
        <span>{{item}}</span>
    </li>
  </ul>
</template>
<script>
export default {
  name: 'App',
  data() {
    curIndex: 0,
    movieArr: ['三國', '大人物', '無雙']
  }
}
</script>
<style>
.actived {
  color: red;
}
</style>
27. vue實現(xiàn)路由懶加載

懶加載:也叫延遲加載,即在需要的時候進行加載类浪,隨用隨載载城。
為什么需要使用懶加載?

像vue這種單頁面應用费就,如果不應用懶加載诉瓦,運用 webpack 打包后的文件將會異常的大,造成進入首頁時力细,需要加載的內(nèi)容過多睬澡,時間過長,會出現(xiàn)長時間的白屏眠蚂,即使做了loading也是不利于用戶體驗煞聪,而運用懶加載則可以將頁面進行劃分,需要的時候加載頁面逝慧,可以有效的分擔首頁所承擔的加載壓力昔脯,減少首頁加載用時

不使用懶加載的路由配置:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/Home'
import News from '@/components/News'

Vue.use(Router)

export default new Router({
    routes: [
        {
            path: '/',
            component: Home
        },
        {
            path: '/helloworld',
            name: 'HelloWorld',
            component: HelloWorld,
            meta: {
                keepAlive: true
            }
        },
        {
            path: '/home',
            name: 'Home',
            component: Home,
            // 組件切換時啄糙,將狀態(tài)保存在內(nèi)存中,防止重復渲染
            meta: {
                keepAlive: true  // true表示需要使用緩存  false表示不需要被緩存
            }
        },
        {
            path: '/news',
            name: 'News',
            component: News,
            meta: {
                keepAlive: true
            }
        }
    ]
})

使用懶加載的路由配置:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'

Vue.use(Router)

export default new Router({
    routes: [
        {
            path: '/',
        },
        {
            path: '/helloworld',
            name: 'HelloWorld',
            component: resolve => require(['@/components/HelloWorld'], resolve)
        },
        {
            path: '/home',
            name: 'Home',
            component: resolve => require(['@/components/Home'], resolve),
            children: [{
                path: '/detail',
                name: 'Detail',
                component: resolve => require(['@/components/Detail'], resolve)
            }],
            meta: {
                keepAlive: true
            }
        },
        {
            path: '/news',
            name: 'News',
            component: resolve => require(['@/components/News'], resolve),
            meta: {
                keepAlive: true
            }
        }
    ]
})

28. vue-router 的兩種模式

hash 模式 和 history 模式

hash 模式:
hash 發(fā)生變化之后云稚,url 都會被瀏覽器記錄下來迈套,所以你會發(fā)現(xiàn)瀏覽器的前進后退都可以用了,點擊前進碱鳞、后退,可以跳轉頁面踱蛀。

hash模式的工作原理是onhashchange事件窿给,可以在window監(jiān)聽hash的變化。
event 事件里邊有兩個屬性newURL和oldURL率拒”琅荩可以通過模擬改變 hash 的值,動態(tài)改變頁面數(shù)據(jù)猬膨。

// 頁面的URL:http://kuayu.lc/hash.html#pink角撞,通過改變 hash 的顏色值,來改變 div 的顏色勃痴。
<div id="div1" style="height: 500px;width: 500px;margin: 0 auto"></div>
<script>
  window.onhashchange = function(event){
    let event = event || window.event;
    let hash = location.hash.slice(1);
    document.getElementById('div1').style.backgroundColor = hash
  }
</script>
盡管瀏覽器沒有向服務器發(fā)送請求谒所,但頁面狀態(tài)已經(jīng)和 url 關聯(lián)起來了,這就是所謂的前端路由沛申,單頁應用的標配劣领。

網(wǎng)易云音樂,百度網(wǎng)盤就采用了hash路由铁材,看起來就是這個樣子:

  1. 網(wǎng)易云音樂:http://music.163.com/#/friend
  2. 百度網(wǎng)盤:https://pan.baidu.com/disk/home#list/vmode=list

history模式:
把window.history 對象打印出來之后尖淘,可以看到里邊提供的方法和記錄長度(__ proto__ 原型鏈上)
console.log(window.history);


image.png

前進,后退著觉,跳轉操作方法:

  history.go(-2);        //后退2次
  history.go(2);         //前進2次
  history.go(0);         //刷新當前頁面
  history.back();        //后退
  history.forward();     //前進

如果不想用 # 的 hash村生,我們可以用路由的 history 模式。

export default new VueRouter({
  mode: 'history',
  routes: [...]
})

當你使用 history 模式時饼丘,URL 就像正常的 url : http://localhost:8080/news

不過這種模式要玩好的話趁桃,還需要后臺配置支持。因為我們的應用是個單頁客戶端應用葬毫,如果后臺沒有正確的配置镇辉,當用戶在瀏覽器直接訪問 http://localhost:8080/news1234 (沒有路由,訪問不到的情況) 就會返回 404贴捡,這就不好看了忽肛。

為了避免這種情況,你應該在 Vue 應用里面覆蓋所有的路由情況烂斋,然后在給出一個 404 的組件頁面屹逛。

export default {
  mode: 'history',
  routes: [
    {path: '*', component: resolve => require(['@/components/NotFound'], resolve)}
  ]
}
29. $router 和 $route 的區(qū)別

$router 為 VueRouter 實例础废,想要導航到不同 URL,使用 $router.push 方法罕模。

$route 為當前 router 跳轉對象评腺,里面可以獲取 name 、 path 淑掌、 query 蒿讥、 params、meta 等信息抛腕。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末芋绸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子担敌,更是在濱河造成了極大的恐慌摔敛,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件全封,死亡現(xiàn)場離奇詭異马昙,居然都是意外死亡,警方通過查閱死者的電腦和手機刹悴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門行楞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人土匀,你說我怎么就攤上這事敢伸。” “怎么了恒削?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵池颈,是天一觀的道長。 經(jīng)常有香客問我钓丰,道長躯砰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任携丁,我火速辦了婚禮琢歇,結果婚禮上,老公的妹妹穿的比我還像新娘梦鉴。我一直安慰自己李茫,他們只是感情好,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布肥橙。 她就那樣靜靜地躺著魄宏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪存筏。 梳的紋絲不亂的頭發(fā)上宠互,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天味榛,我揣著相機與錄音,去河邊找鬼予跌。 笑死搏色,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的券册。 我是一名探鬼主播频轿,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烁焙!你這毒婦竟也來了略吨?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤考阱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鞠苟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乞榨,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年当娱,在試婚紗的時候發(fā)現(xiàn)自己被綠了吃既。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡跨细,死狀恐怖鹦倚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冀惭,我是刑警寧澤震叙,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站散休,受9級特大地震影響媒楼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜戚丸,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一划址、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧限府,春花似錦夺颤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至署穗,卻和暖如春宜狐,著一層夾襖步出監(jiān)牢的瞬間势告,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工抚恒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咱台,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓俭驮,卻偏偏與公主長得像回溺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子混萝,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容遗遵,還有我對于 Vue 1.0 印象不深的內(nèi)容。關于...
    云之外閱讀 5,048評論 0 29
  • ## 框架和庫的區(qū)別?> 框架(framework):一套完整的軟件設計架構和**解決方案**逸嘀。> > 庫(lib...
    Rui_bdad閱讀 2,906評論 1 4
  • vue概述 在官方文檔中车要,有一句話對Vue的定位說的很明確:Vue.js 的核心是一個允許采用簡潔的模板語法來聲明...
    li4065閱讀 7,209評論 0 25
  • 基于Vue的一些資料 內(nèi)容 UI組件 開發(fā)框架 實用庫 服務端 輔助工具 應用實例 Demo示例 element★...
    嘗了又嘗閱讀 1,149評論 0 1
  • 前言 您將在本文當中了解到,往網(wǎng)頁中添加數(shù)據(jù),從傳統(tǒng)的dom操作過渡到數(shù)據(jù)層操作,實現(xiàn)同一個目標,兩種不同的方式....
    itclanCoder閱讀 25,794評論 1 12