Vue之組件


Vue之組件

vue的核心就是組件的使用,玩好了組件才能將前面的基礎更好的運用起來。

組件使我們的項目解耦,更加符合vue的設計思想MVVM。

組件系統是 Vue 的另一個重要概念,因為它是一種抽象,允許我們使用小型、獨立和通常可復用的組件構建大型應用。仔細想想,幾乎任意類型的應用界面都可以抽象為一個組件樹:

例如,你可能會有頁頭,側邊欄,內容區等組件,每個組件又包含了其它的像導航欄鏈接、博文之類的組件

組件的創建

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>組件</title>
</head>
<body>
<div id="app"></div>

<script src="vue.js"></script>
<script>
    // Vheader是組件名,最好大寫開頭
    Vue.component('Vheader', {
// 和實例對象不一樣,這里data不再返回對象,必須要是個函數,而且必須return data:
function () { return { // 必須要return,哪怕是空對象 } }, template: `<div class="header"> <div class="w"> <div class="w1"> <img src="./logo.png"> </div> <div class="w-r"> <button>登陸</button><button>注冊</button> </div> </div> </div>` }); var app = new Vue({ el: '#app', data: {}, computed: {}, methods: {} }) </script> </body> </html>

組件的使用

組件是可服用的Vue實例,並且帶有一個名字,這個例子中是<Vheader> 。

我們可以在一個通過 new Vue 創建的 Vue 根實例中,把這個組件作為自定義元素來使用:

<div id="app">
    <Vheader></Vheader>
</div>

組件的復用

<div id="app">
    <Vheader></Vheader>
    <Vheader></Vheader>
    <Vheader></Vheader>
</div>

vue-cli腳手架安裝和webpack-simple模板項目生成

vue-cli是一個官方發布vue.js項目腳手架,使用vue-cli可以快速創建vue項目。

安裝nodejs

官網下載安裝  

node -v檢查是否安裝成功

npm  是 nodejs package manager ,跟python的pip java mvn一樣

安裝vue-cli

安裝好node之后,我們就可以直接全局安裝vue-cli:

npm install -g vue-cli

安裝慢的話用淘寶鏡像,百度淘寶鏡像

npm install -g cnpm --registry=https://registry.npm.taobao.org

如果安裝失敗使用npm cache clean清理緩存,然后再重新安裝。

安裝完成后vue -V查看vue版本。 

vue hlep查看可用命令

vue list查看官方提供的模板

安裝webpack-simple模板

初始化項目,加項目名myProject就創建一個項目名的目錄里生成,不加名字默認再當前目錄生成項目

vue init webpack-simple myProject

 

最后一步選N,sass是vue的預處理語言還不會。

然后它就告訴你要繼續干什么:

webpack + nodejs 使我們更方便的開發,熱重載。

使用的webpack模板

打開項目myProject,映入眼簾的是一個也看不懂。。。

等等..main.js:

import Vue from 'vue'
import App from './App.vue' new Vue({
  el: '#app',
  render: h => h(App)
})

可以看出,這個和django的manage.py文件一樣都是一個入口文件。

入口文件引的第一個文件就是App.vue:

看看人家是怎么設計的:

<!--一個組件有三部分組成-->
<!-- 一個頁面就把三個部分全部包含了 -->
<template>
    <!--第一部分,頁面的結構-->    
    <!-- 注意template下整個必須是一個閉合標簽,因為他是一個大組件包裹一個個小組件 -->
    <!-- 比如把下面的注釋去掉就會報錯 -->
    <!-- <div class="app2"></div> -->
    <div class="app">
        <h3>{{ msg }}</h3>
        <p>heihei</p>
    </div>
</template>
<script>
    // 第二部分,頁面的業務邏輯
    export default {
        name:'App',          // 只是個名字
        data(){              // 數據屬性必須是個函數
            return {
                msg:'組件'
            }
        },
        methods: {

        },
        computed: {

        }
    }
</script>
<style>
    /*第三部分,css樣式*/
</style>

解耦組件

上面的是一個大組件,要解耦成一個個小組件,所以我們要創建一個存放一個個小組件的文件加。

src下面新建一個folder,就叫components。

並新建三個文件:

每個文件里的結構,跟App.vue里的一樣。

<template>
    <header class="nav">  <!--footer的class:foot,content:wrap-->
        我是header
    </header>
</template>
<script>
    export default {
        name:'Vheader',// footer:Vfooter,content:content     
        data(){             
            return {

            }
        },
    }
</script>
<style scoped>  //scoped:組件里的樣式只在自己的組件里生效
</style>

引入子組件

接下來這些小組件怎么在大組件里用呢:

<template>
    <div class="app">
        <h3>{{ msg }}</h3>
        <p>heihei</p>
        <Vcontent></Vcontent>
        <Vcontent></Vcontent>
        <Vcontent></Vcontent>
    </div>

</template>
<script>
// 1. 先引入子組件
import Vcontent from './components/Vcontent.vue'
import Vheader from './components/Vheader.vue'
import Vfooter from './components/Vfooter.vue'
    export default {
        name:'App',      
        data(){              
            return {
                msg:'組件'
            }
        },
        methods: {

        },
        computed: {

        },
        // 2. 掛載組件
        components:{
            Vheader,   // 相當於Vheader:Vheader,key和value相同可以簡寫
            Vcontent,
            Vfooter,
        }
    }
</script>
<style>
</style>

組件間傳值

父組件向子組件傳遞數據,通過Prop

 
         
1. 父組件向子組件傳值第一步就是, 綁定自定義的屬性,在導入的子組件標簽: <Vheader :title = '父組件中data聲明的數據屬性'/>
2. 父子傳值的第二步就是,要通過props驗證,再子組件里寫這個方法
// 數組類型就必須寫Array,寫Str就會報錯,對應類型可以查官網,然后就可以在子組件里用這個數據量了 props:{ cityArray:Array, }

type 可以是下列原生構造函數中的一個:

    • String
    • Number
    • Boolean
    • Array
    • Object
    • Date
    • Function
    • Symbol

子組件傳遞數據到父組件,通過自定義事件

1. 子父組件傳值,第一步就是自定義事件
<Vcontent v-on:addCunHandler = 'addHandler'></Vcontent>
2. 給子組件中的某個按鈕綁定原生事件,我們可以調用內建的 this.$emit('自定義的事件名','傳遞的數據'),來向父級組件觸發一個自定義的事件.
        methods:{
            addCunHandler(){
                // 通過$emit觸發自定義事件
                // 參數1:自定義事件的名字
                // 參數2:數據
                this.$emit('addCunHandler','北海北');
            }
        },
 

MarkDown項目

寫一個markdown項目,練習一下組件傳值

父組件:App.vue

<template>
    <div class="app">
        <Vheader></Vheader>
        <h2>{{ currentMsg }}</h2>
        <!-- webpack里的file-loader工具能把圖片看做變量 -->
        <!-- 所以取圖片用下面這種方式即可 -->
        <img :src="imgSrc">
        <ul>
            <li v-for = 'item in getArray'>
                <!-- a標簽里的href="javascript;"表示阻止a標簽的事件,等於a標簽失效了 -->
                <a href="javascript;">{{item}}</a>
            </li>
        </ul>
        <!-- 來個點擊事件 -->
        <button @click='clickHandler'>修改</button>
        
        <!-- 子父組件傳值,第一步就是自定義事件 -->
        <Vcontent v-on:addCunHandler = 'addHandler'></Vcontent>
        <!-- 父子組件傳值,第一步就是綁定自定義屬性 -->
        <Vfooter :cityArray = 'citys'></Vfooter>
    </div>
</template>
<script>
    import imgSrc from './assets/logo.png'
    // 子組件渲染到父組件的第一步就是,導入
    import Vheader from './components/Vheader.vue'
    import Vcontent from './components/Vcontent.vue'
    import Vfooter from './components/Vfooter.vue'
    export default {
        name:'App',     
        data(){             
            return {
                msg:'hello world',
                stars:[
                    "nsn","alex",'nezha'
                ],
                imgSrc:imgSrc,
                citys:['沙河','通州','西二旗']
            }
        },
        methods: {
            clickHandler(){
                this.msg = '哈哈哈',
                this.stars.push('anglebaby')
            },
            addHandler(str){
                this.citys.push(str)
            }
        },
        // 所有的屬性,都可以被計算屬性綁定起來,多用計算屬性
        computed: {
            currentMsg(){
                return this.msg;
            },
            getArray(){
                return this.stars
            }
        },
        // 子組件渲染到父組件的第二步就是,掛載
        components:{
            Vheader,
            Vfooter,
            Vcontent
        }
    }
</script>
<style>
*{
    padding: 0px;
    margin: 0px;
}
</style>

子組件Vfooter

<template>
    <footer class="foot"> 
        <ul v-for = 'item in cityArray'>
            <li>{{item}}</li>
        </ul>
    </footer>
</template>
<script>
    export default {
        name:'Vfooter', 
        data(){             
            return {

            }
        },
        // 父子傳值的第二步就是,一定要通過props驗證
        // 數組類型就必須寫Array,寫Str就會報錯,對應類型可以查官網,然后就可以在上面用了
        props:{
            cityArray:Array,
        }
    }
</script>
<style>
</style>

子組件Vcontent

<template>
    <div class="wrap">  
        <div class="t">
        <button @click='addCunHandler'>添加一個村庄</button>
        </div>

        <div class="mark">
            <textarea rows="10" cols="100" class="editor" v-model = 'markValue'></textarea>
            <div class="show" v-html = 'markedValue'></div>
        </div>
    </div>
</template>
<script>
    // npm install marked --save,別人寫好的markdown工具,直接解析你的markdown語法
    import Marked from 'marked'
    export default {
        name:'Vcontent', 
        data(){             
            return {
                markValue:''
            }
        },
        methods:{
            // 子組件向父組件傳值,第二步就是觸發自定義事件
            addCunHandler(){
                // 通過$emit觸發自定義事件
                // 參數1:自定義事件的名字
                // 參數2:數據
                this.$emit('addCunHandler','北海北');
            }
        },
        computed:{
            markedValue(){
                return Marked(this.markValue)
            }
        }
    }
</script>
<style scoped>
    .t {
        width: 300px;
        height: 100px;
    }
    .mark{
        width:1210px;
        height: 600px;
        margin: 0 auto;
    }
    .editor,.show{
        float: left;
        width: 603px;
        height: 600px;
        border: 1px solid #666;
    }
</style>

子組件Vheader

<template>
    <header class="header"> 
        <div class="nav">
            <div class="logo">
                <img :src="imgSrc" />
            </div>
            <div class="info">
                <button>注冊</button>
                <button>登陸</button>
            </div>
        </div>
    </header>
</template>
<script>
    import imgSrc from '../assets/logo.png'
    export default {
        name:'Vheader',    
        data(){             
            return {
                imgSrc:imgSrc
            }
        },
    }
</script>
<style scoped>
    .header{
        width: 100%;
        height: 40px;
        background-color: #fff;
        box-shadow: 0 2px 4px 0 #c9c9c9; /* box-shadow是框邊的陰影,更有立體感*/ 
    }
    .header .nav{
        width: 980px;
        height: 40px;
        margin: 0 auto;
        /*transparent透明*/
        background-color: transparent;
    }
    .nav .logo{
        width: 100px;
        height: 40px;
        float: left;
    }
    .logo img{
        width: 40px;
        height: 40px;
    }
    .nav .info{
        float: right;
        width: 200px;
        height: 40px;
    }
    .info button{
        width: 80px;
        height: 40px;
        float: left;
    }
</style>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM