Vue2.0 基礎入門


前言:" 今生遇汝,何其幸哉;於我蒙昧之時遇到你,於我大霧初透之時愛上你,於我大智初醒之時沉淪你。 "

官網: 介紹 — Vue.js (vuejs.org)

指令與修飾符

創建實例

<div id="app">
  {{ message }}
</div>
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

結果 Hello Vue!

v-html

    <div id="box">
        <!-- v-html -->
        <div v-html="myhtml"></div>
    </div>

    <script type="text/javascript">
        new Vue({
            el: "#box",
            data: {
                myhtml: "<b>1111</b>"
            }

        })
    </script>
v-html,防止xSS,csrf (
	(1)前端過濾
	(2)后台轉義(< > &lt;&gt;)
	(3)給cookie加上屬性http
)

v-cloak與v-text

  • 使用 v-cloakv-text 與能夠解決插值表達式閃爍的問題
<p v-cloak>{{msg}}</p>
<p v-text="msg"></p>

//=====
<style>

  [v-cloak]{
      display: none;
  }  
    
</style>

v-show 與 v-if

    <div id="box">
        <div v-show="isShow">動態顯示與隱藏</div>
        <div v-if="isCreated">動態創建與刪除</div>

    </div>

    <script type="text/javascript">
        new Vue({
            el: "#box",
            data: {
                isShow: false,
                isCreated: true
            }
        })
    </script>

vue-class 綁定

    <div id="box">
        <div :class="isActive?'red':'yellow'">
            我的樣式是動態切換的!----三目寫法
        </div>
        <button @click="handleClick()">click</button>
        <div :class="classObj">
            我的樣式是動態切換的!----對象寫法
        </div>
        <div :class="classArr">
            我的樣式是動態切換的!----數組寫法
        </div>
    </div>

    <script type="text/javascript">
        new Vue({
            el: "#box",
            data: {
                isActive: true,
                classObj: {
                    a: true,
                    b: true
                }, // a,b 為class名稱
                classArr: ["a","b"]
            },
            methods: {
                handleClick() {
                    this.isActive = !this.isActive
                }
            }

        })
    </script>

vue-style 綁定

    <div id="box">
        
        <button @click="handleClick()">click</button>
        <div :style="'background:'+isActive?'red':'yellow'">
            我的樣式是動態切換的!----三目寫法
        </div>
        <div :style="styleObj">
            我的樣式是動態切換的!----對象寫法
        </div>
        <div :style="styleArr">  
            我的樣式是動態切換的!----數組寫法
        </div>
    </div>

    <script type="text/javascript">
        new Vue({
            el: "#box",
            data: {
                isActive: true,
                styleObj: {
                   backgroundColor: "red"
                }, 
                styleArr: ["a","b"]  //建議使用數組  shift()刪除所有的樣式
            },
            methods: {
                handleClick() {
                    this.isActive = !this.isActive
                }
            }

        })
    </script>

vue 條件渲染

    <div id="box">

        <button @click="handleClick()">click</button>
        <div v-if="isCreated">動態的創建與刪除----111</div>
        <div v-else>動態的創建與刪除----222</div>
        <!-- 實例 -->
        <ul v-if="dataList.length">
            <li v-for="data in dataList">
                {{data}}
            </li>
        </ul>
        <div v-else>空空如也</div>


    <div v-if="which==1">111</div>
    <div v-else-if="which==2">222</div>
    <div v-else>333</div>

</div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#box",
            data: {
                isCreated: true,
                dataList: [],
                which: 1
            },
            methods: {
                handleClick() {
                    this.isCreated = !this.isCreated,
                        this.dataList = ["111", "2222"]
                }
            }

        })
    </script>

vue 列表渲染

    <div id="box">
        <ul>
            <li v-for="(data,index) in dataList">
                {{data}}----{{index}}
            </li>
        </ul>

        <ul>
            <li v-for="(data,index) of dataList">
                {{data}}----{{index}}
            </li>
        </ul>

        <ul>
            <li v-for="(data,key) in dataObj">
                {{data}}----{{key}}
            </li>
        </ul>


    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#box",
            data: {
                dataList: ["111", "2222", "333"],
                dataObj: {
                    name: "qiandu",
                    age: 18,
                    sex: "男"
                }
            }
        })
    </script>

vue 列表key值設置

跟蹤每個節點的身份,從而重用和重新排序現有元素

理想的 key值是每項都有的且唯一的id。data.id

列表數組檢測

a.使用以下方法操作數組,可以檢測變動

  push()  pop()   shift()    unshift()  splice() sort()    reverse()

b. filter(), concat() 和 slice() ,map(),新數組替換舊數組

c.不能檢測以下變動的數組

  • vm.items [ indexOfltem] = newValue

  • 解決 (1) Vue.set(example1.items, indexOfltem, newValue)

    ​ (2)splice

過濾--模糊查詢

 <div id="box">

        <input type="text" @input="handleInput()" v-model="mytext" />
        <!-- @change 只要失去焦點就會觸發 -->
        <ul>
            <li v-for="data in dataList">
                {{data}}
            </li>
        </ul>

    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#box",
            data: {
                mytext: '',
                dataList: ["111", "2222", "333"],
            },
            methods: {
                handleInput() {
                    // console.log("只要value改變 就會觸發");
                    //利用輸入框的字符,過濾包含字段的元素
                    //filter 過濾

             var newList = this.dataList.filter(item => item.indexOf(this.mytext) > -1);
                    console.log(newList);

                   /*  改變列表值 有兩種方法  
                   
                            1. 復制一份數組  List: ["111", "2222", "333"]
        var newList = this.List.filter(item => item.indexOf(this.mytext) > -1);
                            this.dataList = newList;
                            2. 計算屬性 后期使用
                   */
                }
            }
        })
    </script>

事件處理器

