Vue獲取DOM,數據監聽,組件,混合和插槽


Vue獲取DOM,數據監聽,組件,混合和插槽

注:“:” 是指令 “v-bind”的縮寫,“@”是指令“v-on”的縮寫;“.”是修飾符。

Vue獲取DOM

給標簽加ref屬性:ref="my_box"
獲取:this.$refs.my_box;

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <div ref="my_box"></div>
    <button v-on:click="my_click">點擊顯示文本</button>
</div>
<script>
    const app = new Vue({
        el:"#app",
        data:{},
        methods:{
            my_click: function(){
                let ele = this.$refs.my_box;
                console.log(ele);
                ele.innerText = "hello"
            }
        }
    })
</script>
</body>
</html>

computed:計算屬性,放的是需要處理的數據

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <table>
        <tr>
            <th>科目</th>
            <th>成績</th>
        </tr>
        <tr>
            <td>Python</td>
            <td><input type="text" v-model.number="python"></td>
        </tr>
        <tr>
            <td>Java</td>
            <td><input type="text" v-model.number="java"></td>
        </tr>
        <tr>
            <td>Go</td>
            <td><input type="text" v-model.number="go"></td>
        </tr>
        <tr>
            <td>總分</td>
            <td>{{total}}</td>
        </tr>
        <tr>
            <td>平均分</td>
            <td>{{average}}</td>
        </tr>
<!-- 繁瑣方法 -->
<!-- <tr> -->
<!-- <td>總分</td> -->
<!-- <td>{{python + java + go}}</td> -->
<!-- </tr>  -->
<!-- <tr> -->
<!-- <td>平均分</td> -->
<!-- <td>{{total/3}}</td> -->
<!-- </tr> -->

    </table>
</div>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            python:"",
            java:"",
            go:""
        },
        methods:{},
        computed:{
            total: function(){
                return this.python + this.java + this.go
            },
            average: function(){
                return this.total/3
            }
        }
    })
</script>
</body>
</html>

數據監聽

watch :監聽不到可以添加deep屬性
deep:true :深度監聽,deep監聽不到,可以使用 $.set() 屬性操作值
$.set()

字符串監聽:監聽到的新舊值不同。
數組:只能監聽到長度的變化,新舊值相同,改變數組值的時候要使用 $set(array,index,value)
對象:只能監聽到value的改變,必須深度監聽:deep,增加對象的key必須使用:$set(array,key,value)

注:數組監聽有坑

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    {{name}}
    <br>
    {{hobby}}
    <br>
    {{obj}}
    <br>
    <button v-on:click="my_click">點我改變數據</button>
</div>
<script>
    const app = new Vue({
        el:"#app",
        data:{
            name:"eric",
            hobby:["打游戲","打豆豆"],
            obj:{
                boy:"PDD",
                age:23
            }
        },
        methods:{
            my_click: function(){
                // 修改name數據
                this.name = "bob";
                // this.hobby.push("潛水");
                // this.hobby[0] = "潛水";
                // app.$set(this.hobby,0,"潛水");
                // this.obj.age = 20;
                // this.obj["sex"] = "男";
                app.$set(this.obj,"sex","男");
            }
        },
        watch: {
            name: {
                handler: function(val,oldVal){
                    console.log(val);
                    console.log(oldVal);
                }
            },
            hobby: {
                handler: function(val,oldVal){
                    // 改變數組的長度的時候新舊值相同
                    console.log(val);
                    console.log(oldVal);
                },
                // deep: true
            },
            obj: {
                handler: function(val,oldVal){
                    console.log(val);
                    console.log(oldVal);
                },
                deep: true
            }
        }
    })
</script>
</body>
</html>

組件

可復用
全局組件的定義:Vue.component("myheader",{})
全局組件的使用:<myheader></myheader>

<!-- 全局注冊組件 -->
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <myheader></myheader>
</div>
<div id="apps">
    <myheader></myheader>
