388 vue 之 props: 只讀,prop的大小寫,prop的類型,prop的校驗


十、props 的特點 : 只讀

  • 演示驗證 props 只讀
    • 傳的是簡單類型 : 修改會報錯
    • 傳的復雜類型 (地址) : 修改不會報錯,是因為地址沒有變 ,測試 obj={}立馬報錯 【修改對象中的數據,不會修改對象的地址,但是修改對象的地址就報錯。】
  • 修改父組件傳給子組件的數據

思路 : 把接收過來的數據,保存到 data 中一個臨時值 (適用在該組件接收數據只會在當前組件內使用)

  Vue.component('child', {
        template: `
      <div>子組件 {{ cmsg }} </div>
       `,
        data() {
          return {
            cmsg: this.msg
          }
        },
        props: ['msg'],
        created() {
          this.cmsg = 666
        }
      })

完善TodoMVC => 修改狀態 + 修改任務


08-prop的只讀特性.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <div id="app">
        <child :msg="pmsg" :obj="pobj"></child>
    </div>

    <script src="./vue.js"></script>
    <script>
        Vue.component('child', {
            template: `
                <div> 子組件 : {{ obj.name }}</div>
            `,
            props: ['msg', 'obj'],
            mounted() {
                // 修改傳遞過來的數據
                // 1. 修改基本類型的數據,報錯
                // this.msg = 666 

                //2. 只是改了對象里的內容 ,並沒有改地址
                // this.obj.name = '春春'   // 雖然這不會報錯,但是也不要這么改
                this.obj = {} // 這樣寫報錯
            }
        })

        const vm = new Vue({
            el: '#app',
            data: {
                pmsg: '父的信息',
                pobj: {
                    name: '張三'
                }
            }
        })
    </script>
</body>

</html>

補充的案例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <one :msg="pMsg" :obj="pObj"></one>
  </div>

  <script src="./vue.js"></script>

  <script>
    Vue.component('one', {
      template: `
        <div>
          <div>{{msg}} - {{obj.name}}</div>
          <div>{{cMsg}} - {{cObj.name}}</div>
        </div> `,
      data() {
        return {
          // 把接收過來的數據,保存到 data 中一個臨時
          cMsg: this.msg,
          cObj: this.obj
        }
      },
      props: ['msg', 'obj'],
      created() {
        this.cMsg = 333
        this.cObj.name = '嘻嘻'
        this.cObj = { name: '嘿嘿' }
      },
    })

    const vm = new Vue({
      el: '#app',
      data: {
        pMsg: '111',
        pObj: {
          name: '哈哈'
        }
      }
    })
  </script>
</body>

</html>


十一、prop 的大小寫

  • 官 : HTML 中的特性名是大小寫不敏感的,所以瀏覽器會把所有大寫字符解釋為小寫字符。

    • html 的標簽和 屬性 都是一樣,忽略大小寫
    • <H1 TITLE="哈哈">我是h1</H1>
  • 官 : 這意味着當你使用 DOM 中的模板時,camelCase (駝峰命名法) 的 prop 名不好使了

    • <child :cMsg="pmsg"></child> 會報警告,父傳子也接收不到了
    • 原因是 : 接收的屬性是:cMsg, 因為忽略大小寫,已為 : cmsg
    • 所以已經准備要讀取的 是 cmsg 的值,否則要報警告
      You should probably use "c-msg" instead of "cMsg".
  • 方式 1 : 全用小寫,不要使用駝峰命名 (不推薦)

    • 接收 : cmsg
    • props/讀取 :cmsg
  • 方式 2 官 : 需要使用其等價的 kebab-case (短橫線分隔命名) 命名: (推薦)

    • 接收 : :c-msg='pmsg'
    • props/讀取 : cMsg / this.cMsg
  • 大小寫在 父傳子和 子傳父中的應用 (都是要 帶 - 的)

    • 父傳子 : :c-msg ==> cMsg 改駝峰 - 因為props
    • 子傳父 : @todo-head = 'pAddTodo' ==> this.$emit('todo-head') 不改駝峰
  • 完善 TodoMVC : 底部隱藏+剩余完成數+清除完成

    • 計算屬性 : 已知值(todoList 在 根組件) ==> 得到一個新值(子組件里使用)
    • 父 => 子通訊
  • 番外篇 : 方法當屬性傳、傳過來的帶:得到的原型