在這里插入圖片描述

    <div id="box">

        <!-- 無需參數 -->
        <button @click="handleClick()">click1</button>
        <!-- 需要參數 -->
        <button @click="handleClick">click2</button>
        <!-- 語句簡單 盡量避免 -->
        <button @click="isCreated = !isCreated">click3</button>
        <div v-show="isCreated">動態的創建與刪除----111</div>

</div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#box",
            data: {
                isCreated: false,
            },
            methods: {
                handleClick() {
                    this.isCreated = !this.isCreated;
                }
            }

        })
    </script>

事件修飾符

    <div id="box">
        <!-- 點自己才會觸發 -->
        <ul @click.self="handleULClick">
            <li @click.stop="handleLiClick"> 111</li>
            <li @click.once="handleLiClick"> 222</li>
            <li @click="handleLiClick"> 111</li>
        </ul>

        <a href="www.baidu.com" @click.prevent="handleChangePage">changePage</a>

    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#box",
            data: {
                isCreated: false,
            },
            methods: {
                // handleClick() {
                //     this.isCreated = !this.isCreated;
                // }
                handleLiClick(ev) {
                    //  ev.stopPropagation(); 原生
                    console.log("111");
                },
                handleULClick() {
                    console.log("222");
                },
                handleChangePage(ev) {
                   //   ev.preventDefault();  阻止默認
                    console.log("333")
                }
            }
        })
    </script>

按鍵修飾符

 <div id="box">

        <a href="www.baidu.com" @click.prevent="handleChangePage">changePage</a>

        <!-- 鍵值也可以 -->
        <input type="text" @keyup.enter="handleULClick($event)" />

    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#box",
            data: {
            },
            methods: {
                handleULClick() {
                    console.log("222");
                    //傳統方法
                    // if (ev.keyCode === 13) {
                    //     //....13表示回車鍵
                    // }

                },
            }
        })
    </script>

表單控件綁定

   <div id="box">
        <input type="text" v-model="mytext">
        <textarea name="" id="" cols="30" rows="10" v-model="mytext"></textarea>
        {{mytext}}
        <br>
        <input type="checkbox" v-model="isChecked">記住我
        <br>
        <p>你喜歡的運動為:
            <input type="checkbox" v-model="checkgroup" value="游泳" />游泳
            <input type="checkbox" v-model="checkgroup" value="滑冰" />滑冰
        </p>
        {{checkgroup}}
        <br>
        <p>你最喜歡的運動為:
            <input type="radio" v-model="picked" value="游泳" />游泳
            <input type="radio" v-model="picked" value="滑冰" />滑冰
        </p>
        {{picked}}

    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#box",
            data: {
                mytext: "aaaa",
                isChecked: true,
                checkgroup: [],
                picked: ""
            }
        })
    </script>

購物車案例

    <div id="box">
        <input type="checkbox" @change="handleChange" v-model="isAllChecked">
        <ul>
            <li v-for="data in dataList">
                <input type="checkbox" v-model="checkGroup" :value="data" @change="handleLiChange">
                {{data}}
                <button @click="data.number++">add</button>
                {{data.number}}
                <button @click="handleDelClick(data)">del</button>
            </li>
        </ul>
        {{checkGroup}}
        <p>總金額為:{{getSum()}}</p>
    </div>
    <script type="text/javascript">
        new Vue({
            el: "#box",
            data: {
                checkGroup: [],
                isAllChecked: false,
                dataList: [
                    {
                        name: "商品1",
                        price: 10,
                        number: 1,
                        id: "1"
                    },
                    {
                        name: "商品2",
                        price: 20,
                        number: 4,
                        id: "2"
                    }
                ]
            },
            methods: {
                getSum() {
                    //函數計算的狀態改變,會自動執行一次
                    var sum = 0;

                    for (var i in this.checkGroup) {
   sum += this.checkGroup[i].number * this.checkGroup[i].price;
                    }
                    return sum;
                },
                handleChange() {
                    if (this.isAllChecked) {
                        this.checkGroup = this.dataList;
                    } else {
                        this.checkGroup = [];
                    }
                },
                handleLiChange() {
                    if (this.dataList.length === this.checkGroup.length) {
                        this.isAllChecked = true;
                    } else {
                        this.isAllChecked = false;
                    }
                },
                handleDelClick(data) {
                    if (data.number != 0) {
                        data.number--
                    } else { data.number = 0 }

                }
            }
        })
    </script>

表單修飾符

        <!-- 失去焦點才顯示 -->
        <input type="text" v-model.lazy="mytext">
        <!-- 只能輸入數字 效果不好 -->
        <input type="text" v-model.number="mynumber">
        <!-- 去除收尾空格 -->
        <input type="text" v-model.trim="myname">

axios

  • 方式一
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
   aaa: function () {
                    axios.get("xxx").then((res) => {
                        console.log(res.data)
                    }).catch((err) => {

                    });
                },
   bbb: function () {
                    axios.post("xxx", {
                        //請求參數
                    }).then(res => {
                        console.log(res.data)
                    }).catch(err => {
                        console.log(err)
                    })
                }
  • 方式二
  1. 安裝axios依賴
npm install axios
  1. 在main.js中引入
import axios from 'axios'

Vue.prototype.$axios = axios;
  1. 使用
mounted() {
    this.$axios.get('http://www.liulongbin.top:3005/api/getlunbo')
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
  }

vue引入Axios

隨筆-vue項目引入axios

使用增刪改查

npm 安裝axios和使用增刪改查

Vue項目引入Axios 插件(封裝):

Vue項目引入Axios 插件(封裝) - 簡書 (jianshu.com)

  • 完整寫法
    axios({
        url:"",
        headers:{

        }
    }).then(res=>{
			console.log(res.data)
    }).catch(err => {
            console.log(err)
    })

計算屬性

  • 定義像函數 使用像屬性
  • 計算屬性會緩存