</div>
<script>
    Vue.component("myheader",{
        template: '<div><h1>{{ title }}</h1></div>',
        // template: '<div><h1>Hello world!</h1></div>',
        data(){  // 對象的單體模式
            return{
                title: "HelloWorld!"
            }
        },
        methods:{}
    });
    const app = new Vue({
        el:"#app",
        data:{},
        methods:{}
    });
    const apps = new Vue({
        el:"#apps",
        data:{},
        methods:{}
    })
</script>
</body>
</html>

局部組件的定義:components: {my_com: my_com_config}
局部組件的使用:<my_com></my_com>

<!-- 局部注冊組件 -->
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <my_com></my_com>
</div>
<script>
    let my_com_config = {
        template: '<div><h1>局部組件</h1></div>'
    };
    const app = new Vue({
        el:"#app",
        components: {
            my_com: my_com_config
        }
    })
</script>
</body>
</html>

父子組件:
注:組件只識別一個作用域塊

<!-- 父子組件的進本使用 -->
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <my_com></my_com>
</div>
<script>
    let child_config = {
        template: '<div><h2>子組件</h2></div>'
    };
    let my_com_config = {
        template: '<div><h1>父組件</h1><child></child></div>',
        components: {
            child: child_config
        }
    };
    const app = new Vue({
        el:"#app",
        components: {
            my_com: my_com_config
        }
    })
</script>
</body>
</html>

父子組件的通信:
父子通信(主操作在父級):
父級定義方法::father_say="f_say"
子級調用方法:props: ['father_say']
子級使用方法(模板語言直接調用):{{father_say}}

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <my_com></my_com>
</div>
<script>
    let child_config = {
        template: '<div><h2>子組件</h2><p>father_say:{{father_say}}</p></div>',
        props: ['father_say']
    };
    let my_com_config = {
        template: '<div><h1>父組件</h1><child :father_say="f_say"></child></div>',
        components: {
            child: child_config
        },
        data(){
            return {
                f_say: "滾~~"
            }
        }
    };
    const app = new Vue({
        el:"#app",
        components: {
            my_com: my_com_config
        }
    })
</script>
</body>
</html>

子父通信(主操作在子級):
子集定義方法:@click='my_click'
子級提交事件:this.$emit("事件名",data)
父級綁定子級提交的事件:@事件名="處理的方法"
父級處理方法: methods: {處理的方法: function(data){data 數據處理} }
父級使用方法(模板語言直接調用):{{say}}

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <my_com></my_com>
</div>
<script>
    let child_config = {
        template: "" +
            "<div>" +
            "<h2>子組件</h2>" +
            "<button @click='my_click'>向父級傳送數據</button>" +
            "</div>",
        methods: {
            my_click(){
                // 子組件提交事件名稱
                this.$emit("son_say","滾~~")
            }
        }
    };
    let my_com_config = {
        template: '' +
            '<div>' +
            '<h1>父組件</h1>' +
            '<child @son_say="my_son_say"></child>' +
            '<p>son_say:{{say}}</p>' +
            '</div>',
        components: {
            child: child_config
        },
        data(){
            return {
                say:""
            }
        },
        methods: {
            my_son_say: function(data){
                this.say = data
            }
        }
    };
    const app = new Vue({
        el:"#app",
        components: {
            my_com: my_com_config
        }
    })
</script>
</body>
</html>

