(精華)2020年7月12日 vue 手搭腳手架vue-cli

愚公搬程式碼發表於2020-07-12

Vue.js

一、 單檔案元件

1. .vue檔案

.vue檔案,稱為單檔案元件,是Vue.js自定義的一種檔案格式,一個.vue檔案就是一個單獨的元件,在檔案內封裝了元件相關的程式碼:html、css、js

.vue檔案由三部分組成:<template>、<style>、<script>
    <template>
        html
    </template>

    <style>
        css
    </style>

    <script>
        js
    </script>

2. vue-loader

瀏覽器本身並不認為.vue檔案,所以必須對.vue檔案進行載入解析,此時需要vue-loader
類似的loader還有許多,如:html-loader、css-loader、style-loader、babel-loader等
需要注意的是vue-loader是基於webpack的     

3. webpack

webpack是一個前端資源模板化載入器和打包工具,它能夠把各種資源都作為模組來使用和處理
實際上,webpack是通過不同的loader將這些資源載入後打包,然後輸出打包後檔案 
簡單來說,webpack就是一個模組載入器,所有資源都可以作為模組來載入,最後打包輸出

官網

webpack有一個核心配置檔案:webpack.config.js,必須放在專案根目錄下

4. 示例,步驟:

4.1 建立專案,目錄結構 如下:

webpack-demo
|-index.html
|- src
---- |-main.js 入口檔案
------|-App.vue vue檔案
|-package.json 工程檔案
|-webpack.config.js webpack配置檔案
|-.babelrc Babel配置檔案

mkdir webpack-demo
touch index.html webpack.config.js .babelrc
mkdir src
cd src
touch main.js App.vue

4.2 編寫App.vue

   <template>
   <div id="app">
       <h1>{{msg}}</h1>
   </div>
   </template>

   <script>
   export default {
       name: 'app',
       data () {
           return {
           msg: 'Welcome to ruanmou'
           }
       }
   }
   </script>

4.3 安裝相關模板

npm install vue -S

npm install webpack -D
npm install webpack-cli -D
cnpm install webpack-dev-server -D

npm install vue -D
npm install vue-loader -D
npm install css-loader -D
npm install vue-style-loader -D
npm install file-loader -D
npm install url-loader -D
npm install html-webpack-plugin -D

npm install babel-loader -D
npm install @babel/core -D
npm install @babel/preset-env -D  //根據配置的執行環境自動啟用需要的babel外掛
npm install vue-template-compiler -D //預編譯模板

合併:npm install -D webpack webpack-cli webpack-dev-server vue vue-loader css-loader vue-style-loader file-loader url-loader babel-loader @babel/core @babel/preset-env vue-template-compiler

4.4 編寫main.js

    /**
     * 使用ES6語法引入模板
     */
    import Vue from 'vue'
    import App from './App.vue'

    new Vue({
        el:'#app',
        render:function(h){ //使用render函式渲染元件
            return h(App);
        }
    });


-------------------------------------------------

   /**
     * 使用ES6語法引入模板
     */
    import Vue from 'vue'
    import App from './App.vue'
    import VueRouter from './router/index.js';

    // 第一種寫法: index.html裡的dom 為app作為模板
    // new Vue({
    //     el:'app',
    //     data:{
    //         hello:'hello',
    //         msg: 'Welcome to ruanmou'
    //     }
    // })

    //第二種寫法:template 模式, 需要compiler去編譯成render函式進行渲染頁面,效能不是最優
    // new Vue({
    //     el:'app',
    //     data:{
    //         hello:'hello',
    //         msg: 'Welcome to ruanmou'
    //     },

    //     // template:`<div id="app1">
    //     //             <h1>{{msg}}</h1>
    //     //         </div>`,

    //     // 改成引用元件就是下面的模式
    //     components:{
    //         App //App:App 
    //     }, //註冊全域性元件
    //     template:'<App/>'
    // });
    
    //第三種寫法:render模式,效能最優
     new Vue({
        el:'#app',
        router:VueRouter,
        data:{
            hello:'hello',
            msg: 'Welcome to ruanmou'
        },
        //建立虛擬Dom,不用元件
        // render(createElement){
        //     return createElement('div',{
        //         id: "app1",
        //         style:{
        //             color:'red'
        //         }
        //         },[
        //             createElement('h1',this.msg),
        //             createElement('span','world')
        //         ])
        // },
        //使用元件, 利用render函式渲染
        render:function(h){
                return h(App);
         },
        //  render:h => h(App)
        mounted(){
            console.log(this);
        }
    });

