1. 程式人生 > 其它 >計算屬性、偵聽屬性、區域性與全域性元件使用、元件通訊(父子互傳)、ref屬性、動態元件和keep-alive、插槽

計算屬性、偵聽屬性、區域性與全域性元件使用、元件通訊(父子互傳)、ref屬性、動態元件和keep-alive、插槽

今日內容概要

  • 計算屬性
  • 偵聽屬性
  • 區域性元件和全域性元件
  • 元件通訊之父傳子
  • 元件通訊之子傳父
  • ref屬性(元件間通訊)
  • 動態元件和keep-alive
  • 插槽

內容詳細

1、計算屬性

# 插值的普通函式,只要頁面一重新整理,函式就會重寫計算,跟函式沒關的值的變化,函式也會重寫計算

# 把函式當成屬性來用---》只有這個函式使用的屬性(變數)變化,函式才重寫運算

案例:通過計算屬性實現名字首字母大寫

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <input type="text" v-model="mytest2">-->{{mytest2}}
    <br>
    <input type="text" v-model="mytext">--->{{mytext.substring(0, 1).toUpperCase() + mytext.substring(1)}}
    <br>
    函式方式:{{getName()}}
    <br>
    計算屬性:{{getName2}}
</div>
</body>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            mytext: '',
            mytest2: '',
        },
        methods: {
            getName() {
                console.log("我執行了")
                return this.mytext.substring(0, 1).toUpperCase() + this.mytext.substring(1)
            }
        },

        // 8生命週期
        computed: {
            getName2() {
                console.log("計算屬性我執行了")
                return this.mytext.substring(0, 1).toUpperCase() + this.mytext.substring(1)
            }
        }
    })
</script>
</html>

案例:通過計算屬性,重寫過濾案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="box">
    <p><input type="text" v-model="myText" placeholder="請輸入要篩選的內容:"></p>
    <ul>
        <li v-for="data in newList">{{data}}</li>
    </ul>
</div>
</body>

<script>
    var vm = new Vue({
        el: '#box',
        data: {
            myText: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
        },
        computed: {
            newList() {
                console.log('我執行了')
                var datalist2 = this.dataList.filter(item => {
                    return item.indexOf(this.myText) > -1
                })
                return datalist2
            }
        }
    })
</script>
</html>

2、偵聽屬性

只要變數發生變化,就會執行監聽屬性中的方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="box">
    <p><input type="text" v-model="myText" placeholder="請輸入要篩選的內容:"></p>
    <ul>
        <li v-for="data in newList">{{data}}</li>
    </ul>
</div>
</body>

<script>
    var vm = new Vue({
        el: '#box',
        data: {
            myText: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
        },

        computed: {
            newList() {
                console.log('我執行了')
                var datalist2 = this.dataList.filter(item => {
                    return item.indexOf(this.myText) > -1
                })
                return datalist2
            }
        }
    })
</script>
</html>

3、區域性元件和全域性元件

# 擴充套件 HTML 元素,封裝可重用的程式碼,目的是複用
	例如:有一個輪播,可以在很多頁面中使用,一個輪播有js,css,html
    
	元件把js,css,html放到一起,有邏輯,有樣式,有html
  
# 區域性元件,全域性元件


# 注意事項
	1 自定義元件需要有一個root element,一般包裹在一個div中
	2 父子元件的data是無法共享
	3 元件可以有data,methods,computed....,但是data 必須是一個函式

區域性元件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <Top></Top>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <Bottom></Bottom>
</div>
</body>

<script>
    var vm = new Vue({
        // el  data  methods watch computed 8個
        el: '#app',
        data: {},

        // 定義在 components裡面的叫區域性元件,只能在區域性使用,只能在id為app的標籤內使用
        components: {
            'Top': {
                template: `
                  <div>
                  <h1 style="background: pink;font-size: 60px;text-align: center">{{ name }}</h1>
                  <hr>
                  <button @click="handleC">點我看美女</button>
                  </div>
                `,
                data() {
                    return {
                        name: "我是頭部"
                    }
                },
                methods: {
                    handleC() {
                        alert('美女')
                    }
                },
            },

            'Bottom': {
                template: `
                  <div>
                  <hr>
                  <h1 style="background: green;font-size: 60px;text-align: center">{{ name }}</h1>

                  </div>
                `,
                data() {
                    return {
                        name: "我是尾部"
                    }
                },
            },
        },
    })
</script>
</html>

