Vue后臺管理界面

Vue后臺管理項目

一、自我總結后臺管理界面項目里的知識點

單頁應用
1. webapck 把很多的js,img,hmtl,css .... 打包成一個html文件以及相應的css和js
2. node可以操作本地文件
3. npm下載安裝nodejs模塊(插件)
4. 路由,單頁應用通過改變路由來改變頁面顯示的內容
模板(使用下面技術)
1. vue 
2. elm-ui
3. webapck
4. 文檔地址:  https://panjiachen.github.io/vue-element-admin-site/zh/guide/
5. 使用
* 下載項目源文件
* npm i 安裝依賴的模塊或者插件
* npm run dev 啟動服務
接口:http://132.232.87.95:3000/ 
  • 單頁應用 APS
單頁應用
1. webapck 把很多的js,img,hmtl,css .... 打包成一個html文件以及相應的css和js
2. node可以操作本地文件
3. npm下載安裝nodejs模塊(插件)
4. 路由,單頁應用通過改變路由來改變頁面顯示的內容

模板(使用下面技術)
1. vue 
2. elm-ui
3. webapck
4. 文檔地址:  https://panjiachen.github.io/vue-element-admin-site/zh/guide/
5. 使用
* 下載項目源文件
* npm i 安裝依賴的模塊或者插件
* npm run dev 啟動服務
這里的dev是根據package.json里scripts對象里的start來決定的

在文件夾shift+右擊,調出對應文件夾的命令窗口
  • vue文件格式
<template>
  <div>
    // 只能有一個標簽,html里的內容放在這里面
  </div>
</template>
<script>
import  from './'
// 到入 從某某文件里導出某某 ./用來選定當前文件夾 不能直接填否者會報錯
export default {
    // 導出,vue js的代碼放這里
    生命周期函數 了解可以看vue基礎篇
};
</script>
<style scoped lang="less">
    // css代碼放這里 scoped表示該樣式只用于這個文件 lang="less"需安裝less插件才可用 關于less請看我主頁的文章
</style>
  • 組件使用流程
    組件->全局組件->局部組件->組件注冊->組件使用->路由設置->路徑相關->vue文件格式->組件導入、導出->eleme-ui引用->樣式更改
全局組件:定義在Vue對象(main.js里)外,必須注冊才能使用 注冊之后 Vue對象都可以訪問使用 
Vue.componet('組件名',{
    data:function(){
        // data必須是函數
        return:{
            // 返回想要的函數對象等
        }
    }
    template:`里面可以是標簽也可以是其他的`
})

組件注冊:script里加 component('組件名', {
  // ... 選項 ...
})

局部組件:定義在vue組件里面,只有在這個vue組件里才能使用
  • 配置路由
路由設置:router文件夾是路由設置的文件夾,對應里面的router.js 是配置路徑的地方
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export const constantRouterMap=[
  {
    path: './文件對應的文件夾',
    component: () => import('@/views/對應的文件夾)
    children: [  // 上面文件夾下的文件夾,簡稱子文件
      {
        path: 'index 文件名一般固定為index',
        name: '和父文件里path對應',
        component: () => import('@/views/index對應的文件夾/index'), // 如果有幾個子文件時默認顯示的文件
        meta: { title: '隨意命名', icon: '圖標名' }
      }
    ]
  }
]
export default new Router({
  routes: constantRouterMap
})

然后在main.js函數里面導入
import Vue from 'vue'
import router from './router'
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})
  • 父子組件通信
    假設a為父組件,b為子組件
    a引用b時需要引入,import b from 'b'
    a使用b時需要在a里面注冊b,
    components:{
        b
    }
    a使用b組件:<b></b>  后續一切動作的源頭(如果沒有引用二者之間毫無關系)
    a使用b相當于使用標簽,但是標簽一般都有屬性
    b可以自定義屬性 b里面使用 props 數組定義數組 注意是數組后接 :[ ] 屬性填在里面
    父組件傳數據給子組件:
    a使用b里聲明好的屬性,然后給屬性賦值,也就是所謂的父組件傳數據給子組件
    給屬性賦值可以是字符串也可以是變量,但是變量之前要加:
    子組件傳數據給父組件:
    a在b里聲明了自定義的事件,以及函數
    在b里面觸發a的自定義事件來傳數據 this.$emit("自定義事件名",數據data)
  • 簡單的數據結構