計算屬性模糊查詢

    <div id="box">

        <input type="text" v-model="mytext" />
        <!-- @change 只要失去焦點就會觸發 -->
        <ul>
            <li v-for="data in getDataList">
                {{data}}
            </li>
        </ul>

    </div>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#box",
            data: {
                mytext: '',
                dataList: ["111", "2222", "333"],
            },
            computed: {
                getDataList() {
 return this.dataList.filter(item => item.indexOf(this.mytext) > -1)
                }
            }
        })
    </script>

組件化開發

定義全局組件

    <div id="box">
        <navbar></navbar>

    </div>

    <script type="text/javascript">
        //1.全局定義組件(作用域隔離)
        Vue.component("navbar", {
            template: `
            <div @click="handleback()" style="background:red">
            我是導航欄
            </div>
            `,
            methods: {
                handleback() {
                    console.log("back...")
                }
            }
        })

        new Vue({
            el: "#box",
        })
    </script>

局部

  <div id="box">
        <navbar></navbar>

    </div>

    <script type="text/javascript">
        //1.全局定義組件(作用域隔離)
        Vue.component("navbar", {
            template: `
            <div @click="handleback()" style="background:red">
            我是導航欄
            <child></child>
            <navbarchild></navbarchild>
            </div>
           
            `,
            methods: {
                handleback() {
                    console.log("back...")
                }
            },
            components: {
                navbarchild: {
                    template: `
                         <div >
                          我是child組件----局部定義
                         </div>
                       `
                }
            } //局部
        })

        //全局
        Vue.component("child", {
            template: `
            <div  style="background:green">
            我是child組件----全局定義
            </div>
            `,
            methods: {
                handleback() {
                    console.log("back...")
                }
            }
        })

        new Vue({
            el: "#box",
        })
    </script>

在這里插入圖片描述

父傳子與屬性驗證

  <div id="box">
        <navbar myname="home" :myshow="false"></navbar>
        <navbar myname="list" :myshow="true"></navbar>
        <navbar :myname="parentname" :myshow="true"></navbar>
    </div>

    <script type="text/javascript">
        //全局
        Vue.component("navbar", {
            template: `
            <div  style="background:green">
            <button v-show="myshow">返回</button>
            導航欄----{{myname}}
            <button v-show="myshow">首頁</button>
            </div>
            `,
           // props: ["myname","myshow"]  //接收父組件傳來的屬性  js代碼用v-bind
		  //屬性驗證
            props:{
                myname:String,
                myshow:Boolean
            }
        })

        new Vue({
            el: "#box",
            data: {
                parentname: "parentname屬性"
            }
        })
    </script>

在這里插入圖片描述