非父子級通信:
定義中間調度器:let event = new Vue()
需要通信的組件向中間調度器提交事件:event.$emit("事件名", data)
接收通信的組件監聽中間調度器里的事件:event.$on("事件名", function(data){data操作(注意:this的問題)})

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
<eric></eric>
<jing></jing>
</div>
<script>
    let midlen = new Vue();
    let eric = {
        template: "" +
            "<div>" +
            "<h1>This is Eric</h1>" +
            "<button @click='my_click'>點擊通知靜靜</button>" +
            "</div>",
        methods: {
            my_click(){
                // 通知bob,晚上等我
                // 向bob,提交事件
                midlen.$emit("email","晚上,一起吃飯")
            }
        }
    };
    let jing = {
        template: "" +
            "<div>" +
            "<h1>This is jing</h1>" +
            "<p>eric和我說:{{ eric_email }}</p>" +
            "</div>",
        data(){
            return {
                eric_email: ""
            }
        },
        mounted(){
            // 組件加載完成后執行的方法
            let that = this;
            midlen.$on("email", function(data){
                that.eric_email = data;
                // console.log(data);
            })
        }
    };
    const app = new Vue({
        el:"#app",
        components: {
            eric: eric,
            jing: jing
        }
    })
</script>
</body>
</html>

混合

實際上在框架中用的很少
作用:復用共用的代碼塊
minxins:[base]

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <button @click=\"show_text\">點擊顯示文本</button>
    <button @click=\"hide_text\">點擊隱藏文本</button>
    <button @mouseenter="show_text" @mouseleave="hide_text">提示框</button>
    <div v-show=\"is_show\"><h1>look wyl and kjj</h1></div>
</div>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            is_show:false
        },
        methods: {
            show_text: function(){
                this.is_show = true
            },
            hide_text: function(){
                this.is_show = false
            }
        }
    })
</script>
</body>
</html>
<!-- 混合示例 -->
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <com1></com1>
    <com2></com2>
</div>
<script>
    let base = {
        data(){
            return {
                is_show:false
            };
        },
        methods: {
            show_text(){
                this.is_show = true
            },
            hide_text(){
                this.is_show = false
            }
        }
    };
    let com1 = {
        template:"" +
            "<div>" +
            "<button @click=\"show_text\">點擊顯示文本</button>" +
            "<button @click=\"hide_text\">點擊隱藏文本</button>" +
            "<div v-show=\"is_show\"><h1>look wyl and kjj</h1></div>" +
            "</div>",
        mixins: [base],
        data(){
            return {
                is_show: true
            }
        }
    };
    let com2 = {
        template:"" +
            "<div>" +
            "<button @mouseenter=\"show_text\" @mouseleave=\"hide_text\">提示框</button>" +
            "<div v-show=\"is_show\"><h1>look wyl and kjj</h1></div>" +
            "</div>",
        mixins: [base],
    };
    const app = new Vue({
        el:"#app",
        components: {
            com1: com1,
            com2: com2
        }
    })
</script>
</body>
</html>

插槽

作用:實現組件內容的分發
slot:
直接使用slot標簽:<slot></slot>
名命slot標簽:
先給slot加name屬性:<slot name="title"></slot>
給標簽元素添加slot屬性:<h3 slot="title">Python</h3>

<!-- 未命名的slot標簽 -->
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <com>
        <slot>This is jing</slot>
    </com>
    <com>
        <slot>This is wyl</slot>
    </com>
</div>
<template id="my_com">
    <div>
        <h1>這是一個組件</h1>
        <slot></slot>
    </div>
</template>
<script>
    let com = {
        template: "#my_com"
    };
    const app = new Vue({
        el:"#app",
        components: {
            com: com
        }
    })
</script>
</body>
</html>
<!-- 命名的slot標簽 -->
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <style>
        .my_box{
            width: 200px;
            height: 200px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
<div id="app">
    <com>
        <h3 slot="title">Python</h3>
        <p slot="brief">This is jing</p>
    </com>
    <com>
        <h3 slot="title">Git</h3>
        <p slot="brief">This is wyl</p>
    </com>
</div>
<template id="my_com">
    <div>
        <h1>這是一個組件</h1>
        <slot name="title"></slot>
        <slot name="brief"></slot>
    </div>
</template>
<script>
    let com = {
        template: "#my_com"
    };
    const app = new Vue({
        el:"#app",
        components: {
            com: com
        }
    })
</script>
</body>
</html>


免責聲明!

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



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