棧:存放基本數據類型(數字,字符串,布爾,undef,null)
堆:存放對象
棧像一個杯子,內部的東西都是從外放進來的,而且是先進后出
堆像一個倉庫,內部存放對象,對象里包含很多信息,一個變量對應一個對象,當兩個變量對應的對象是相同的話
  只要有一方更改,對象里面的數據都會發生更改,類似于通過一個變量綁定相同的對象然后實現雙向綁定
棧堆:先進后出 數組的兩個方法可以解釋 push pop  
數列:先進先出 數組的兩個方法可以解釋 push shift
  • 組件的使用和引用
步驟:1.引入elme組件,形成靜態頁面
    需要注意標簽內綁定的事件函數、屬性和變量,更改或者對應的在下面創建好不然不會顯示
    2.把相同部分做成一個小組件
    創建小組件,然后把相同部分的代碼放在組件里面,注意里面的變量屬性和函數要對應存在否者不顯示
    3.引用剛才創建的小組件
    首先得導入,import  from '' 路徑要填對 同一個文件夾的話只需要./后接組件名
    然后在導出export default下面 注冊組件 components:{ 組件名 }
    4.使用組件,放在之前對應的地方,使用直接是<標簽名/>
    5.在組件里面定義屬性然后傳需要的數據過去
    在組件的導出下面使用props:[屬性名] 定義屬性名 然后在引用的組件標簽
    里面添加屬性并傳入需要的屬性,是變量的時候前面需要加:
    6.然后組件實現的功能都是在組件里面編輯的,到引用的上面直接就是有功能的了
  • 三目運算符
三目運算符
三元表達式
if()else() => *?*:*
意思相近,?為if,如果前面的true則打印?后面的,如果為false則打印:后面的

sc 快速生成vue組件的框架

二、實際應用

一、 vue里頁面之間傳參通過router-link

獲取頁面傳過來的參數
this.$route.params.參數名;
第一步: <router-link :to="`/cinema/edit/${scope.row.cinemaId}`">編輯</router-link>
通過router-link跳轉到對呀路由(/cinema/edit)下,后面接/然后就是參數。模板字符串``里用${參數}來傳
第二步:{
        path: 'edit/:id',
        component: () => import('@/views/cinema/edit'),
        meta: {
          title: '編輯影院',
          icon: 'form'
        }
      }
router里面在路徑對應的后面加/:id,用id來接受參數,當然參數是自定義的
第三步: 在跳轉后的頁面獲取參數this.$route.params.id   id對應我們在路由里定義的儲存參數的變量上

二、vue里獲取接口數據

 created() {
        let id = this.$route.params.id;
        this.findList(id);
    },
    methods: {
        findList(id){
            const url = process.env.BASE_API + '/cinema/findById'
          //  封裝后的使用
            axios.get(url,{
                params:{
              // 參數
                    cinemaId:id
                }
            }).then( res => {
                this.list=res.data.data.cinema;
            }).catch( error => {
                console.log(error)
            })
        }
    },

和js原生對比不然發現有不同的地方,這里是對接口進行了一些封裝


image.png

image.png

image.png

image.png
  • 由圖片可以看出,這個是經過了一些列封裝然后使得用的時候方便
    創建文件夾utils用來放封裝函數->request.js對獲取后臺數據的axios進行封裝->然后使用的時候在config文件夾下的dev-env.js里更改BASE_API為我們接口的各個部分即可

三、 結合數組函數map實現二級聯動