子傳父

    <div id="box">
        <navbar @myevent="handleEvent($event)"></navbar>
        <!-- 或者 -->
        <navbar @myevent="handleEvent"></navbar>
    </div>

    <script type="text/javascript">

        //全局
        Vue.component("navbar", {
            template: `
            <div  style="background:green">
            <button @click="pay()">返回</button>
            </div>
            `,
            data() {
                return {
                    txt: "子組件的內容"
                }
            },
            methods: {
                pay() {
                    this.$emit("myevent",this.txt)  //分發事件
                }
            }
        })

        new Vue({
            el: "#box",
            data: {
                parentname: "parentname屬性"
            },
            methods: {
                handleEvent() {
                    console.log("父組件收到!")
                }
            }
        })
    </script>
  • 案例 側邊欄的隱藏與顯示
  <div id="box">
        <!-- 2.觸發后 執行父組件方法 -->
        <navbar @myevent="handleEvent($event)"></navbar>
        <sidebar v-show="isShow"></sidebar>
    </div>

    <script type="text/javascript">

        Vue.component("navbar", {
            template: `<div>
            <button @click="handleClick">點擊</button>
             </div>
                `,
            methods: {
                handleClick() {
                    this.$emit("myevent")    //1.點擊按鈕 觸發回調函數 找到 myevent
                }
            }
        })

        Vue.component("sidebar", {
            template: `
            <div>
                <ul>
                  <li>
                     選項1 
                  </li>
                  <li>
                     選項2
                  </li>
                </ul>
            </div>`
        })

        new Vue({
            el: "#box",
            data: {
                isShow: false
            },
            methods: {
                handleEvent() {
                    this.isShow = !this.isShow  //3. 控制
                }
            }
        })
    </script>

  • 方法改造
   <div id="box">
        <!-- 2.觸發后 執行父組件方法 -->
        <navbar>
            <button @click="handleEvent($event)">點擊</button>
        </navbar>
        <sidebar v-show="isShow"></sidebar>
    </div>

    <script type="text/javascript">

        Vue.component("navbar", {
            template: `<div>
             <slot></slot>
             </div>
        })
        Vue.component("sidebar", {
            template: `
            <div>
                <ul>
                  <li>
                     選項1 
                  </li>
            </div>`
        })

        new Vue({
            el: "#box",
            data: {
                isShow: false
            },
            methods: {
                handleEvent() {
                    this.isShow = !this.isShow  //3. 控制
                }
            }
        })
    </script>

父傳子靠屬性,子傳父靠事件**

ref-父子通信通信

    <div id="box">
        <input type="text" ref="mytext">
        <button @click="handleEvent()">click</button>
        <child ref="mychild"></child>

    </div>

    <script type="text/javascript">

        Vue.component("child", {
            template: `
            <div>
                child
                </div>
            `,
            data() {
                return {
                    name: "childName"
                }
            },
            methods: {
                aa(data) {
                    console.log("自己的", data)
                }
            }

        })
        new Vue({
            el: "#box",
            methods: {
                handleEvent() {
                    console.log(this.$refs.mytext.value)
                    console.log(this.$refs.mychild)
                    this.$refs.mychild.aa("傳過去的")
                }
            }
        })

        /*
            絕對的控制權
         1. ref放在標簽上拿到的是原生節點
         2. ref放在組件上,拿到的是組件對象
        */
    </script>

非父子通信--事件總線

    <div id="box">
        <author></author>
        <user></user>
    </div>

    <script type="text/javascript">
        /* 創建事件總線 $emit與$on */
        //創建空的vue實例賦值給一個變量
        var bus = new Vue();

        Vue.component("author", {
            template: `
            <div>
             <input type="text" ref="mytext" />
             <button @click="handleClick()">發布</button>
                </div>
                `,
            methods: {
                handleClick() {
                    bus.$emit("mseeage",this.$refs.mytext.value)
                }
            }
        })

        Vue.component("user", {
            //合適的位置訂閱=>當前組件創建完成時 bus.$on
            template: `
            <div>
            我是用戶
                </div>
            `,
            mounted() {  //組件創建完調用
                bus.$on("mseeage", (data) => {
                    console.log("收到推送",data)
                })
                console.log("生命周期函數--當前組件dom創建完成之后就會調用")
            }
        })
    </script>

動態組件

在這里插入圖片描述

    <div id="box">
        <!-- vue 提供動態組件  is屬性 -->
        <component is="home"></component>

        <!-- 避免重新渲染 -->
        <keep-alive>
            <component is="home"></component>
        </keep-alive>
    </div>

    <script type="text/javascript">
        new Vue({
            el: "#box",
            components: {
                "home": {
                    template: `<div>home組件</div>`
                },
                "list": {
                    template: `<div>list組件</div>`
                },
                "footer": {
                    template: `<div>footer組件</div>`
                }
            }
        })
    </script>

slot插槽

在這里插入圖片描述

  • 使用場景:輪播圖
    <div id="box">
        <swiper>
            <li v-for="data in dataList">
                {{data}}
            </li>
        </swiper>
    </div>

    <script type="text/javascript">
        Vue.component("swiper", {
            template: `
            <div>
                 <ul>
                    <slot></slot>
                 </ul>
             </div>
            `
        })
        new Vue({
            el: "#box",
            data: {
                dataList: ["1111", "222", "333"]
            }
        })
    </script>
  • 具名插槽 [ name 與 slot ]
 <div id="box">
        <swiper>
           <p slot="a">111</p>
           <p slot="b">222</p>
        </swiper>
 </div>

//=============================
 Vue.component("swiper", {
            template: `
            <div>
                 <slot name="a"></slot>
                 ---------------------
                 <slot name="b"></slot>
             </div>
            `
        })

元素過度

不在詳細學習 具體請看教程

動畫效果

在這里插入圖片描述

<link href="https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css" rel="stylesheet">
    
//或者
    
npm install animate.css
// or
yarn install animate.css    

使用詳解===> Vue.animate.css組件庫的使用的詳細解析

生命周期

生命周期

超強VUE教程(強烈推薦)_嗶哩嗶哩_bilibili

  • mounted:頁面一創建發送ajax請求
  • dom節點更新完之后的操作放入updated之中

在這里插入圖片描述

過濾器

		<!-- 格式:要有空格 -->
 <img src="xxx.jpg | aaafilter" alt="">

			<!-- js -->
//過濾器
Vue.filter("aafilter", function (data) {
      return data.replce("xxx", "xxxx");  //替換源---替換目標
 })

在這里插入圖片描述

Swiper輪播

  • 引入cdn
    <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.css">
    <script src="https://unpkg.com/swiper/swiper-bundle.js"> </script>
  • 實例
 <div id="box">
        
        <div class="swiper-container">
            <div class="swiper-wrapper">
                <div class="swiper-slide" v-for="data in dataList" style="width: 300px;height: 300px;">
                    {{data}}
                </div>

            </div>
            <!-- 如果需要分頁器 -->
            <div class="swiper-pagination"></div>

            <!-- 如果需要導航按鈕 -->
            <div class="swiper-button-prev"></div>
            <div class="swiper-button-next"></div>

            <!-- 如果需要滾動條 -->
            <div class="swiper-scrollbar"></div>
        </div>

    </div>

    <script type="text/javascript">

        new Vue({
            el: "#box",
            data: {
                dataList: []
            },
            mounted() {    //swiper放入mounted會出現初始化過早問題
                setTimeout(() => {
                    this.dataList = ["1111", "2222", "3333"]   //異步更新dom節點
                }, 2000)
            },
            updated() {
                new Swiper('.swiper-container', {
                    //   direction: 'vertical', // 垂直切換選項
                    loop: true, // 循環模式選項
                    // 如果需要分頁器
                    pagination: {
                        el: '.swiper-pagination',
                        clickable: true

                    },

                    // 如果需要前進后退按鈕
                    navigation: {
                        nextEl: '.swiper-button-next',
                        prevEl: '.swiper-button-prev',
                    },

                    // 如果需要滾動條
                    scrollbar: {
                        el: '.swiper-scrollbar',
                    },
                    //設置自動輪播
                    autoplay: true
                })
            }
        })
    </script>

上述方法使用太麻煩,我們封裝成組件

<!-- css 自己設置 -->
     <swiper :key="dataList.length">
            <div class="swiper-slide" v-for="data in dataList" style="width: 300px;height: 300px;">
                {{data}}
            </div>
      </swiper>
//===================================
  Vue.component("swiper", {
            template: `
            <div class="swiper-container">
            <div class="swiper-wrapper">
              <slot></slot>
            </div>
            <!-- 如果需要分頁器 -->
            <div class="swiper-pagination"></div>
            <!-- 如果需要導航按鈕 -->
            <div class="swiper-button-prev"></div>
            <div class="swiper-button-next"></div>
            <!-- 如果需要滾動條 -->
            <div class="swiper-scrollbar"></div>
        </div>
             `,
            mounted() {
                new Swiper('.swiper-container', {
                    //   direction: 'vertical', // 垂直切換選項
                    loop: true, // 循環模式選項
                    // 如果需要分頁器
                    pagination: {
                        el: '.swiper-pagination',
                        clickable: true
                    },
                    // 如果需要前進后退按鈕
                    navigation: {
                        nextEl: '.swiper-button-next',
                        prevEl: '.swiper-button-prev',
                    },
                    // 如果需要滾動條
                    scrollbar: {
                        el: '.swiper-scrollbar',
                    },
                    //設置自動輪播
                    autoplay: true
                })
            }
        })
  • 用指令封裝
  <div id="box">
        <div class="swiper-container">
            <div class="swiper-wrapper">
                <div class="swiper-slide" v-for="(data,index) in dataList" 		           style="width: 300px;height: 300px;" v-swiper=" {
                    index:index,
                    length:dataList.length
                }">
                    {{data}}
                </div>
            </div>
            <!-- 如果需要分頁器 -->
            <div class="swiper-pagination"></div>

            <!-- 如果需要導航按鈕 -->
            <div class="swiper-button-prev"></div>
            <div class="swiper-button-next"></div>
        </div>

    </div>
    <script type="text/javascript">
        Vue.directive("swiper", {
            inserted(el, bind) {
                if (bind.value.index === bind.value.length - 1) {
                    new Swiper('.swiper-container', {
                        //   direction: 'vertical', // 垂直切換選項
                        loop: true, // 循環模式選項
                        // 如果需要分頁器
                        pagination: {
                            el: '.swiper-pagination',
                            clickable: true

                        },
                        // 如果需要前進后退按鈕
                        navigation: {
                            nextEl: '.swiper-button-next',
                            prevEl: '.swiper-button-prev',
                        },
                        // 如果需要滾動條
                        scrollbar: {
                            el: '.swiper-scrollbar',
                        },
                    })
                }
            }
        })

        new Vue({
            el: "#box",
            data: {
                dataList: []
            },
            mounted() {
                setTimeout(() => {
                    this.dataList = ["1111", "2222", "3333"]
                }, 2000)

            }
        })
    </script>

指令用法

  • 自定義指令 自己可以操作 Dom

在這里插入圖片描述

  <div id="box">
        <div v-qiandu="'red'">1111</div>
        <div v-qiandu="color">1111</div>
    </div>
    <script type="text/javascript">

        Vue.directive("qiandu", {
            inserted(el, bind) {  //el:獲取dom
                //插入指令  ----創建階段  只執行一次
                console.log("當前節點插入到父節點中了")
                console.log(el)
                console.log(bind)
                el.style.background=bind.value   //改變背景色
            },
            update(el, bind) {
                el.style.background=bind.value
            }
        })

        new Vue({
            el: "#box",
            data: {
                color:"yellow"
            },
            computed: {

            }
        })
    </script>

腳手架

cli配置

安裝Node.js

配置 ===> 安裝npm及cnpm(Windows) - 山高我為峰 - 博客園 (cnblogs.com)

Vue cli安裝

安裝 | Vue CLI (vuejs.org)

npm install -g @vue/cli
# OR
yarn global add @vue/cli

創建腳手架

  1. 創建路徑運行終端 輸入
 vue create xxx
  1. 一系列設置

具體配置教程: 腳手架配置

參考文章: VueCLI v4.5.4 創建vue項目(手選模式創建)_{竹子} -CSDN博客

在這里插入圖片描述

  • 所有的靜態資源全部放入public文件夾下 引入到index.html
<link rel="stylesheet" href="<%= BASE_URL %>public下的文件路徑">
  • 模塊化引入css
import 'swiper/dist/css/swiper.css'

單文件組件

在這里插入圖片描述

  • 以xxx.vue命名
  • 結構樣式

在這里插入圖片描述

基本寫法

<template>

</template>

<script>
export default {
    
};
</script>

<style>
</style>

例子

//Navbar.vue
<template>
  <nav>導航欄</nav>
</template>

//APP.vue

<template>
  <div id="app">
    <!-- <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/> -->
    <p>HelloWorld</p>
    <Navbar></Navbar>
    <siderbar></siderbar>
  </div>
</template>

<script>
import Navbar from "./components/Navbar.vue";
import Siderbar from "./components/Siderbar.vue";
// import Vue from "vue";
// Vue.component("Navbar", NavBar);
// Vue.component("Siderbar", Siderbar);

export default {
  name: "App",
  components: {
    Navbar:Navbar,
    Siderbar:Siderbar,
  },
};
</script>

注意!!!為防止互相影響 加上 scoped屬性

打包

修復錯誤

npm run lint

上線項目

npm run build

成功生成dist文件夾拷出里面文件即可

跨域請求

解決跨域請求vue.config.js配置(與 package.json )同級

官方文檔 配置參考 | Vue CLI (vuejs.org)

注意:更改配置文件要重啟服務器

module.exports = {
    devServer: {
      proxy: {
        '/api': {     // *: 所有請求都會轉到target
          target: '<url>',  
        //   ws: true,
          changeOrigin: true
        },
        '/api': {     // 第二個
            target: '<url>',  
          //   ws: true,
            changeOrigin: true
          },
        // '/foo': {
        //   target: '<other_url>'
        // }
      }
    }
  }

  //比如 http:www.baidu.com/ajax?&q=ewqe
  // api填寫:ajax
  //target填:http:www.baidu.com
  //axios填寫后面字段:/ajax?&q=ewqe

路由

  • 寫法

在這里插入圖片描述

路由配置

  • 路徑改變,頁面不會刷新

相關配置教程 vue的路由安裝及配置

關於components與views文件夾

  • 把需要共享的組件放入到 components 文件夾中
  • 把單頁面或者只用於一次的組件放入到 views 之中
  1. 引入路由 新建 vouter.jsmain.js同級
npm install vue-router
  1. 編寫路由
import Vue from 'vue' // 引入vue
import VRouter from 'vue-router' // 引入路由
import File  from '@/views/File' // 引入需要用到路由的頁面  @:表示指向src文件夾
import Center from '@/views/Center'

Vue.use(VRouter) // vue使用路由

export default new VRouter({ // 創建路由
    mode: 'history', // 去掉鏈接中的#  /File || /#/File
    routes: [ // 此處寫路由  放入數組
        {
            path: '/File', // 鏈接中的顯示路勁
            name: 'File', // 名字
            component: File // 引入的路由名稱,必須與import里的名稱一樣
        }
    ]
})
  1. main.js引入
import router from './router'

Vue.config.productionTip = false

new Vue({
  router: router,  //key與value相同時,可以簡寫為router
  render: h => h(App),
}).$mount('#app')
  1. 使用
<template>
  <div id="app">
    <!-- <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/> -->
    <p>HelloWorld</p>
    <Navbar></Navbar>
    <siderbar></siderbar>
    <!-- 路由容器 -->
    <router-view></router-view>
  </div>
</template>
  1. 在 ```views文件夾下編寫相應的vue文件``

聲明式導航

  • (點擊)事件跳轉到相應路由

在這里插入圖片描述

router-link 可以達到高亮顯示效果----同步變化

  • to :/url
  • tag:標簽
  • active-class:class
<template>
  <div>
    <ul>
      <!-- 聲明式導航 -->
      <router-link to="/File" tag="li" active-class="myactive"
        >file</router-link>
      <router-link to="/Center" tag="li" active-class="myactive"
        >center</router-link
      >
      <!-- 作用與下方相同 -->
      <!-- <li>
        <a href="/File">-File-</a>
      </li>
      <li>
        <a href="/Center">-Center-</a>
      </li> -->
    </ul>
  </div>
</template>

<style scoped>
.myactive {
  color: red;
}
</style>

重定向

默認顯示或者請求url錯誤顯示

import Vue from 'vue' // 引入vue
import VRouter from 'vue-router' // 引入路由

Vue.use(VRouter) // vue使用路由

export default new VRouter({ // 創建路由
    mode: 'history', // 去掉鏈接中的#  /File || /#/File
    routes: [ // 此處寫路由  放入數組
        {
            path:'*',
            redirect:'/File'
        }
    ]
})

二級路由

  • 例子
http://localhost:8080/#/File/aaa
http://localhost:8080/#/File/bbb
  1. router.js
import Vue from 'vue' // 引入vue
import VRouter from 'vue-router' // 引入路由

Vue.use(VRouter) // vue使用路由

export default new VRouter({ // 創建路由
    // mode: 'history', // 去掉鏈接中的#  /File || /#/File
    routes: [ // 此處寫路由  放入數組
        {
            path: '/File', // 鏈接中的顯示路勁
            name: 'File', // 名字
            component: File, 
            children:[    //二級路由數組
                {
                    path:'',  //此路徑無需加不能加 /
                    component:File  
                }
            ]
        }
    ]
})

  1. 父組件留插槽
    <!-- 路由容器 -->
    <router-view></router-view>
  1. 創建相應的子組件 並有完整的項目結構 二級放入一級文件夾下

設置子路由默認路徑

import Vue from 'vue' // 引入vue
import VRouter from 'vue-router' // 引入路由
import File from '@/views/File' // 引入需要用到路由的頁面  @:表示指向src文件夾
import Center from '@/views/Center'

Vue.use(VRouter) // vue使用路由

export default new VRouter({ // 創建路由
    // mode: 'history', // 去掉鏈接中的#  /File || /#/File
    routes: [ // 此處寫路由  放入數組
        {
            path: '/File', // 鏈接中的顯示路勁
            name: 'File', // 名字
            component: File,
            children: [    //二級路由數組
                {
                    path: '',
                    component: File
                },
                {
                    prth: '',
                    redirect: "/父路徑/子路徑"
                }
            ]
        }
    ]
})

動態路由

點擊事件 列表跳轉詳情頁面

  1. 列表頁面
<template>
  <div>
    <ul>
      <li v-for="data in dataList" :key="data" @click="handlePage(data)">
        {{ data }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  setup() {},
  data() {
    return { dataList: ["1111", "2222", "3333"] };
  },
  methods: {
    handlePage(id) {
      console.log(id);
      //編程式導航  按照路徑
      this.$router.push('/detail/'+id)  //跳轉具體頁面     
        
      //編程式導航  按照name
      this.$router.push({name:"qddetail",params:{id:id}});
    },
  },
};
</script>
  1. 詳情頁面
<template>
  <div>detail</div>
</template>

<script>
export default {
  setup() { },
  mounted() {
      // $route,this  獲取參數
        console.log(this.$route,this.$route.params.id);
  },
};
</script>
  1. 動態路由設置
import Vue from 'vue' // 引入vue
import VRouter from 'vue-router' // 引入路由
import File from '@/views/File' // 引入需要用到路由的頁面  @:表示指向src文件夾
import Center from '@/views/Center'
import Erji from '@/views/Erji'
import detail from '@/views/detail'

Vue.use(VRouter) // vue使用路由

export default new VRouter({ 
    // mode: 'history', // 去掉鏈接中的#  /File || /#/File
    routes: [ 
        {
            path: '/detail/:id', // 動態路由 冒號+自定義參數
            name: "qddetail",
            component: detail 
        }
    ]
})

===

//頁面跳轉
this.$router.push('/detail/'+id)  //跳轉具體頁面   
//存到本地
localStorage.setItem("key","value")
//獲取本地值
localStorage.getItem("key")
//移除  清除
remove   clear

History模式

正常的路由采用的是hash模式 url會有#標志 去除#號 只需加上這一句

   mode: 'history',

不過這種模式要玩好,還需要后台配置支持。因為我們的應用是個單頁客戶端應用,如果后台沒有正確的配置,當用戶在瀏覽器直接訪問 http://oursite .com/user/id就會返回404,這就不好看了。

在這里插入圖片描述

路由攔截

  • 舉例

我們在選購商品准備付款時,判斷你是否登錄,未登錄跳轉到登錄頁面,

只有登錄后才能購買

全局

//驗證方法
const auth = {
    isLogin() {
        //判斷token session cookie等
        return false;
    }
}

//全局守衛:任何一個路由跳轉進來執行此方法
VRouter.beforeEach((to, from, next) => {
    if (to.path === '/shoppPage') {
        if (auth.isLogin()) {
            next()
        }
    } else {
        next() //放行
    }
})

局部 ===> 寫在組件< script>中

const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染該組件的對應路由被 confirm 前調用
    // 不!能!獲取組件實例 `this`
    // 因為當守衛執行前,組件實例還沒被創建
  },
  beforeRouteUpdate(to, from, next) {
    // 在當前路由改變,但是該組件被復用時調用
    // 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 由於會渲染同樣的 Foo 組件,因此組件實例會被復用。而這個鈎子就會在這個情況下被調用。
    // 可以訪問組件實例 `this`
  },
  beforeRouteLeave(to, from, next) {
    // 導航離開該組件的對應路由時調用
    // 可以訪問組件實例 `this`
  }
}