全域性元件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <top></top>
</div>
</body>

<script>
    // 定義全域性元件 Vue.component中的--->任意位置都可以用
    Vue.component('top', {
        template: `
          <div>
          <h1 style="background: pink;font-size: 60px;text-align: center">{{ name }}</h1>
          <hr>
          <button @click="handleC">點我看美女</button>
          </div>
        `,
        data() {
            return {
                name: "我是頭部"
            }
        },
        methods: {
            handleC() {
                alert('美女')
            }
        },

    },)

    var vm = new Vue({
        // el  data  methods watch computed 8個
        el: '#app',
        data: {},
    })
</script>
</html>

4、元件通訊之父傳子

# 元件間data資料不同享,資料傳遞
	從父元件傳到子元件
		通過自定義屬性
        
	從子元件傳到父元件
		通過自定義事件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <!--    通過自定義屬性:myheader-->
    <top :myheader="headerName"></top>
    {{headerName}}
    <input type="text" v-model="headerName">
</div>
</body>

<script>
    // 定義全域性元件--->任意位置都可以用
    Vue.component('top', {
        template: `
          <div>
          <h1 style="background: pink;font-size: 60px;text-align: center">{{ myheader }}</h1>
          </div>
        `,
        data() {
            return {
                name: "我是頭部"
            }
        },

        // 必須叫props,陣列內放自定義屬性的名字
        // 屬性驗證
        // props:['myheader',],
        props: {
            myheader: String,  // key是自定義屬性名,value是型別名,如果是別的型別就報錯
        },
    },)

    var vm = new Vue({
        // el  data  methods watch computed 8個
        el: '#app',
        data: {
            headerName: 999
        },
    })
</script>
</html>

5、元件通訊之子傳父

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <!--    自定義了一個myevent事件 -->
    <top @myevent="handelRecv"></top>
    <hr>
    接收到子元件的資料是:{{childText}}
</div>
</body>

<script>
    // 定義全域性元件--->任意位置都可以用
    Vue.component('top', {
        template: `
          <div>
          <h1 style="background: pink;font-size: 60px;text-align: center">{{ myheader }}</h1>
          <input type="text" v-model="text">
          <button @click="handleSend">點我傳出去</button>
          </div>
        `,
        data() {
            return {
                myheader: "我是頭部",
                text: '',
            }
        },
        methods: {
            handleSend() {
                // 觸發繫結在該元件上的事件,myevent---》父元件中會執行事件對應的函式handelRecv--》
                this.$emit('myevent', this.text)
            }
        }
    },)

    var vm = new Vue({
        // el  data  methods watch computed 8個
        el: '#app',
        data: {
            childText: ''
        },
        methods: {
            handelRecv(text) {
                // 接收一個引數,賦值給父元件的childText
                this.childText = text
            }
        }
    })
</script>
</html>

6、ref屬性(元件間通訊)

# ref屬性,如果放在普通標籤上,就是普通標籤的原生html,操作,設定
# ref屬性,如果放在元件上,就是當前元件物件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <top ref="top"></top>
    <input type="text" v-model="text" ref="myinput">
    <img src="" alt="" ref="myimg" height="80px" width="80px">
    <hr>
    <button @click="handleC">點我</button>
</div>
</body>

<script>
    // 定義全域性元件--->任意位置都可以用
    Vue.component('top', {
        template: `
          <div>
          <h1>{{ myheader }}</h1>
          <button @click="handleC">點我看美女</button>
          <hr>
          </div>
        `,
        data() {
            return {
                myheader: "我是頭部",
            }
        },
        methods: {
            handleC() {
                alert("美女")
            }
        }
    },)

    var vm = new Vue({
        el: '#app',
        data: {
            text: ''
        },
        methods: {
            handleC() {
                console.log('我被點了')
                // 把所有有ref屬性的標籤 弄到 一個物件中
                console.log(this.$refs) // 是所有標籤寫了ref屬性的物件{myinput:真正的標籤,myimg:真正的標籤}

                // 111111 放在普通標籤上示例
                // 取到input的value值
                // console.log(this.$refs.myinput.value)
                // this.$refs.myinput.value = 'lqz is nb'
                // this.$refs.myimg.src = 'https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg'

                // 222222 放在元件上示例
                // console.log(this.$refs.top)
                // 既然能夠拿到元件物件,元件中的data中的值也可以拿到,元件中的方法也可呼叫
                console.log(this.$refs.top.myheader) // 父元件中拿到了子元件的值
                // 不區分是子傳父還是父傳子了

                // 想子傳父--》下面就是子傳父
                // console.log(this.$refs.top.myheader)
                // this.text = this.$refs.top.myheader

                // 想父傳子
                // this.$refs.top.myheader = '劉清政 is nb'
                // this.$refs.top.myheader = this.text

                // 還可以呼叫元件的方法
                this.$refs.top.handleC()  // 如果有引數,是不是也可以傳到子元件中
            }
        }
    })
