Vue相關(guān)問題

首先什么是mvvm

MVVMModel-View-ViewModel的縮寫。mvvm 是一種設(shè)計思想。Model 層代表數(shù)據(jù)模型,也可以在 Model 中定義數(shù)據(jù)修改和操作的業(yè)務(wù)邏輯;View 代表 UI 組件,它負責將數(shù)據(jù)模型轉(zhuǎn)化成 UI 展現(xiàn)出來,ViewModel 是一個同步 View 和 Model 的對象。
在 MVVM 架構(gòu)下,View 和 Model 之間并沒有直接的聯(lián)系,而是通過 ViewModel 進行交互,Model 和 ViewModel 之間的交互是雙向的, 因此 View 數(shù)據(jù)的變化會同步到 Model 中,而 Model 數(shù)據(jù)的變化也會立即反應(yīng)到 View 上。
ViewModel 通過雙向數(shù)據(jù)綁定把 View 層和 Model 層連接了起來,而 View 和 Model 之間的同步工作完全是自動的,無需人為干涉,因此開發(fā)者只需關(guān)注業(yè)務(wù)邏輯,不需要手動操作 DOM, 不需要關(guān)注數(shù)據(jù)狀態(tài)的同步問題,復(fù)雜的數(shù)據(jù)狀態(tài)維護完全由 MVVM 來統(tǒng)一管理。

vue生命周期的理解:

總共分為 8 個階段創(chuàng)建前/后,載入前/后,更新前/后,銷毀前/后。
創(chuàng)建前/后: 在beforeCreate 階段,vue 實例的掛載元素 el 還沒有。
載入前/后:在 beforeMount 階段,vue 實例的$el 和 data 都初始化了,但還是掛載之前為虛擬的 dom 節(jié)點,data.message 還未替換。在 mounted 階段,vue 實例掛載完成,data.message 成功渲染。
更新前/后:當 data 變化時,會觸發(fā)beforeUpdateupdated 方法。
銷毀前/后:在執(zhí)行 destroy 方法后,對 data 的改變不會再觸發(fā)周期函數(shù),說明此時 vue 實例已經(jīng)解除了事件監(jiān)聽以及和 dom 的綁定,但是 dom 結(jié)構(gòu)依然存在。

vue的雙向綁定的原理:

vue.js 是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過 Object.defineProperty()來劫持各個屬性的 setter,getter,在數(shù)據(jù)變動時發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)。

具體步驟:

  • 第一步:需要 observe 的數(shù)據(jù)對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter 和 getter 這樣的話,給這個對象的某個值賦值,就會觸發(fā) setter,那么就能監(jiān)聽到了數(shù)據(jù)變化。
  • 第二步:compile 解析模板指令,將模板中的變量替換成數(shù)據(jù),然后初始化渲染頁面視圖,并將每個指令對應(yīng)的節(jié)點綁定更新函數(shù),添加監(jiān)聽數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動,收到通知,更新視圖。
  • 第三步:Watcher 訂閱者是 Observer 和 Compile 之間通信的橋梁,主要做的事情是:
    在自身實例化時往屬性訂閱器(dep)里面添加自己;
    自身必須有一個 update()方法;
    待屬性變動 dep.notice()通知時,能調(diào)用自身的 update() 方法,并觸發(fā) Compile 中綁定的回調(diào),則功成身退。
  • 第四步:MVVM 作為數(shù)據(jù)綁定的入口,整合 Observer、Compile 和 Watcher 三者,通過 Observer 來監(jiān)聽自己的 model 數(shù)據(jù)變化,通過 Compile 來解析編譯模板指令,最終利用 Watcher 搭起 Observer 和 Compile 之間的通信橋梁,達到數(shù)據(jù)變化 -> 視圖更新;視圖交互變化(input) -> 數(shù)據(jù) model 變更的雙向綁定效果。

vuex相關(guān):

有 5 種屬性,分別是 state、getter、mutation、action、module。

  • store 特性:
    vuex 就是一個倉庫,倉庫里放了很多對象。其中 state 就是數(shù)據(jù)源存放地,對應(yīng)于一般 vue 對象里面的 data。
    state 里面存放的數(shù)據(jù)是響應(yīng)式的,vue 組件從 store 讀取數(shù)據(jù),若是 store 中的數(shù)據(jù)發(fā)生改變,依賴這相數(shù)據(jù)的組件也會發(fā)生更新。
    它通過 mapState 把全局的 state 和 getters 映射到當前組件的 computed 計算屬性。
  • getter 特性:
    getter 可以對 state 進行計算操作,它就是 store 的計算屬性。
    雖然在組件內(nèi)也可以做計算屬性,但是 getters 可以在多給件之間復(fù)用。
    如果一個狀態(tài)只在一個組件內(nèi)使用,是可以不用 getters。
  • mutation 特性:
    action 類似于 muation, 不同在于:action 提交的是 mutation,而不是直接變更狀態(tài)。
    action 可以包含任意異步操作。