4.5 編寫webpack.config.js

    //入口檔案
    var path = require('path'); 
    var SRC_PATH = path.resolve(__dirname,'./src');
    var DIST_PATH = path.resolve(__dirname,'./dist');
    const VueLoaderPlugin = require('vue-loader/lib/plugin');
    
    module.exports={
        //配置入口檔案
        entry:SRC_PATH +'/main.js',
        //配置入口檔案輸出位置
        output:{
            path:DIST_PATH, //專案根路徑
            filename:'[name].js'
        },
        resolve: {
            //別名
            alias: {
            'vue$': 'vue/dist/vue.esm.js'
            },
            extensions: ['*', '.js', '.vue', '.json']
        },
        //配置模組載入器
        module:{
            rules:[
                {
                    test: /\.css$/,
                    use: [
                    'vue-style-loader',
                    'css-loader'
                    ]
                }, 
                {
                    test:/\.vue$/, //所有以.vue結尾的檔案都由vue-loader載入
                    use:'vue-loader'
                },
                {
                    test:/\.js$/, //所有以.js結尾的檔案都由babel-loader載入,除了node_modules以外
                    use:'babel-loader',
                    exclude:/node_modules/
                }
            ]
        },
        // 開發伺服器 
        devServer: { 
            hot: true, // 熱更新,無需手動重新整理 
            contentBase: path.resolve(__dirname, './dist/'),  //熱啟動檔案所指向的檔案路徑
            host: '0.0.0.0', // host地址 
            port: 8082, // 伺服器埠 
            historyApiFallback: true, // 該選項的作用所用404都連線到index.html 
            publicPath:'/', //預設設定
            proxy: { 
            "/api": "http://localhost:3000" 
            // 代理到後端的服務地址,會攔截所有以api開頭的請求地址
             } ,
            useLocalIp: true ,
            // open:true,
            // noInfo:true
        },
        // 外掛
        plugins: [
            new VueLoaderPlugin()
        ]

    }

4.6 編寫.babelrc

{
    "presets":[
          [ 
            "@babel/preset-env", { 
                "useBuiltIns": "usage", //按需注入
                "corejs": "2", // 宣告corejs版本
                "targets": { 
                    "browsers": [ "> 1%", "last 5 versions", "ie >= 8" ] 
                } 
            }
         ]
    ]
}

4.7 編寫package.json

    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server --config webpack.config.js",
        "build": "webpack --config webpack.config.js"
    }

4.8 執行測試

npm run dev    
npm run build

4.9 理順8個版本vue的區別(小結)

vue.js : vue.js則是直接用在<script>標籤中的,完整版本,直接就可以通過script引用。
vue.common.js :預編譯除錯時,CommonJS規範的格式,可以使用require("")引用的NODEJS格式。
vue.esm.js:預編譯除錯時, EcmaScript Module(ES MODULE),支援import from 最新標準的。

//----------------------------------------------------------------------
Runtime-only
vue.runtime.js :生產的執行時,需要預編譯,比完整版小30%左右,UMD
vue.runtime.common.js:生產執行時,commonJS標準。 CommonJS
vue.runtime.esm.js:生產執行時,esm標準。  ES Module 


https://www.jb51.net/article/147538.htm

4.10 配置路由

安裝

npm install vue-router -D

配置

新建router/index.js

import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

import home from '../pages/home.vue';
import news from '../pages/news.vue';

var allRoutes = [{
    path:'/home',
    name:'home',
    component:home
},{
    path:'/news',
    name:'news',
    component:news
}]
export default new VueRouter({
    routes:allRoutes,
    mode:'hash',
    base:'/',
    //   vue-router 認為只有路由真正匹配時,才會加上 exact-active-link 這個 class,
    //   如果只有一部分重合,就會加上 active-menu。
    // fallback
    // 不是所有瀏覽器都支援前端路由的方式,如果不支援,設定 fallback: true,
    // vue 會自動 fallback 到 hash 模式。
    fallback: true,
    linkActiveClass: "active-menu",
    linkExactActiveClass: "exact-active-menu",
})

// 在main.js中把router 例項注入到 vue 根例項中,就可以使用路由了

在main.js裡注入

import VueRouter from './router/index.js';
new Vue({
        el:'#app',
        router:VueRouter
        ....
})

在App.vue 裡新增連結 ,以及路由導航連結

<template>
  <div id="app">
    <h1>{{msg}}</h1>
    <div >
      <!-- <router-link to="/home" tag='li'>主頁</router-link>
		   <router-link to="/news" tag='li'>新聞</router-link> 
           -->
      <ul @click="gotoPage($event)">
        <li tag='home'>主頁</li>
        <li tag='news'>新聞</li>
      </ul>   
    </div>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      msg: 'Welcome to ruanmou'
    }
  },
  methods:{
    gotoPage(ev){
      var target = ev.target,
          tag = target.getAttribute('tag');
      switch(tag){
        case 'home':
          this.$router.push({
            path:'/home',
            query:{
              name:'laney'
            }
          })
          break;
        case 'news':
        this.$router.push({
          path:'/news',
          query:{
            age:'10'
          }
        })
        break;
      }
    }
  }
}
</script>

相關文章