Vuex

入門

Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。尤其為非父子通信服務非常好

官網: Vuex 是什么? | Vuex (vuejs.org)

  1. 引入
npm install vuex --save
  1. main.js同級新建 store.js內部結構
import Vue from "vue";
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {

    },
    mutations: {

    },
    actions: {

    }
})
  1. main.js中引入
import store from './store'

new Vue({
  router: router,  //key與value相同時,可以簡寫為router
  store,
  render: h => h(App),
}).$mount('#app')
  1. 使用
v-show="this.$store.state.isTabbarShow"   //this可以省略

this.$store.state.字段

設計原則

  • 應用層級的狀態應該集中到單個store對象中。

  • 提交mutation是更改狀態的唯一方法,並且這個過程是同步的。

  • 異步邏輯都應該封裝到action里面。

狀態管理

我們需要一個監控或者管理系統來具體了解什么時候改變了狀態

所有修改狀態都會經過 mutations這一層 調式工具會記錄下來

在這里插入圖片描述

  1. 具體更改方法中
this.$store.commit( "自定義函數名",false);  //第一個參數就是mutation名字
this.$store.commit( "自定義函數名",true); 
  1. store.js
    state: {
        //放入全局的自定義共享狀態
        isTabbarShow: false
    },
    mutations: {  //唯一修改狀態的位置
        zidingyi(state, data) {
            state.isTabbarShow = data
        }
    },