<template>
    <!-- 聯動選擇組件 -->
    <div>
        <el-select @change="changeCity" v-model="film.cityId" filterable placeholder="請選擇城市">
      <el-option  v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
    </el-select>
    <el-select v-model="film.districtId" style="margin-left: 20px;" placeholder="請選擇區域">
      <el-option v-for="item in district" :key="item.value" :label="item.label" :value="item.value"></el-option>
    </el-select>
    </div>
</template>

<script>
import axios from 'axios'
export default {
    props:[
        'film'
    ],
    data() {
        return {
            options:[],
            district:[]
        }
    },
    created() {
        this.getlist();
    },
    methods: {
        getlist(){
            const url = process.env.BASE_API +'/city/getList';
            axios.get(url,{
                params:{}
            }).then(res=>{
                const cities = res.data.cities;
                const arr = cities.map(item=>{
                    return{
                        value:item.cityId,
                        label:item.name
                    }
                })
                this.options = arr;
            }).catch(error=>{
                console.log(error)
            })
        },
        changeCity(cityId){ 
            this.getDistrId(cityId)
            this.film.districtId=''
        },
        getDistrId(cityId){
            const url = process.env.BASE_API +'/district/findByCityId';
            axios.get(url,{
                params:{
                    cityId
                }
            }).then(res=>{
                const distr = res.data.districts;
                const arr = distr.map(item=>{
                    return{
                        value:item.objectId,
                        label:item.name
                    }
                })
                this.district = arr;
            }).catch(error=>{
                console.log(error)
            })
        }
    },
}
</script>
<style>
</style>
  • @ v-on的縮寫 : v-bind縮寫 @綁定事件 :變為變量

四、 結合數組函數push、indexOf、splice增刪輸入框

<template>
<!-- 增刪輸入框組件 -->
  <div class="sb">
    <el-form-item class="input" label="劇照">
      <el-input placeholder="請輸入內容" v-model="film.pics">
      </el-input>
      <el-button @click="addDomain" class="button" type="info">新增</el-button>
    </el-form-item>
    <el-form-item class="input" label='劇照' v-for="(domain) in photos.domains" :key="domain.key">
     <div>
        <el-input placeholder="請輸入內容" v-model="film.pics">
      </el-input>
      <el-button @click.prevent="removeDomain(domain)" class="button" type="info">刪除</el-button>
     </div>
    </el-form-item>
  </div>
</template>

<script>
export default {
    props:[
        "film"
    ],
  data() {
    return {
      photos: {
        domains: []
      }
    };
  },
  created() {
  },
  methods: {
    addDomain() {
        this.photos.domains.push({
        value: "",
      });
    },
    removeDomain(item) {
      var index = this.photos.domains.indexOf(item);
      if (index !== -1) {
        this.photos.domains.splice(index, 1);
      }
    }
  }
};
</script>
<style>
.input {
  position: relative;
  right: 80px;
}
.button {
  position: relative;
  float: right;
  top: -40px;
  left: 75px;
}
.ab {
  clear: both;
}
</style>
  • 可見input類型標簽使用v-model和數據雙向綁定更改值
    以及遍歷使用v-for((item,index) in list) :key="index"
  • v-for key 實現輸入框的增加、刪除
<template>
  <div>
    <h3>v-for key 實現輸入框的增加、刪除</h3>
    <div
      :v-model="lists[index].value"
      :class="'input'+index"
      v-for="(list,index) in lists"
      :key="list.id"
    >
      <input type="text" placeholder="請輸入">
      <button v-if="panduan(index)" @click="add">+</button>
      <button v-else @click="del(index)">-</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      lists: [{}]
    };
  },
  created() {},
  methods: {
    add() {
      this.lists.push({
        value: ""
      });
    },
    del() {
      this.lists.pop();
    },
    panduan(index) {
      return this.lists.length - 1 === index;
    }
  }
};
</script>
<style>
button {
  width: 25px;
  height: 25px;
}
</style>
// key 指定一個屬性為區別兩個數據,一般是id,類似于數據庫里的主鍵