09-prop的大小寫問題.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <!-- 
       原因 :
       1. cMsg  => cmsg

       解決辦法 :
       1. 用小寫 (不推薦)
       2. 短橫線分割符
         賦值   :c-msg='pMsg'
               -刪除掉 -后面的首字母變大寫 cMsg
         指定 : cMsg
         使用 : cMsg
     -->
    <div id="app">
        <child :c-msg="pMsg" :c-user-name="pUserName"></child>
    </div>

    <script src="./vue.js"></script>
    <script>
        Vue.component('child', {
            template: `
                <div> 子組件 : {{ cMsg }}  {{ cUserName }} </div>
             `,
            props: ['cMsg', 'cUserName']
        })

        const vm = new Vue({
            el: '#app',
            data: {
                pMsg: '父的信息',
                pUserName: '大傻春'
            }
        })
    </script>
</body>

</html>

10-大小寫問題應用在子傳父和父傳子.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <!-- 
       (prop的)大小寫問題 【是prop的大小寫問題,不是事件的。 】
       1. 父傳子  c-msg  =>  cMsg
       2. 子傳父 @add-todo   ==> add-todo
     -->
    <div id="app">
        <child :c-msg="pMsg" @add-todo="pAddTodo"></child>
    </div>

    <script src="./vue.js"></script>
    <script>
        Vue.component('child', {
            template: `
                <div> 子組件 :  {{ cMsg }} </div>
            `,
            props: ['cMsg'],
            created() {
                this.$emit('add-todo')
            }
        })

        const vm = new Vue({
            el: '#app',
            data: {
                pMsg: '父的信息'
            },
            methods: {
                pAddTodo() {
                    console.log('哈哈')
                }
            }
        })
    </script>
</body>

</html>

11-prop的類型問題.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <!-- 
       1. 通過prop 賦值的時候, 如果直接賦值一個靜態值, 不管是什么值, 都是字符串類型
        'abc' / '123' / 'true'
       2. 在 屬性前面加一個冒號“:” , 可以獲取它的真實類型

        總結 :
        1.  :msg='pmsg/動態值/data里屬性'  
        2.  :msg='固定值/靜態值' : 讀取固定值的真實類型,賦值給 msg    

     -->

    <div id="app">
        <child :msg="true" :na="name"></child>
    </div>

    <script src="./vue.js"></script>
    <script>
        Vue.component('child', {
            template: `
            <div> 子組件 :  </div>
           `,
            props: ['msg'],
            created() {
                // 'abc'  => 字符串
                // '123'  => '123' 字符串
                console.warn(this.msg, typeof this.msg) // true "boolean"
                console.warn(this.na, typeof this.na) // 123 "number"
            }
        })

        const vm = new Vue({
            el: '#app',
            data: {
                name: 123
            }
        })
    </script>
</body>

</html>

12-類型的校驗問題.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 大傻春拿去用了 -->
        <!-- <child :msg="111"></child> -->
        <child></child>
    </div>
    <script src="./vue.js"></script>
    <script>
        // 這個組件是我注冊的
        Vue.component('child', {
            template: `
        		<div> 子組件 :  </div>
          	`,
            props: ['msg'],

            // props: {
            //   msg: Number // 僅僅是告訴其類型
            // },
            // props: {
            //     msg: {
            //         type: Number, // 類型
            //         default: 100 // 默認值
            //     }
            // },
            created() {
                // 我希望的是一個數字類型
                console.log(this.msg, typeof this.msg)
                console.log(this.msg + 10) // 133
            }
        })

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

</html>

<!-- 
   Vue.component('my-component', {
  props: {
    // 基礎的類型檢查 (`null` 和 `undefined` 會通過任何類型驗證)
    propA: Number,
    // 多個可能的類型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 帶有默認值的數字
    propD: {
      type: Number,
      default: 100
    },
    // 帶有默認值的對象
    propE: {
      type: Object,
      // 對象或數組默認值必須從一個工廠函數獲取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定義驗證函數
    propF: {
      validator: function (value) {
        // 這個值必須匹配下列字符串中的一個
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})
 -->


免責聲明!

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



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