異步處理

  • 需求

電影網站分為熱映與即將上映 當我們點擊熱映時 ,判斷熱映頁面是否有數據 如果沒有,發起ajax請求 然后存放到mutation 然后頁面更新 如果有 直接取數據 渲染頁面 無需Ajax請求

實現

  1. 具體地址調用
  if (this.$store.state.dataList.length === 0) {
      //發送Ajax請求
      this.$store.disapath("自定義函數");
    } else {
      //使用緩存的數據
    }
  1. store.js
export default new Vuex.Store({
    state: {
        //放入全局的自定義共享狀態
        dataList: []
    },
    mutations: {  //唯一修改狀態的位置
        dataListMutation(state, data) {
            state.dataList = data
        }
    },
    actions: { //從后端異步請求需要經過actions
        //異步處理
        zidingyi(store) {
            //axios請求
            //引入axios
            //傳入到mutations中
            store.commit("dataListMutation", "獲取的數據")
        }
    }
})

寫法轉換

  • 對比
this.$store.state.data

import {mapState} from 'vuex'

computed:{
    mapState(["data"])  //不建議
	...mapState(["data"])  //建議這樣寫  ES6中展開合並運算符
}

導入導出規范

  • 問題

很多時候我們只需要某個包中的一個或者幾個方法 但是之前的方法會默認導入全部 加載會慢

  • 對比