五、渲染列表

<template>
<!-- 父子通信組件 -->
<div>    
    <el-form-item label="電影名稱">
    <el-input v-model="film.name"></el-input>
  </el-form-item>
  <el-form-item label="海報地址">
    <el-input v-model="film.poster"></el-input>
  </el-form-item>
  <el-form-item label="演員">
    <el-input v-model="film.actors"></el-input>
  </el-form-item>
  <el-form-item label="導演">
    <el-input v-model="film.director"></el-input>
  </el-form-item>
  <el-form-item label="產地">
    <el-input v-model="film.nation"></el-input>
  </el-form-item>
</div>
</template>

<script>
import Xuan from './Xuan'
export default {
    props:[
        'film'
    ],
    data() {
        return {
        }
    },
    components:{
      Xuan
    }
}
</script>
<style>
</style>

列表里大部分用的都是input標簽,然后渲染方式就是綁定v-model雙向綁定更改數據
六、父子通信

// 父組件
<template>
    <div>
        <Form></Form>
        <Form title="添加電影"></Form>
        <!-- 通過字符串添加 -->
        <Form :title="title"></Form>
        <!-- 通過變量以及組件里的屬性添加 -->

        <!-- 通過自定義事件把子組件的數據傳到父組件 -->
        <Form id="app" @aaa="test">自定義事件</Form>

        <!-- 二級聯動 -->
        <demo class="demo"></demo>

        <!-- 增刪輸入框 -->
        <xinzeng></xinzeng>
    </div>
</template>
<script>
// 加載Form 組件
import xinzeng from './components/xinzeng';
import demo from './components/demo';
import Form from './components/Form'
export default {
    data() {
        return {
            title:'這是通過組件的屬性添加的'
        }
    },
    created() {
        // emit 觸發自定義事件
        // this.$emit('aaa');
    },
    mounted() {
    },
    methods: {
        test(data){
            alert(data);
        }
    },
    // 注冊組件
    components:{
        Form,
        demo,
        xinzeng
    }
}
</script>
<style>
.demo{
    margin-top: 20px;
    margin-left: 20px;
}
</style>
// 子組件
<template>
    <div>
        <h3>{{title}}</h3>
        <span>用戶名:</span>
        <input v-model="user" type="text">
        <button @click="submit">傳數據</button>
        
    </div>
</template>

<script>
export default {
    props    //  屬性   如果把組件當成標簽
    :[
        "title",
    ],
    data() {
        return {
            user:''
        }
    },
    // 避免修改從父組件傳下來的屬性,修改會給后期維護帶來不利
    created() {
        console.log(this.title);
        // 可以通過this訪問title
    },
    methods: {
        submit(){
            // 觸發父組件的自定義aaa事件
            this.$emit("aaa",this.user)
        }
    },
}
</script>
<style>
    button{
        width: 100px;
    }
</style>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內容,還有我對于 Vue 1.0 印象不深的內容。關于...
    云之外閱讀 5,074評論 0 29
  • 前言 您將在本文當中了解到,往網頁中添加數據,從傳統的dom操作過渡到數據層操作,實現同一個目標,兩種不同的方式....
    itclanCoder閱讀 25,891評論 1 12
  • ## 框架和庫的區別?> 框架(framework):一套完整的軟件設計架構和**解決方案**。> > 庫(lib...
    Rui_bdad閱讀 2,961評論 1 4
  • 一:什么是閉包?閉包的用處? (1)閉包就是能夠讀取其他函數內部變量的函數。在本質上,閉包就 是將函數內部和函數外...
    xuguibin閱讀 9,722評論 1 52
  • 每個人心里都有一個地方,住著一個人,那里春風秋月、冬暖夏涼。 你微微笑著,不問我說什么話, 而我覺得,為了這個,我...
    喜歡詩詞的女孩閱讀 610評論 0 0