Javascript - Vue - webpack中的組件、路由和動畫

引入vue.js

1.cnpm i vue -Scss

2.在mian.js中引入vue文件html

import Vue from "vue"
//在main.js中使用這種方式引用vue文件時,webpack默認會到node_modules/vue/dist目錄找到package.json文件裏的配置,這個文件的mian屬性指向了node_modules/vue/dist/vue.runtime.common.js
//這個路徑指向的vue文件就是import Vue from "vue"中的"vue",它只是一個運行時加載的不完整的vue文件
//能夠經過設置webpack.config.js中的resolve屬性,讓它正確指向完整的vue文件。若是不向對路徑進行配置,你還能夠直接使用import Vue from "../node_modules/vue/dist/vue.js"

3.在webpack.config.js中設置resolvevue

resolve{
    alias{
        'vue''vue/dist/vue.js'
    }
}

4.在html頁面將bundle.js的引入放在html結尾處。node

……
</html>
<script src="/bundle.js"></script>

組件文件

組件不必定要寫在js文件裏,還有一種之後綴名爲.vue的文件結合render渲染的方式也可使用組件。webpack

1.在src目錄建立一個login.vue的組件文件git

打開文件輸入如下代碼,ue組件文件的代碼提示工具:veturgithub

<template>
<div>
    <h5>這是經過xx.vue文件定義的組件</h5>
</div>
</template>

<script></script> 
<style></style> 

2.安裝vue-loader,用它來解析vue組件文件web

2-1.cnpm info vue先查看vue的版本ajax

2-2.cnpm i vue-template-compiler@2.6.10 -D (安裝vue-loader的依賴vue-template-compiler,compiler這個包必須和vue的版本保持一致,不然報錯)vue-router

2-3.cnpm i vue-loader -D

3.在webpack.config.js中配置

const VueLoaderPlugin = require('vue-loader/lib/plugin');
//或    
const { VueLoaderPlugin } = require('vue-loader');


plugins[
    new VueLoaderPlugin()
],
{ test: /\.vue$/, use'vue-loader'}

4.在main.js中引入vue和login.vue,vue組件文件只能經過render來渲染,不能以註冊爲components組件進行使用。

import Vue from "vue"
import login from "./login.vue"

var vm = new Vue({
    el: "#box",   
 data:{msg:"hello"}
    // components:{
    //     login:login
    // }這種方式沒法引入組件文件裏的組件
    render:createHtml=>createHtml(login)

});

5.在index.html中調用vue

<body>
    <div id="box">
        <p>{{msg}}</p> //組件文件裏的html會替換掉id爲box的盒子及其內容      
    </div>
</body>

組件文件中組件的內部數據

在src目錄下建立components目錄,在該目錄下建立app.vue

<template>
    <div>
        <p>{{msg}}</p>
        <button @click="show">OK</button>
    </div>
</template>

<script>
export default{
    data:function() {
        return {msg:"hello"}
    },
    methods:{
        show:function(){
            alert("OK");
        }
    }
}
</script>

<style></style>

在main.js中導入組件

import Vue from "vue"
import app from "./components/app.vue"

var vm=new Vue({
    el:"#box",
    render:createEls=>createEls(app)
})

組件文件的style標籤

組件文件中能夠寫css樣式,能夠選擇在當前<style>標籤裏寫的樣式是在當前組件的做用域(scoped)可用仍是在全局可用、是應用less樣式仍是css或sass樣式,加scoped的原理是它會自動爲你的組件根元素增長一個css屬性,而後經過屬性選擇器爲這個組件應用你設置的css樣式。若是是在當前做用域可用,則你的css樣式只針對當前組件裏的htm,其它諸如設置body等是無效的。

<template>
    <div>
        組件
    </div>
</template>
<style scoped lang="less">
div{
    background:rgb(67, 0, 252);
    color:#fff;
    p{
        color:blue;
    }
}
</style>

組件文件的導入

導入組件文件就是導入組件對象,默認狀況下不須要使用export語法將組件文件裏的組件導出到外部,外部只須要直接import引入.vue文件所在路徑便可導入組件。只有在引入本身建立的js文件時則須要提供js文件的路徑。

路由組件

1.cnpm i vue-router -S 安裝處理路由的js包

2.導入路由組件,如今假設建立了兩個組件(account.vue和productList.vue)

3.建立你的router.js文件,在文件中導入官方的vue-router.js和組件文件

import Vue from "vue"
import VueRouter from "vue-router"
import account from "./components/account.vue"
import productList from "./components/productList.vue"