</script>
</html>

7、動態元件和keep-alive

# keep-alive:元件不銷燬(保留輸入過的資料)

# component:有個is屬性,指定顯示的元件是哪個
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <ul>
        <li @click="changeC('index')">首頁</li>
        <li @click="changeC('order')">訂單</li>
        <li @click="changeC('good')">商品</li>
    </ul>
    <!--    笨辦法 不用-->
    <!--<index v-if="index_show"></index>-->
    <!--<order v-if="order_show"></order>-->
    <!--<good v-if="good_show"></good>-->

    <keep-alive>
        <component :is='who'></component>
    </keep-alive>
</div>
</body>

<script>
    // 定義全域性元件--->任意位置都可以用
    Vue.component('index', {
        template: `
            <div>
                <h1>我是首頁</h1>
            </div>
        `,
    },)
    Vue.component('order', {
        template: `
            <div>
                <h1>我是訂單</h1>
                請輸入要查詢的訂單:<input type="text">
            </div>
        `,
    },)
    Vue.component('good', {
        template: `
            <div>
                <h1>我是商品</h1>
            </div>
        `,
    },)

    var vm = new Vue({
        el: '#app',
        data: {
            // index_show: true,
            // order_show: false,
            // good_show: false,
            who: 'index'
        },
        methods: {
            changeC(i) {
                this.who = i
            }
        }
    })
</script>
</html>

8、插槽

8.1 普通插槽

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <index>
        <div>
            使用者名稱:<input type="text">
            密碼:<input type="text">
        </div>
    </index>
</div>
</body>

<script>
    Vue.component('index', {
        template: `
            <div>
                <h1>我是首頁</h1>

<!--            插槽就是將指定標籤內的內容 替換到插槽標籤處 此處指定標籤為 index標籤-->
                <slot></slot>
            </div>
        `,
    },)

    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {}
    })
</script>
</html>

8.2 具名插槽

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>

<body>
<div id="app">
    <index>
        <p slot="a">pppp</p>
        <div slot="b">
            div--div
        </div>
    </index>
</div>
</body>

<script>
    Vue.component('index', {
        template: `
            <div>
<!--                可以寫多個插槽 並且可以指定標籤替換指定插槽-->
                <slot name="a"></slot>
                <h1>我是首頁</h1>
                <slot name="b"></slot>
            </div>
        `,
    },)

    var vm = new Vue({
        el: '#app',
        data: {},
    })
</script>
</html>

補充知識:

# 編輯器的選擇
	java:IDEA(主流),eclipse,myeclipse
	python:pycharm(主流),Jupyter(資料分析)
	go: goland(主流),vscode(微軟出的,免費)
	前端:webstorm,vscode,sublime-text,Hbuilder
	安卓開發:AndrioStudio
	ios:Xcode,只能裝在mac ---》必須要有mac系統,普通PC機不好裝mac系統,黑蘋果--》驅動支援不好
	
# 總結:
	Jetbrains公司,出了所有開發語言可以用的編輯器,Jetbrains全家桶,最開始Jetbrains只有一款編輯器,就是idea,出外掛,安裝了外掛後,可以開發其它語言,每個語言有個編輯器
    
# 由於咱們用pycharm比較習慣,建議以後選擇jet的全家桶,使用習慣完全一致,只是換了個語法寫程式碼

# AndrioStudio:
	谷歌公司推出的,谷歌買了Jetbrains公司版權,自己定製的ADT--》AndrioStudio
    
# vscode:免費,佔記憶體小
  
# jetbrains收費---》價格不低--》組織:699刀一年
# 正常途徑:學生--》學生郵箱申請   開源軟體作者--->申請

# pycharm過期問題
	淘寶購買
	IDE Eval Reset  ---》全家桶---》任意一款jetbrains的ide都行
	30天免費試用--》用了29天,刪除pycharm的配置檔案---》重新是30天
	最新版的pycharm不支援:遠端認證,不讓試用了---》老版本--》2020版本