Bad

//===========A1.js================
function A(){ }
function B(){ }
function C(){ }
//ES6導出規范
const All = {
    A,B,C
}

export default All

//=============導入=================
import All from 'A1'

//結果 引入全部方法

Good

//===========A1.js================
export function A(){ }
export function B(){ }
export function C(){ }
//=============導入=================
import {A,B} from 'A1'

//結果 引入A B方法

import {A as myA} from 'A1'    //起別名

Gitters

有時候我們需要從 store 中的 state 中派生出一些狀態,例如對列表進行過濾並計數

Vuex 允許我們在 store 中定義“getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算。

  1. store.js
    getters: {  //處理數據
        zidingyi(state) {
            return state.dataList.filter((item, index) => index < 3)
        }

    }
  1. 使用
this.$store.getters.自定義函數名
mapGitters(["  "])

mutation常量風格

  • 問題

當我們方法多了或者多人開發勢必會出現同名方法 這里可以規避這個問題

  1. 新建文件夾 比如 type 下的 a1.js有如下代碼
export const   SHOW_TABBAR_MUTATION = "show"
  1. store.js
//===先引入a1.js

	mutations: {  //唯一修改狀態的位置
        show (state, data) {
        }
      //等同於
        [SHOW_TABBAR_MUTATION] (state, data) {
        }
    },

注意:commit 調用方法也需要改

element UI

介紹

Element,一套為開發者、設計師和產品經理准備的基於 Vue 2.0 的桌面端組件庫

  • 官網地址 ===> 組件 | Element

    element-ui是由餓了么前端團隊推出的一套為開發者、設計師和產品經理准備的基於Vue.js 2.0的桌面組件庫

擴展使用文章:===> Element-ui 基本使用 - 簡書 (jianshu.com)

安裝

引入element ui到vue中

npm i element-ui -S
<!-- 引入樣式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入組件庫 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

vscoe代碼提示插件 : Element-UI-Snippets