Vue.use(VueRouter); //在webpack中使用vue路由時須要調用這個方法來獲得vue-router.js包,註冊路由包到vue對象上

var router=new VueRouter({
    routes:[
        {path:"/",redirect:"/account"},
        {path:"/account",component:account},
        {path:"/productList",component:productList}
    ]
});


而後將你編寫路由文件導入到main.js中

import  Vue  from  "vue" ;
import  router  from  "./js/router"  //你編寫的關於路由的js文件

var  vm  =  new  Vue ({
    el :  ".box" ,    
    router :  router
});

在html頁面中引入router-view

<div id="box">
    <router-link to="/account">帳戶</router-link>
    <router-link to="/productList">圖書列表</router-link>
    <router-view></router-view> 
</div>

若是上面例子中的vue內部使用了render來渲染某個組件到頁面,同時還使用了router-view,那麼由於render渲染組件後會替換掉#box元素,因此router-view中的路由組件是不會顯示的,解決辦法是將router-link及其router-view放在render所渲染的那個組件裏,好比render了一個叫作app的組件,代碼以下

<template>
    <div>
        這是普通的app組件
        <router-link to="/account">帳戶</router-link>
        <router-link to="/productList">圖書列表</router-link>
        <router-view></router-view> 
    </div>
</template>

*還能夠把建立路由對象的代碼移植到單獨的js文件中,經過導入路由對象來使用它。

*粗劣總結一下就是將普通組件註冊到路由匹配裏的組件就是路由組件

路由子組件

與沒有使用webpack時的寫法是同樣的,將子組件的router-link和router-view放在父組件的template中

import account from "./components/account.vue"
import login from "./components/login.vue"
import register from "./components/register.vue"
import productList from "./components/productList.vue"

Vue.use(VueRouter);

var router = new VueRouter({
    routes: [
        { path: "/", redirect: "/account" }, //訪問根目錄時自動轉到帳戶組件的匹配上
        {
            path: "/account",
            redirect:"/account/login", //訪問帳戶組件時自動轉到登陸子組件的匹配上
            component: account,
            children:[
                {path:"/account/login",component:login},
                {path:"/account/register",component:register}
            ]
        },
        { path: "/productList", component: productList }
    ]
});

var vm = new Vue({
    el: "#box",
    router: router   
});

組件切換的動畫

<transition mode="out-in">
    <router-view></router-view>
</transition>
.v-enter
    opacity0;
    transformtranslateX(100%);
}
.v-leave-to{
    opacity0;
    transformtranslateX(-100%);
}

.v-enter-active,.v-leav-active{
    transitionall 0.3s ease;
}

總結一下就是:vue-router.js路由是指不向服務端發起請求,在路由對象中設置路由匹配規則,建立vue文件,將該文件導入到路由對象所在的那個js文件中,再將路由對象註冊到vue對象上。當發起路由請求時由vue對象捕獲請求,接着調用路由對象對路由請求進行匹配,匹配成功則展示對應的組件到router-view中

分清路由子組件和普通子組件

路由子組件是將普通組件註冊到路由對象內部的某個路由匹配規則的children中,這樣該組件才能成爲路由子組件。而普通子組件是將一個普通的組件註冊到vue對象或其餘組件對象的內部的components中。二者的最大區別在於路由子組件一般都是大於1個,由於大於1個的子組件們須要在一個router-view中進行切換顯示(同級別的組件之間的切換顯示),而普通的子組件不存在同級別的切換顯示,也即若是該子組件不須要同級別的切換顯示,則只須要將它註冊在vue對象或其餘組件對象之中(經過屬性components註冊),若是它須要和與它同級別的組件之間進行切換顯示,那麼能夠考慮將它們作成子路由組件。

下圖是普通路由組件

點擊首頁中的新聞路由組件,顯示新聞路由組件

 

下圖是路由子組件

下圖是普通子組件

這個頁面是一個新聞路由組件,在這個組件內部有一個普通的子組件(評論區)

 

普通子組件的註冊

var vm = new Vue({
    components: {
        mycom:com
    }
});
//或
export default {

    components: {
        mycom:com
    }
}

路由組件的註冊

{ path"/index", componentindex }
{ path"/index/news", componentnews }

路由子組件的註冊

{
    path"/index",
    componentindex,
    children[{ path: "news" }]
}

組件的正確使用方式

