文章目錄
- axios 的使用
- 1、axios 基本使用
- 2、vue 中的 axios
- Vue中的影片
- 1、使用過渡類名實作影片
- 2、可修改 v- 前綴
- 3、使用第三方類別庫實作影片
- 4、使用鉤子函式實作小球的半場影片
- 5、串列影片
- Vue 組件
- 定義 Vue 組件
- 全域組件定義的三種方式
- 第一種方式:
- 第二種方式:
- 第三種方式:
- 私有組件定義
- 組件中展示資料和回應事件
- 組件切換
- 切換方式一(使用flag識別符號結合v-if和v-else切換組件)
- 切換方式二(使用component標簽的:is屬性來切換組件,并添加影片)
- 組件切換時切換影片
- 父組件向子組件傳值
- 父組件向子組件傳遞方法
- 組件案例-評論串列
- 使用 `this.$refs` 來獲取元素和組件
- `ref` 介紹
- `this.$refs` 介紹
- 實體
- 在 Vue 組件中 data 和 props 的區別
- 補充(localStorage 本地存盤)
axios 的使用
Axios 是一個基于 promise 網路請求庫,作用于node.js和瀏覽器中,它是 isomorphic 的(即同一套代碼可以運行在瀏覽器和 node.js 中),在服務端它使用原生 node.js http 模塊, 而在客戶端(瀏覽端)則使用XMLHttpRequests,
1、axios 基本使用
axios 必須先匯入才可以使用
使用 get 或 post 方法即可發送對應的請求
then 方法中的回呼函式會在請求成功或失敗時觸發(成功是第一個,失敗時第二個函式)
通過回呼函式的形參可以獲取回應內容,或錯誤資訊
代碼:
<!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>
<input type="button" value="get請求" class="get">
<input type="button" value="post請求" class="post">
<!-- 官網提供的 axios 在線地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
/*
介面1:隨機笑話
請求地址:https://autumnfish.cn/api/joke/list
請求方法:get
請求引數:num(笑話條數,數字)
回應內容:隨機笑話
*/
document.querySelector(".get").onclick = function () {
axios.get("https://autumnfish.cn/api/joke/list?num=3")
.then(function (response) {
console.log(response);
}, function (err) {
console.log(err);
})
}
/*
介面2:用戶注冊
請求地址:https://autumnfish.cn/api/user/reg
請求方法:post
請求引數:username(用戶名,字串)
回應內容:注冊成功或失敗
*/
document.querySelector(".post").onclick = function () {
axios.post("https://autumnfish.cn/api/user/reg", { username: "jack" })
.then(function (response) {
console.log(response);
}, function (err) {
console.log(err);
})
}
</script>
</body>
</html>
2、vue 中的 axios
代碼:
<!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">
<input type="button" value="獲取笑話" @click="getJoke">
<p>{{joke}}</p>
</div>
<!-- 官網提供的 axios 在線地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src=" https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
/*
介面1:隨機笑話
請求地址:https://autumnfish.cn/api/joke
請求方法:get
請求引數:無
回應內容:隨機笑話
*/
var app = new Vue({
el: "#app",
data: {
joke: "joke"
},
methods: {
getJoke: function () {
console.log(this);
var that = this;
axios.get("https://autumnfish.cn/api/joke").then(
function (response) {
// console.log(response);
console.log(response.data);
that.joke = response.data;
}, function (err) {
console.log(err);
}
)
}
},
})
</script>
</body>
</html>
axios 回呼函式中的 this 已經改變,無法訪問到 data 中資料
把 this 保存起來,回呼函式中直接使用保存的 this 即可
和本地應用的最大區別就是改變了資料來源
Vue中的影片
鏈接:Vue 影片
為什么要有影片:影片能夠提高用戶的體驗,幫助用戶更好的理解頁面中的功能;
1、使用過渡類名實作影片
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 2.自定義兩組樣式,來控制 transition 內部的元素實作影片 -->
<style>
/* v-enter [這是一個時間點] 是進入之前,元素的起始狀態,此時還沒有開始進入 */
/* v-leave-to [這是一個時間點] 是影片離開之后,離開的終止狀態,此時,元素影片已經結束了 */
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(150px);
}
/* v-enter-active 【入場影片的時間段】 */
/* v-leave-active 【離場影片的時間段】 */
.v-enter-active,
.v-leave-active {
transition: all 0.8s ease;
}
</style>
</head>
<body>
<div id="app">
<input type="button" value="toggle" @click="flag=!flag">
<!-- 需求: 點擊按鈕,讓 h3 顯示 ,再點擊,讓 h3 隱藏 -->
<!-- 1. 使用 transition 元素,把需要影片控制的元素,包裹起來 -->
<!-- transition 元素,是Vue官方提供的 -->
<transition>
<h3 v-if="flag">這是一個H3</h3>
</transition>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
flag: false
},
methods: {}
});
</script>
</body>
</html>
2、可修改 v- 前綴
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 2.自定義兩組樣式,來控制 transition 內部的元素實作影片 -->
<style>
/* v-enter [這是一個時間點] 是進入之前,元素的起始狀態,此時還沒有開始進入 */
/* v-leave-to [這是一個時間點] 是影片離開之后,離開的終止狀態,此時,元素影片已經結束了 */
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(150px);
}
/* v-enter-active 【入場影片的時間段】 */
/* v-leave-active 【離場影片的時間段】 */
.v-enter-active,
.v-leave-active {
transition: all 0.8s ease;
}
.my-enter,
.my-leave-to {
opacity: 0;
transform: translateY(70px);
}
.my-enter-active,
.my-leave-active {
transition: all 0.8s ease;
}
</style>
</head>
<body>
<div id="app">
<input type="button" value="toggle" @click="flag=!flag">
<!-- 需求: 點擊按鈕,讓 h3 顯示 ,再點擊,讓 h3 隱藏 -->
<!-- 1. 使用 transition 元素,把需要影片控制的元素,包裹起來 -->
<!-- transition 元素,是Vue官方提供的 -->
<transition>
<h3 v-if="flag">這是一個H3</h3>
</transition>
<hr>
<input type="button" value="toggle2" @click="flag2=!flag2">
<transition name="my">
<h6 v-if="flag2">這是一個H6</h6>
</transition>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
flag: false,
flag2: false
},
methods: {}
});
</script>
</body>
</html>
3、使用第三方類別庫實作影片
1)匯入影片類別庫:
<link rel="stylesheet" type="text/css" href="./lib/animate.css">
2)定義 transition 及屬性:
<transition
enter-active-class="bounceIn"
leave-active-class="bounceOut"
:duration="{enter: 200, leave: 400}">
<h3 v-if="flag" class="animated">這是一個H3</h3>
</transition>
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 引入在線的animate庫 -->
<link rel="stylesheet" href="https://unpkg.com/animate.css@3.5.2/animate.min.css">
<!-- 入場 bounceIn 離場 bounceOut -->
</head>
<body>
<div id="app">
<input type="button" value="toggle" @click="flag=!flag">
<!-- 使用 :duration="{enter: 200, leave: 400}" 來分別設定 入場時長 和 離場時長 -->
<transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="{enter: 200, leave: 400}">
<h3 v-if="flag" class="animated">這是一個H3</h3>
</transition>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
flag: false
},
methods: {}
});
</script>
</body>
</html>
4、使用鉤子函式實作小球的半場影片
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.ball {
width: 15px;
height: 15px;
border-radius: 50%;
background-color: red;
}
</style>
</head>
<body>
<div id="app">
<input type="button" value="快到碗里來" @click="flag=!flag">
<!-- 1. 使用 transition 元素把 小球包裹起來 -->
<!-- 定義 transition 組件以及三個鉤子函式 -->
<transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
<div class="ball" v-show="flag"></div>
</transition>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
flag: false
},
methods: {
// 定義三個 methods 鉤子方法:
// 注意: 影片鉤子函式的第一個引數: el ,表示 要執行影片的那個 DOM 元素 是原生的JS DOM物件
// 大家可以認為 , el 是通過 document.getElementById('') 方式獲取到的原生JS DOM 物件
beforeEnter(el) {
// beforeEnter 表示影片入場之前,此時,影片尚未開始,可以在 beforeEnter 中,設定元素開始影片之前的起始樣式
// 設定小球開始影片之前的,起始位置
el.style.transform = "translate(0,0)"
},
enter(el, done) {
// 這句話,沒有實際的作用,但是,如果不寫,出不來影片效果
// 可以認為 el.offsetWidth 會強制影片重繪
el.offsetWidth
// enter 表示影片 開始之后的樣式,這里,可以設定小球完成影片之后的 結束狀態
el.style.transform = "translate(150px,450px)"
el.style.transition = "all 1s ease"
// 這里的done,其實就是afterEnter 這個函式,也就是說:done 是 afterEnter 函式的參考
done()
},
afterEnter(el) {
// 影片完成之后,會呼叫 afterEnter
this.flag = !this.flag
}
}
});
</script>
</body>
</html>
5、串列影片
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
li {
border: 1px dashed #999;
margin: 5px;
line-height: 35px;
padding-left: 5px;
font-size: 12px;
width: 100%;
}
li:hover {
background-color: pink;
transition: all 0.6s ease;
}
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateY(80px);
}
.v-enter-active,
.v-leave-active {
transition: all 0.6s ease;
}
/* 下面的 .v-move 和 .v-leave-active 配合使用,能夠實作串列后續元素,漸漸地飄上來的效果 */
.v-move {
transition: all 0.6s ease;
}
.v-leave-active {
position: absolute;
}
</style>
</head>
<body>
<div id="app">
<div>
<label for="">
Id:
<input type="text" v-model="id">
</label>
<label for="">
Name:
<input type="text" v-model="name">
</label>
<input type="button" value="增加" @click="add">
</div>
<!-- <ul> -->
<!-- 在實作串列過渡的時候,如果需要過渡的元素,是通過 v-for 回圈渲染出來的,不能使用transition包裹,需要使用transitionGroup -->
<!-- 如果要為 v-for 回圈創建的元素設定影片,必須為每一個 元素 設定 :key 屬性 -->
<!-- 給transition-group 添加 appear 屬性,實作頁面剛展示出來,入場的時候的效果 -->
<!-- 通過為 transition-group 元素,設定tag屬性,指定 transition-group 渲染為指定的元素,如果不指定 tag 屬性,默認
渲染為 span 標簽 -->
<transition-group appear tag="ul">
<li v-for="(item,i) in list" :key="item.id" @click="del(i)">
{{item.id}} --- {{item.name}}
</li>
</transition-group>
<!-- </ul> -->
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
list: [
{ id: 1, name: '周哥' },
{ id: 2, name: '李哥' },
{ id: 3, name: '張哥' },
{ id: 4, name: '沈哥' }
]
},
methods: {
add() {
this.list.push({ id: this.id, name: this.name })
this.id = this.name = ''
},
del(i) {
this.list.splice(i, 1)
}
}
});
</script>
</body>
</html>
Vue 組件
定義 Vue 組件
- 什么是模塊化:模塊化是從代碼的角度出發,分析專案,把專案中一些功能類似的代碼,單獨的抽離為一個個的模塊;那么為了保證大家以相同的方式去封裝模塊,于是我們就創造了模塊化的規范(CommonJS規范);
- 模塊化的好處:方便專案的開發;和后期的維護與擴展;今后如果需要某些固定功能的模塊,則直接拿來參考就行,提高了專案開發效率!
- 什么是組件化:從UI的角度出發考慮問題,把頁面上有重用性的UI解構和樣式,單獨的抽離出來,封裝為單獨的組件;
- 組件化的好處:隨著專案規模的發展,我們手里的組件,會越來越多,這樣,我們今后一個頁面中的UI,幾乎都可以從手中拿現成的組件拼接出來;方便專案的開發和維護;
全域組件定義的三種方式
第一種方式:
1、先呼叫 Vue.extend() 得到組件的建構式:
// 創建全域組件的第一種方式: component
const com1 = Vue.extend({
template: '<h1>這是創建的第一個全域組件</h1>' // template 屬性,表示這個組件的 UI 代碼解構
})
2、通過 Vue.component(‘組件的名稱’, 組件的建構式) 來注冊全域組件:
// 使用 Vue.component 向全域注冊一個組件
// Vue.component('組件的名稱', 組件的建構式)
Vue.component('mycom1', com1)
注意:
如果使用 Vue.component 定義全域組件的時候,組件名稱使用了駝峰命名,則在參考組件的時候,需要把大寫的駝峰改為小寫的字母同時,兩個單詞之間,使用 - 鏈接
如果不使用駝峰,則直接拿名稱來使用即可
以上兩步可寫為一步:
Vue.component('myCom1', Vue.extend({
template: '<h3>這是使用 Vue.extend 創建的組件</h3>'
}))
3、把注冊好的全域組件名稱,以標簽形式引入到頁面中即可:
<!-- 如何引入一個全域的Vue組件呢? 直接把 組件的名稱,以標簽的形式,放到頁面上就好了! -->
<mycom1></mycom1>
第二種方式:
直接使用 Vue.component(‘組件名稱’, { 組件模板物件 })
const com2Obj = {
// 1. template 屬性中,不能單獨放一段文本,必須用標簽包裹起來;
// 2. 如果在 template 屬性中,想要放多個元素了,那么,在這些元素外,必須有唯一的一個根元素進行包裹;
template: '<div><h2>這是直接使用 Vue.component 創建出來的組件</h2><h3>紅紅火火</h3></div>'
}
// 定義全域的組件
// Vue.component 的第二個引數,既接收 一個 組件的建構式, 同時,也接受 一個物件
Vue.component('mycom2', com2Obj)
或者:
Vue.component('mycom2', {
// 注意: 不論是哪種方式創建出來的組件,組件的 template 屬性指向的模板內容,必須有且只能有唯一的一個根元素
template: '<div><h3>這是直接使用 Vue.component 創建出來的組件的組件</h3><span>123</span></div>'
})
第三種方式:
1、先使用 template 標簽定義一個模板的代碼解構:
<!-- 定義一個 template 標簽元素 -->
<!-- 使用 Vue 提供的 template 標簽,可以定義組件的UI模板解構 -->
<template id="tmpl">
<div>
<h3>哈哈,這是在外界定義的組件UI解構</h3>
<h3>我是來搗亂的</h3>
</div>
</template>
2、使用 Vue.component 注冊組件:
// 這是定義的全域組件
Vue.component('mycom3', {
template: '#tmpl'
})
注意: 從更抽象的角度來說,每個組件,就相當于是一個自定義的元素; 注意: 組件中的DOM結構,有且只能有唯一的根元素(Root Element)來進行包裹!
私有組件定義
私有組件只能當前定義的 VM 實體中可以使用
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<login></login>
</div>
<template id="tmpl2">
<div>
<h1>這是私有的 login 組件</h1>
</div>
</template>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {},
components: { //定義實體內部私有組件
login: {
template: "#tmpl2"
}
}
});
</script>
</body>
</html>
組件中展示資料和回應事件
1.組件可以有自己的 data 資料
2.組件的 data 和實體的 data 有點不一樣,實體中的 data 可以為一個物件,但是組件中的 data 必須是一個方法
3.組件中的 data 除了必須為一個方法之外,這個方法內部,還必須回傳一個物件才行
4.組件中的 data 資料使用方式,和實體中的 data 使用方式完全一樣!!!
Vue.component('mycom1', {
template: "<h1>這是全域組件 --- {{ msg }}</h1>",
data: function () {
return {
msg: '這是組件中的data定義的資料'
}
}
})
計數器案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<counter></counter>
<hr>
<counter></counter>
<hr>
<counter></counter>
</div>
<template id="tmpl">
<div>
<input type="button" value="+1" @click="increment">
<h3>{{ count }}</h3>
</div>
</template>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var dataObj = { count: 0 }
// 這是一個計數器組件,身上有個按鈕,每當點擊按鈕,讓 data 中的 count 值 +1
Vue.component('counter', {
template: '#tmpl',
data: function () {
// return dataObj
return { count: 0 }
},
methods: {
increment() {
this.count++
}
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>
</html>
以上案例可以解釋為什么 組件中的 data 必須是一個方法 以及 組件中的 data 除了必須為一個方法之外,這個方法內部,還必須回傳一個物件才行
“組件中的data寫成一個函式,資料以函式回傳值形式定義,這樣每復用一次組件,就會回傳一份新的data,類似于給每個組件實體創建一個私有的資料空間,讓各個組件實體維護各自的資料,而單純的寫成物件形式,就使得所有組件實體共用了一份data,就會造成一個變了全都會變的結果,”
組件切換
切換方式一(使用flag識別符號結合v-if和v-else切換組件)
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<a href="" @click.prevent="flag=true">登錄</a>
<a href="" @click.prevent="flag=flase">注冊</a>
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
Vue.component('login', {
template: '<h3>登錄組件</h3>'
})
Vue.component('register', {
template: '<h3>注冊組件</h3>'
})
var vm = new Vue({
el: '#app',
data: {
flag: true
},
methods: {}
});
</script>
</body>
</html>
切換方式二(使用component標簽的:is屬性來切換組件,并添加影片)
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<a href="" @click.prevent="comName='login'">登錄</a>
<a href="" @click.prevent="comName='register'">注冊</a>
<!-- Vue 提供了 component ,來展示對應名稱的組件 -->
<!-- component 是一個占位符,:is 屬性,可以用來指定要展示的組件名稱 -->
<component :is="comName"></component>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
// 組件名稱是 字串
Vue.component('login', {
template: '<h3>登錄組件</h3>'
})
Vue.component('register', {
template: '<h3>注冊組件</h3>'
})
var vm = new Vue({
el: '#app',
data: {
comName: 'login' //當前 component 中的 :is 系結的組件名稱
},
methods: {}
});
</script>
</body>
</html>
組件切換時切換影片
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(150px);
}
.v-enter-active,
.v-leave-active {
transition: all 0.5s ease;
}
</style>
</head>
<body>
<div id="app">
<a href="" @click.prevent="comName='login'">登錄</a>
<a href="" @click.prevent="comName='register'">注冊</a>
<!-- 通過 mode 屬性,設定組件切換時候的模式 -->
<transition mode='out-in'>
<component :is="comName"></component>
</transition>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
// 組件名稱是 字串
Vue.component('login', {
template: '<h3>登錄組件</h3>'
})
Vue.component('register', {
template: '<h3>注冊組件</h3>'
})
var vm = new Vue({
el: '#app',
data: {
comName: 'login' //當前 component 中的 :is 系結的組件名稱
},
methods: {}
});
</script>
</body>
</html>
注意:通過 mode 屬性,設定組件切換時候的模式 非常重要,可以使影片看起來非常流暢,
父組件向子組件傳值
步驟:
1、把要傳遞給子組件的資料,作為 自定義屬性,通過 v-bind: 系結到子組件身上
2、在子組件中,不能直接使用父組件傳遞過來的資料,需要先使用 props 陣列來接收一下
3、注意:在接收父組件傳遞過來的 props 的時候,接收的名稱,一定要和父組件傳遞過來的自定義屬性,名稱保持一致!
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 父組件可以在 參考子組件的時候,通過 屬性系結(v-bind:)的形式,把需要傳遞給子組件的資料,以屬性系結的形式,傳遞到子組件內部,供子組件使用 -->
<com1 v-bind:parentmsg="msg"></com1>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '123 父組件中的資料'
},
methods: {},
components: {
// 結論: 經過演示,發現,子組件中,默認無法訪問到 父組件中的data 上的資料 和methods 中的方法
com1: {
data() { //注意: 子組件中的data資料,并不是通過 父組件傳遞過來的,而是子組件自身私有的,
// 比如:子組件通過Ajax,請求回來的資料,都可以放到 data 身上
// data 上的資料,都是可讀可寫的
return {
title: '123',
content: 'qqq'
}
},
template: '<h1 @click="changed">這是子組件 --- {{ parentmsg }}</h1>',
// 注意: 組件中的 所有 props 中的資料,都是通過 父組件傳遞給 子組件的
// props 中的資料,都是只讀的,無法重新賦值
props: ['parentmsg'], //把父組件傳遞過來的parentmsg 屬性,現在props 陣列中定義一下,這樣才能使用這個資料
directives: {},
filters: {},
components: {},
methods: {
changed() {
this.parentmsg = '被修改了'
}
},
}
}
});
</script>
</body>
</html>
父組件向子組件傳遞方法
組件向子組件 傳遞方法,使用的是 事件系結機制,v-on,當我們自定義了 一個 事件屬性之后,那么,子組件就能夠,通過某些方式,來呼叫 傳遞進去的這個方法了
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 父組件向子組件 傳遞方法,使用的是 事件系結機制,v-on,當我們自定義了 一個 事件屬性之后,那么,子組件就能夠,通過
某些方式,來呼叫 傳遞進去的這個方法了 -->
<com2 v-on:func="show"></com2>
</div>
<template id="tmpl">
<div>
<h1>這是 子組件</h1>
<input type="button" value="這是子組件中的按鈕 - 點擊它,觸發 父組件傳遞過來的 func 方法" @click="myclick">
</div>
</template>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
// 定義了一個字面量型別的 組件模板物件
var com2 = {
template: '#tmpl', //通過指定一個Id,表示說,要去加載 這個指定Id的 template 元素中的內容,當做組件的HTML結構
data() {
return {
sonmsg: { name: '小頭兒子', age: 6 }
}
},
methods: {
myclick() {
// console.log('ok')
// 當點擊 子組件 按鈕的時候,如何拿到父組件 傳遞過來的 func 方法,并呼叫這個方法?
// emit 英文原意:是觸發,呼叫,發射的意思
// this.$emit('func', 123, 456)
this.$emit('func', this.sonmsg)
}
},
}
var vm = new Vue({
el: '#app',
data: {
datamsgFormSon: null
},
methods: {
show(data) {
// console.log('呼叫了父組件身上的 show 方法: --- ' + data)
console.log(data)
this.datamsgFormSon = data
}
},
components: {
com2
}
});
</script>
</body>
</html>
更多組件之間的傳值參考網站:子組件與父組件之間傳值
組件案例-評論串列
分析:發表評論的業務邏輯
1.評論的資料存到哪里去??? 存放到 localStorage 中
2.先組織出一個最新的評論資料物件
3.想辦法,把第二步中得到的評論物件,保存到 localStorage 中
3.1 localStorage 只支持存放字串物件,要先呼叫 JSON.stringify
3.2 在保存最新的評論資料之前,要先從 localStorage 獲取之前的評論資料( string ),轉化為 一個 陣列物件
然后,把最新的評論,push 到這個陣列
3.3 如果獲取到的 localStorage 中的 評論字串,為空不存在,則 可以 回傳一個 ‘[]’ 讓 JSON.parse 去轉換
3.4 把 最新的評論串列陣列,再次呼叫 JSON.stringify 轉為 陣列字串,然后呼叫 localStorage.setItem()
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<cmt-box @func="loadComments"></cmt-box>
<ul class="list-group">
<li class="list-group-item" v-for="item in list" :key="item.id">
<span class="badge">評論人 : {{ item.user }}</span>
{{ item.content }}
</li>
</ul>
</div>
<template id="tmpl">
<div>
<div class="form-group">
<label>評論人:</label>
<input type="text" class="form-control" v-model="user">
</div>
<div class="form-group">
<label>評論內容:</label>
<textarea class="form-control" v-model="content"></textarea>
</div>
<div class="form-group">
<input type="button" value="發表評論" class="btn btn-primary" @click="postComment">
</div>
</div>
</template>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var commentBox = {
data() {
return {
user: '',
content: ''
}
},
template: '#tmpl',
methods: {
postComment() { //發表評論的方法
// 分析:發表評論的業務邏輯
// 1.評論的資料存到哪里去??? 存放到 localStorage 中
// 2.先組織出一個最新的評論資料物件
// 3.想辦法,把第二步中得到的評論物件,保存到 localStorage 中
// 3.1 localStorage 只支持存放字串物件,要先呼叫 JSON.stringify
// 3.2 在保存最新的評論資料之前,要先從 localStorage 獲取之前的評論資料( string ),轉化為 一個 陣列物件
// 然后,把最新的評論,push 到這個陣列
// 3.3 如果獲取到的 localStorage 中的 評論字串,為空不存在,則 可以 回傳一個 '[]' 讓 JSON.parse 去轉換
// 3.4 把 最新的評論串列陣列,再次呼叫 JSON.stringify 轉為 陣列字串,然后呼叫 localStorage.setItem()
var comment = { id: Date.now(), user: this.user, content: this.content }
// 從 localStorage 中獲取所有的評論
var list = JSON.parse(localStorage.getItem('cmts') || '[]')
list.unshift(comment)
// 重新保存最新的評論資料
localStorage.setItem('cmts', JSON.stringify(list))
this.user = this.content = ''
// 子組件呼叫父組件方法
this.$emit('func')
}
},
}
var vm = new Vue({
el: '#app',
data: {
list: [
{ id: Date.now(), user: '李白', content: '天生我材必有用' },
{ id: Date.now(), user: '小李白', content: '勸君更盡一杯酒' },
{ id: Date.now(), user: '小李', content: '小李飛刀' },
]
},
beforeCreate() { // 注意:這里不能呼叫 loadComments 方法,因為在執行這個鉤子函式的時候,data 和 methods 都還沒有被初始化好
},
created() {
this.loadComments()
},
methods: {
loadComments() { //從本地的localStorage 中,加載評論串列
var list = JSON.parse(localStorage.getItem('cmts') || '[]')
this.list = list
}
},
components: {
'cmt-box': commentBox
}
});
</script>
</body>
</html>
使用 this.$refs 來獲取元素和組件
ref 介紹
ref被用來給元素或子組件注冊參考資訊,參考資訊將會注冊在父組件的$refs物件上,如果在普通的 DOM
元素上使用,參考指向的就是 DOM 元素;如果用在子組件上,參考就指向該子組件實體
通俗的講,ref特性就是為元素或子組件賦予一個ID參考,通過this.$refs.refName來訪問元素或子組件的實體
this.$refs 介紹
this.$refs是一個物件,持有當前組件中注冊過 ref 特性的所有 DOM 元素和子組件實體
注意: $refs只有在組件渲染完成河駁充,在初始渲染的時候不能訪問它們,并且它是非回應式的,因此不能用它在模板中做資料系結
實體
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="button" value="獲取元素" @click="getElement" ref="mtbtn">
<h3 id="myh3" ref="myh3">哈哈哈,今天天氣真好!</h3>
<hr>
<login ref="mylogin"></login>
</div>
<!-- 開發環境版本,包含了有幫助的命令列警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var login = {
template: '<h1>登錄組件</h1>',
data() {
return {
msg: 'son msg'
}
},
methods: {
show() {
console.log('呼叫了子組件方法')
}
},
}
var vm = new Vue({
el: '#app',
data: {},
methods: {
getElement() {
// console.log(document.getElementById('myh3').innerText)
// ref 是英文單詞 【reference】 值型別 和 參考型別 referenceError
// console.log(this.$refs.myh3.innerText)
// console.log(this.$refs.mylogin.msg)
this.$refs.mylogin.show()
}
},
components: {
login
}
});
</script>
</body>
</html>
在 Vue 組件中 data 和 props 的區別
- data 在組件中,要被定義成 function 并回傳一個物件
- props 在組件中,要被定義成陣列,其中,陣列的值都是字串名,表示父組件傳遞過來的資料;
- props 的資料,不要直接拿來修改,如果想要修改,必須在 data 上重新定義一個 屬性,然后把屬性的值 從 this.props 拿過來;
data 上的資料,都是組件自己私有的, data 上的資料,都是可讀可寫的 props 資料,都是外界傳遞過來的資料, props 中的資料只能讀取,不能重新寫入
補充(localStorage 本地存盤)
localstorage 存盤物件分為兩種:
① sessionStrage: session 即會話的意思,在這里的 session 是指用戶瀏覽某個網站時,從進入網站到關閉網站這個時間段,session 物件的有效期就只有這么長,
② localStorage: 將資料保存在客戶端硬體設備上,不管它是什么,意思就是下次打開計算機時候資料還在,
兩者區別就是一個作為臨時保存,一個長期保存,
localStorage 的存盤,讀取,洗掉方法
參考博客:localStorage的存盤,讀取,洗掉
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/310593.html
標籤:其他
