Vue 元件
axios實現資料請求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="film in films_list">
<p>電影名字是:{{film.name}}</p>
<img :src="film.poster" alt="" width="100px" height="150px">
<p>電影介紹:{{film.synopsis}}</p>
</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
films_list:[]
},
created() {
axios.get('http://127.0.0.1:5000/films').then(res => {
console.log(res.data)
this.films_list=res.data.data.films
})
}
})
</script>
</html>
from flask import Flask,make_response,jsonify
app=Flask(__name__)
@app.route('/films')
def films():
import json
with open('./movie.json','r',encoding='utf-8') as f:
res=json.load(f)
obj = make_response(jsonify(res))
obj.headers['Access-Control-Allow-Origin']='*'
return obj
if __name__ == '__main__':
app.run()
計算屬性
我們可以通過計算屬性computed
來快取計算,什麼意思呢?
在Vue中我們可以使用插值來展示資料,插值的普通函式,只要頁面一重新整理,函式就會重新運算,不管和函式有關沒關的值都會變,函式也會重新計算,導致執行效率降低;
那麼我們可以將自定義函式寫在computed中來控制,把函式當成屬性來用,呼叫不需要加括號,只有這個函式使用的屬性(變數)發生變化,函式才重新運算,這樣做可以減輕壓力,減少資源浪費
案例一:首字母大寫
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>計算屬性</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<div style="font-size: 20px">
輸入內容:<input type="text" v-model="mytext"> ----》 {{mytext.substring(0,1).toUpperCase()+mytext.substring(1)}}
<br><br>
<p>函式繫結(會重新整理頁面,也不推薦):<input type="text" :value="getName()"></p>
<p>計算屬性(推薦):<input type="text" :value="getName1"></p>
</div>
<hr>
<div style="font-size: 20px">
<p>輸入內容:<input type="text" v-model="mytext1"> -----》{{mytext1}}</p>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
mytext: '',
mytext1:''
},
methods:{
getName(){
console.log('函式方式,我執行了')
return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
}
},
//計算屬性
computed:{
getName1(){
console.log('計算屬性,我執行了')
return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
}
}
})
</script>
</html>
我們可以發現只有和屬性相關的才會列印,如果下面輸入內容只是列印了普通函式,就算函式內和mytext1
不相關
案例二:過濾案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>過濾案例</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.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(){
var _this = this
console.log('執行了',_this)
var datalist2 = _this.dataList.filter(function(item){
console.log(_this)
return item.indexOf(_this.myText) > -1
})
return datalist2
}
}
})
</script>
</html>
監聽屬性
watch
來設定監聽屬性,當mytext
發生變化,就會執行和mytext繫結的函式方法
<!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="mytext">--->{{mytext}}
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
mytext: '',
},
watch: {
// 只要mytext發生變化,就會執行該函式
mytext: function () {
console.log('我變化了,執行')
}
}
})
</script>
</html>
區域性元件
寫在
components
裡的是區域性元件,位置被限制,只能再區域性使用
比如如下例子中,Top
元件只能在只能再id為app的標籤(div)內使用, Top
元件內如果想再定義子元件,只能在該元件內的template
中的div
內使用
<!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>
<Bottom></Bottom>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {},
// 定義再這裡面的叫區域性元件,只能再區域性使用,只能再id為app的標籤內使用
components: {
'Top': {
//寫在一個div裡
template: `
<div>
<h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1>
<hr>
<button @click="handleC">點我看美女</button>
</div>
`,
//data是函式,可以設定返回值
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>
全域性元件
任意位置都可以使用,但是也得是在vue例項託管的div範圍內
<!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('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: '#app',
})
</script>
</html>
元件通訊之父傳子
元件間data資料不同享,資料傳遞,如果我們想從父元件傳遞到子元件資料通過props
自定義屬性來實現,比如如下例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
子元件顯示:<top :value="handleName"></top>
<hr>
父元件輸入內容:<input type="text" v-model="handleName">
</div>
</body>
<script>
Vue.component('top', {
template: ` <div>
<h1 style="background: tomato;font-size: 30px;text-align: center">{{value}}</h1>
</div> `,
// 必須叫props,陣列內放自定義屬性的名字
props:{
value: String, // key是自定義屬性名,value是型別名,如果是別的型別就報錯
},
//props也可以寫成陣列的形式,不帶驗證功能
// props:['value',]
})
var vm = new Vue({
el: '#app',
data: {
handleName: ''
}
})
</script>
</html>
元件通訊之子傳父
ps:Vue內建的物件都以$xx出現
我們可以通過自定義事件來實現子元件向父元件傳遞資料,在子元件中使用$emit('自定義事件',引數)
來實現
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<top @myevent="handleRecv"></top>
<hr>
<h1 style="background: green;font-size: 60px;text-align: center">父元件</h1>
<p>接收子元件傳送的資料:{{childText}}</p>
</div>
</body>
<script>
Vue.component('top', {
template: ` <div>
<h1 style="background: tomato;font-size: 60px;text-align: center">{{myheader}}</h1>
<p>子元件輸入內容:<input type="text" v-model="text"></p>
<p><button class="btn-success" @click="handleSend">向父元件傳送資料</button></p>
</div> `,
data(){
return {
myheader:'子元件',
text:''
}
},
methods:{
handleSend(){
//myevent是自定義事件,代表將子元件的text交給myevent事件處理
this.$emit('myevent',this.text)
}
}
})
var vm = new Vue({
el: '#app',
data: {
//接收子元件的資料
childText:''
},
methods: {
handleRecv(data){
// 接收引數,賦值給父元件的childText
this.childText=data
}
}
})
</script>
</html>
ref屬性(元件間通訊)
普通標籤使用
普通標籤使用ref屬性,通過$refs
獲取到的就是ref屬性所在的標籤,獲取到的是一個物件,如果多個標籤寫了ref屬性,那麼就將所有帶ref屬性的標籤弄到一個物件中,可以對html進行操作設定等,如下示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1 style="align-content: center">普通標籤使用ref</h1>
<p><input type="text" ref="myinput"></p>
<p><img src="" height="100px" width="100px" ref="myimg"></p>
<p><button @click="handleC">點我</button>
</p>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
text:''
},
methods: {
handleC(){
console.log('我被點了')
console.log(this.$refs) // 是所有標籤寫了ref屬性的物件{myinput:真正的標籤,myimg:真正的標籤}
console.log(this.$refs.myinput.value)
//設定值
this.$refs.myinput.value='HammerZe'
//設定src屬性,顯示圖片
this.$refs.myimg.src='https://img0.baidu.com/it/u=3608430476,1945954109&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=494'
}
}
})
</script>
</html>
元件使用ref屬性
ref屬性,如果放在元件上,就是當前元件物件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 元件使用ref屬性 -->
<top ref="top"></top>
<p>通訊:<input type="text" v-model="text"></p>
<p>父元件按鈕:<button @click="handleC">點我</button></p>
</p>
</div>
</body>
<script>
Vue.component('top', {
template: `
<div>
<h1>{{myheader}}</h1>
<p>子元件按鈕:<button @click="handleC">點我看美女</button></p>
<hr>
</div>
`,
data() {
return {
myheader: "頭部",
}
},
methods:{
handleC(){
alert("美女")
}
}
},)
let vm = new Vue({
el: '#app',
data: {
text:''
},
methods: {
//放在元件上
handleC() {
console.log(this.$refs.top) //VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
/*子傳父*/
// 父元件拿子元件的值
console.log(this.$refs.top.myheader)
// this.text=this.$refs.top.myheader
// 父元件呼叫子元件的方法
this.$refs.top.handleC()
/*父傳子*/
this.$refs.top.myheader=this.text
}
}
})
</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">
<child1></child1>
<child2></child2>
</div>
</body>
<script>
var bus=new Vue() //new一個vue的例項,就是中央事件匯流排
Vue.component('child1', {
template: `<div>
<input type="text" ref="mytext">
<button @click="handleClick">點我</button>
</div>`,
methods:{
handleClick(){
bus.$emit('suibian',this.$refs.mytext.value) //釋出訊息,名字跟訂閱訊息名一致
}
}
})
Vue.component('child2', {
template: `<div>
<div>收到的訊息 {{msg}}</div>
</div>`,
data(){
return {msg:''}
},
mounted(){
//生命週期,當前元件dom建立完後悔執行
console.log('當前元件dom建立完後悔執行')
//訂閱訊息
bus.$on('suibian',(item)=>{
console.log('收到了',item)
this.msg=item
})
}
})
var vm = new Vue({
el: '#box',
data: {},
methods: {
handleClick() {
console.log(this)
//this.$refs.mytext 獲取到input控制元件,取出value值
console.log(this.$refs.mytext.value)
console.log(this.$refs.mychild.text)
// this.$refs.mychild.add()
this.$refs.mychild.add('傳遞引數')
}
}
})
</script>
</html>
動態元件和keep-alive
動態元件:實現點選不同的連線顯示不同的頁面,實現跳轉,使用component
標籤,用is
屬性繫結,指定哪個顯示哪個
keep-alive:通過keep-alive標籤實現元件不銷燬,保留原來輸入的內容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./js/vue.js"></script>
</head>
<style>
#menu {
font-size: 18px;
font-weight: bold;
}
#menu li {
text-decoration: none; /*去掉前面的圓點*/
list-style: none;
float: left;
margin-right: 20px;
}
</style>
<body>
<div id="app">
<ul id="menu">
<li @click="changeC('index')">首頁</li>
<li @click="changeC('order')" >訂單</li>
<li @click="changeC('good')">商品</li>
</ul>
<keep-alive>
<component :is='who'></component>
</keep-alive>
</div>
</body>
<script>
//三個元件
Vue.component('index', {
template: `
<div style="overflow:hidden;">
<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
who: 'index'
},
methods: {
changeC(data) {
this.who = data
}
}
})
</script>
</html>