如下是一個展現圖片的模塊,點擊導航欄的菜單能夠切換不一樣類型的圖片。這個組件叫作shareImg.vue,導航欄下面的圖片如何顯示?此處並無把圖片區域作成一個路由子組件(在這個組件頁面使用router-link和router-view)。僅僅用了一個普通的ul列來呈現圖片。若是你使用路由子組件來做爲圖片的容器,看起來彷佛很不錯,由於當你切換導航欄菜單的同時就會切換router-view裏的圖片組件,可是這樣作就須要導航欄所對應的組件文件,也即,7個菜單項就須要建立它們所對應的7個組件文件,若是你針對導航菜單的切換隻使用一個組件去承載(由於每一個導航菜單獲得的數據的html模板都是徹底同樣的),那麼當點擊菜單發起請求後,只有第一次會成功,當你再點擊其它菜單時,切換不會發生,由於第一次點擊時已經把惟一的一個展現圖片的組件渲染出來了,該組件對象已經存在,因此再次點擊菜單不會再重複渲染。正確作法是隻須要在這個組件的內部使用一個ul,當導航到這個組件頁面的時發起兩個不一樣的ajax請求,分別請求各自的數據。這樣就能夠把數據分別裝載到各自的html中(導航欄和圖片容器),當點擊菜單後,觸發綁定在超連接上的click事件,click事件調用獲取數據的方法便可再次發起請求得到不一樣的圖片數據。

*總結一下:在一個組件文件中,路由子組件只適合於點擊不一樣的按鈕時會請求不一樣的組件文件,若是點擊不一樣的按鈕所切換的組件模板是徹底同樣的,就不須要定義組件,而是直接使用html。

第三方組件

Mint-UI

mint-ui是基於vue開發的第三方移動端的js組件,具體參考:Mint-UI

使用cnpm install mint-ui -S能夠安裝此組件包,但若是隻想引入這個包的部分組件,除了執行安裝命令以外還須要安裝babel-plugin-component插件。

1.cnpm i babel-plugin-component -D

2.在擴展名爲.babelrc的文件中輸入如下代碼,下面的代碼複製到babelrc中可能會提示語法格式錯誤,不用管它,複製完直接保存。

{  
    "plugins"[
        ["component",
            [
                {
                    "libraryName": "mint-ui",
                    "style": true
                }
            ]
        ]
    ]
}

3.在webpack.config.js中添加處理mint-ui所使用的ttf文件的loader

{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, use'url-loader' },

4.以上完成以後,在import的時候不須要完整引入mint-ui(import MintUI from 'mint-ui'),不須要把MintUI註冊到Vue上(Vue.use(MintUI)),也不須要再引入mint-ui的css(import "../node_modules/mint-ui/lib/style.css")。只須要以下引入便可使用

import Vue from "vue" //mint-ui依賴於vue.js
import { Button } from 'mint-ui'
//有兩種方式將mint-ui組件註冊到vue上
//1.註冊到全局上
Vue.component(Button.name, Button); //這種方式能夠改Button的標籤名字
//2.註冊爲私有組件
var vm=new Vue({
  el:"#box",
  components:{
  mtButton:Button
 }
})

<mt-button size="large" type="danger">OK</mt-button>

*若是你導入了mint-ui,那麼注意在組件文件裏的style標籤不能使用scope,不然style標籤裏的css會失效。

*mint ui的組件中可能包含其餘的組件,好比<mt-header>裏可能包含<mt-button>,引入header組件後則還須要引入buttom

使用Mint ui的固定標題欄組件

在main.js中導入

import { Header } from 'mint-ui';
import { Button } from 'mint-ui';
import app from "./components/app.vue" //首頁框架頁面
Vue.component(Header.name, Header)
Vue.component(Button.name, Button)

var vm=new Vue({
    el:"#box",    
    render:c=>c(app),
    router:router
})

在app.vue中

<mt-header fixed title="hello vue!" class="fix-header">
    <span @click="goBack" slot="left" v-show="flag">
        <mt-button icon="back" class="fix-header-btn">返回</mt-button>
    </span>
    <mt-button icon="more" slot="right"></mt-button>
</mt-header>
export default {
    data: function () {
        return {
            flag: true
        };
    },
    methods: {
        goBack: function () {
            this.$router.go(-1);
        },
        setHaederShow: function () {
            //若是當前路由地址是主頁,則不顯示後退按鈕
            this.flag = this.$route.path === "/index" ? false : true;
        }
    },
    created: function () {
        this.setHaederShow();
    },
    watch: {
        "$route.path": function (newVal) {
            this.setHaederShow();
        }
    }
};

Javascript - 學習總目錄

相關文章
相關標籤/搜索