使用方法====> ( Element-UI-Snippets-VSCode插件代碼提示快捷鍵_

引入

  • 全局引入,在vue入口main.js中增加內容如下
  import ElementUI from 'element-ui';

  import 'element-ui/lib/theme-chalk/index.css';

   Vue.use(ElementUI);
  • 局部引入,在指定的vue文件中引入所需要的組件或主題樣式,如下
    import '@/style/theme/element-variables.scss'

    import { Message, MessageBox, Loading } from  'element-ui'

    Vue.use(Loading.directive) 
    Vue.prototype.$loading = Loading.service 
    Vue.prototype.$msgbox = MessageBox 
    Vue.prototype.$alert = MessageBox.alert 
    Vue.prototype.$confirm = MessageBox.confirm 
    Vue.prototype.$prompt = MessageBox.prompt 
    Vue.prototype.$message = Message

具體使用請前往官網查看

手勢事件

  1. 安裝
npm install vue-touch@next --save
  1. 在 需要的文件中引入
	import Vue from "vue";
	import VueTouch from 'vue-touch'

	Vue.use(VueTouch, {name: 'v-touch'})  v-touch可以是自定義名稱
  1. 使用
<v-touch @swipeleft="onSwipeLeft">
    <div style="background :red;height : 100px">center</div>
</v-touch>
	<v-touch 	
		(1)替換標簽
			tag="要變成的標簽名稱,默認為div"
		
		(2)定義手勢
			@事件類型='回調' 
			
		(3)配置手勢事件選項
			:小寫事件類型名稱-options="{ direction: 'horizontal', threshold: 100 }
				threshold臨界值
				directions方向: 'up', 'down', 'left', 'right', 'horizontal', 'vertical', 'all'
				具體配置查看hammerjs
				
		(4)阻止/觸發手勢
			:enabled="true/false"   允許/禁止所有的手勢
			:enabled="{ pinch: true, rotate: false }"  允許和禁止指定手勢
		
		(5)公共組件方法
			1、通過ref獲取到該標簽
			2、在方法中
				this.$refs.tapper.disable('tap')
				
			公共方法:
				disable('手勢名稱') 	
				enable('手勢名稱') 	
				toggle('手勢名稱') 	
				disableAll() 	disable all Recognizers
				enableAll() 	enable all Recognizers
				isEnabled('手勢名稱') 	
			
		(6)自定義手勢
			在main.js中,在Vue.use之前使用
			
			VueTouchVueTouch.registerCustomEvent('doubletap', {
			  type: '手勢名稱',
			  ...手勢事件的配置選項,見(3)
			  taps: 2  對應tap手勢的觸發點擊次數配置
			})
	
	> ...</v-touch>
	
4、事件類型:
	Pan平移 	
		pan, panstart, panmove, panend, pancancel,
		panleft, panright, panup, pandown 	
		
	Pinch縮放 	
		pinch, pinchstart, pinchmove,pinchend,
		pinchcancel, pinchin, pinchout 	
		
	Press按壓 	
		press, pressup 	
		
	Rotate旋轉 	
		rotate, rotatestart, rotatemove,
		rotateend, rotatecancel, 	
		
	Swipe滑動 	
		swipe, swipeleft, swiperight,
		swipeup, swipedown 	
		
	Tap點擊 	
		tap 

在這里插入圖片描述

Vue SSR

介紹

官網: Vue.js 服務器端渲染指南 )

  • 什么是服務器端渲染 (SSR)?

Vue.js 是構建客戶端應用程序的框架。默認情況下,可以在瀏覽器中輸出 Vue 組件,進行生成 DOM 和操作 DOM。然而,也可以將同一個組件渲染為服務器端的 HTML 字符串,將它們直接發送到瀏覽器,最后將這些靜態標記"激活"為客戶端上完全可交互的應用程序。

服務器渲染的 Vue.js 應用程序也可以被認為是"同構"或"通用",因為應用程序的大部分代碼都可以在服務器客戶端上運行。

優點

  • SEO和爬蟲都是根據url返回的數據來進行的 , 爬蟲seo獲取的數據,是一個沒有數據的殼子

  • 首屏渲染 像vue這樣的單頁面應用,首屏渲染是單頁面spa的通病,打包出來的dist過大,會導致首屏加載緩慢

缺點

  • 需要配置兩個入口文件,一個是服務端首屏渲染所需要的,第二個是前端激活所需要的
  • 相比於單純的spa,服務端渲染加重了服務器的負擔
  • 前后端同構,在后端就需要寫前端vue的代碼,與前后端分離相違背,這個可以通過webpack打包實現,只需要配置入口文件以及相應的邏輯就可以。
  • 緩存和運維的問題。

服務端與客戶端渲染的對比====> 關於SSR( 服務端渲染 )其利與弊是什么? - 知乎 (zhihu.com)

快速使用

  1. 安裝
npm install vue vue-server-renderer --save
  1. 渲染示例
// 第 1 步:創建一個 Vue 實例
const Vue = require('vue')
const app = new Vue({
  template: `<div>Hello World  ----{{myname}}----{{age}} </div>`,
    data:{
        myname:"前度",
        age:"18"
    }
})

// 第 2 步:創建一個 renderer
const renderer = require('vue-server-renderer').createRenderer()

// 在 2.5.0+,如果沒有傳入回調函數,則會返回 Promise:
renderer.renderToString(app).then(html => {
  console.log(html)
}).catch(err => {
  console.error(err)
})
  1. 終端調用
node 路徑+文件名

與服務器集成

npm install express --save
const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()

server.get('*', (req, res) => {
  const app = new Vue({
    data: {
      url: req.url
    },
    template: `<div>訪問的 URL 是: {{ url }}</div>`
  })

  renderer.renderToString(app, (err, html) => {
    if (err) {
      res.status(500).end('Internal Server Error')
      return
    }
   res.writeHead(200,{"Content-Type":"text/html;charset=utf8"})        
    res.end(`
      <!DOCTYPE html>
      <html lang="en">
        <head><title>Hello</title></head>
        <body>${html}</body>
      </html>
    `)
  })
})

server.listen(8080)
node 文件名
訪問端口號

Nuxt.js

官網: 關於 Nuxt.js - NuxtJS | Nuxt.js 中文網

  • 項目的構建

安裝 - NuxtJS | Nuxt.js 中文網

  • 相關教程

nuxt.js

ps:此文章只是對Vue2.0的簡單使用與介紹,不涉及更深層面,僅僅入門,有些介紹也引入了其他小伙伴的博客,還望海涵



免責聲明!

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



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