注冊全局組件:

在components下寫好test.vue組件模板,然后在main.js中引入再全局注冊:

import testel from './components/test';
Vue.component('testel ',testel );

vue組件之間的傳值:

  1. 父組件向子組件傳遞數(shù)據(jù)
//父組件通過標簽上面定義傳值
<template>
    <Main :obj="data"></Main>
</template>
<script>
    //引入子組件
    import Main form "./main"
    exprot default{
        name:"parent",
        data(){
            return {
                data:"我要向子組件傳遞數(shù)據(jù)"
            }
        },
        //初始化組件
        components:{
            Main
        }
    }
</script>

//子組件通過props方法接受數(shù)據(jù)
<template>
    <div>{{data}}</div>
</template>
<script>
    exprot default{
        name:"son",
        //接受父組件傳值
        props:["data"]
    }
</script>
  1. 子組件向父組件傳遞數(shù)據(jù)
//子組件通過$emit方法傳遞參數(shù)
<template>
   <div v-on:click="events"></div>
</template>
<script>
    //引入子組件
    import Main form "./main"
    exprot default{
        methods:{
            events:function(params){
              console.log(params)
            }
        }
    }
</script>
<template>
    <div v-on:click="emitEvent">{{data}}</div>
</template>
<script>
    exprot default{
        name:"son",
        //接受父組件傳值
        props:["data"],
        methods: {
          emitEvent() {
            this.$emit('event', params) // 派發(fā)函數(shù),并傳遞值,params是你自己想傳的值
          }
        }
    }
</script>

默認顯示子路由:

  routes: [
    {path: '/',
      name: 'home',
      component: home,
      children: [{  path: '/echarts',  name: 'echarts',  component: echarts },
              { path: '/index', name: 'index',component: index}],redirect:'/index' }] 
         }]     //通過redirect:'/index' 默認顯示index

Vue中使用echarts:

  <template>
<!-- 定義一個承載容器 -->
      <div id="chartshow" style=" height:500px;"></div>
  </template>

<script>
import echarts from "echarts"; //引入echarts 
//此外在main.js中還需要再引入echarts ,并按照官方的方式Vue.prototype.$echarts = echarts 使用.
export default {
  data() {
    return {
      chartshow: null
    };
  },
  methods: {
    drawshowChart() {
      this.chartshow = echarts.init(document.getElementById("chartshow"));
      this.chartshow.setOption({
    //以下是echarts的數(shù)據(jù)
        tooltip: {
          trigger: "item",
          formatter: "{a} <br/>: {c} (u0z1t8os%)"
        },
        legend: {
          orient: "vertical",
          x: "left",
          data: [
            "直達",
            "營銷廣告",
            "搜索引擎",
            "郵件營銷",
            "聯(lián)盟廣告",
            "視頻廣告",
            "百度",
            "谷歌",
            "必應(yīng)",
            "其他"
          ]
        },
        series: [
          {
            name: "訪問來源",
            type: "pie",
            selectedMode: "single",
            radius: [0, "30%"],
            label: {
              normal: {
                position: "inner"
              }
            },
            labelLine: {
              normal: {
                show: false
              }
            },
            data: [
              { value: 335, name: "直達", selected: true },
              { value: 679, name: "營銷廣告" },
              { value: 1548, name: "搜索引擎" }
            ]
          },
          {
            name: "訪問來源",
            type: "pie",
            radius: ["40%", "55%"],
            label: {
              normal: {
                formatter: "{a|{a}}{abg|}\n{hr|}\n  {b|:}{c}  {per|u0z1t8os%}  ",
                backgroundColor: "#eee",
                borderColor: "#aaa",
                borderWidth: 1,
                borderRadius: 4,
                rich: {
                  a: {
                    color: "#999",
                    lineHeight: 22,
                    align: "center"
                  },
                  hr: {
                    borderColor: "#aaa",
                    width: "100%",
                    borderWidth: 0.5,
                    height: 0
                  },
                  b: {
                    fontSize: 16,
                    lineHeight: 33
                  },
                  per: {
                    color: "#eee",
                    backgroundColor: "#334455",
                    padding: [2, 4],
                    borderRadius: 2
                  }
                }
              }
            },
            data: [
              { value: 335, name: "直達" },
              { value: 310, name: "郵件營銷" },
              { value: 234, name: "聯(lián)盟廣告" },
              { value: 135, name: "視頻廣告" },
              { value: 1048, name: "百度" },
              { value: 251, name: "谷歌" },
              { value: 147, name: "必應(yīng)" },
              { value: 102, name: "其他" }
            ]
          }
        ]
      });
    }, //數(shù)據(jù)結(jié)束
              drawCharts() {  
              this.drawshowChart();
                          }
  },  //methods結(jié)束
              mounted: function() {
              this.drawCharts();
  },
              updated: function() {
              this.drawCharts();
  }
};
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容