Vue学习
一、Vue的介绍
Vue (读音/vju:/,类似于view)
是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。
Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方
库或既有项目整合。另一方面, 当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能
够为复杂的单页应用提供驱动。
二、引入
<script src="./vue.js"></script>
</head>
<body>
<div id="box">
{{10+20}}
{{myname}}
</div>
<script>
var a = new Vue({
el: "#box",
data:{
myname:"zzy" //状态
}
})
</script>
</body>
三、拦截原理
<body>
<div id="box">
</div>
<script>
var obj = {
}
var obox = document.getElementById("box")
Object.defineProperty(obj,"age",{
get:function(){ //访问
console.log("get")
return obox.innerHTML
},
set:function(value){ //修改
console.log("set",value)
obox.innerHTML = value
}
})
</script>
</body>
四、模板语法
<style>
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
</style>
<body>
<div id="box">
{{myname}}-{{age}}
<div :class="whichColor">切换背景色</div>
<div :class="isColor?'red':'yellow'">切换背景色</div>
<img :src="imgpath" />
<button @click="handleChange()">Change</button>
<!-- v-show v-if 指令 -->
<div v-show="isShow">我是动态显示和隐藏</div>
<div v-if="isCreated">我是动态创建和删除</div>
<!-- v-for 列表渲染的指令 -->
<ul>
<li v-for="(item,index) in list">
{{item}}-{{index}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
myname: "zzy",
age: 18 + "岁",
whichColor: "red",
isColor: true,
imgpath: " ",
isShow: false,
isCreated: false,
list: ["aaa", "bbb", "ccc"]
},
// 方法
methods: {
handleChange() {
console.log("handleChange", this)
this.myname = "xiaohong"
this.age = 19 + "岁"
this.whichColor = "yellow"
this.isColor = !this.isColor
this.imgpath = "https://sponsors.vuejs.org/images/passionate_people.png"
this.isShow = !this.isShow
}
}
})
</script>
五、Todolist
<body>
<div id="box">
<!-- 双向绑定了一个输入框的Value -->
<input type="text" v-model="mytext">
<!-- {{mytext}} -->
<button @click="handleAdd()">add</button>
<ul v-show="datalist.length">
<li v-for="(data,index) in datalist">
{{data}}
<button @click="handleDel(index)">del</button>
</li>
</ul>
<div v-show="!datalist.length">请添加内容,亲😙</div>
</div>
<script>
var bm = new Vue({
el: "#box",
data: {
datalist: ["111", "222", "333"],
mytext: "aaa"
},
methods: {
handleAdd() {
// console.log("Value",this.mytext)
this.datalist.push(this.mytext)
// 清空
thsi.mytext = ""
},
handleDel(index) {
// console.log("del", index)
this.datalist.splice(index,1)
}
}
})
</script>
</body>
六、v-html指令
<body>
<div id="box">
{{mytext}}
<div v-html="mytext"></div>
</div>
<script>
new Vue({
el: "#box",
data: {
mytext: "<b>加粗的</b>"
}
})
</script>
</body>
七、点击变色
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
display: flex;
}
li {
flex: 1;
line-height: 50px;
height: 50px;
text-align: center;
}
.active {
background-color: yellow;
}
</style>
<body>
<div id="box">
<ul>
<li v-for="(data,index) in datalist" :class="current == index ? 'active': '' " @click="handleClick(index)">
{{data}}
</li>
</ul>
</div>
<script>
new Vue({
el: "#box",
data: {
datalist: ["首页", "列表", "内容"],
current: 0
},
methods: {
handleClick(index) {
console.log(index)
this.current = index
}
}
})
</script>
</body>
八、class与style
<1>.Vue2.0版本
</head>
<style>
</style>
<body>
<div id="box">
<div :class="classobj">动态切换class-1-对象</div>
<div :class="classarr">动态切换class-2-数组</div>
<div :style="styleobj">动态切换style-1-对象</div>
<div :style="stylearr">动态切换style-2-数组</div>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
classobj: {
aa: true,
bb: true,
cc: false,
},
classarr: ["aa", "bb"],
styleobj: {
backgroundColor: 'red'
},
stylearr: [{ backgroundColor: 'yellow' }]
}
})
//vue2 解决方案: Vue.set(对象,属性,true)
//Vue.set(classobj,"dd",true)
//Vue3 支持动态增加属性的拦截
</script>
</body>
<2>.Vue3.0版本
<body>
<div id="box">
{{10+20}}
{{myname}}
{{mytext}}
<input type="text" v-modle="mytext">
<button @click="handleAdd">add</button>
<div :class="classobj">动态切换class-对象</div>
</div>
<script>
//vue2
// new Vue({
// el:"#box"
// data:{myname:"zzy"}
// })
//vue3
var obj = {
data() {
//函数式
return {
myname: "zzy",
mytext: "",
classobj: {
aa: true,
bb: true,
cc: false,
}
}
},
methods: {
handleAdd() {
console.log("add", this.mytext)
this.classobj.dd = true
}
}
}
Vue.createApp(obj).mount("#box")
</script>
</body>
九、条件渲染
<body>
<!-- <div id="box">
<div v-if="isCreated">111</div>
<div v-else>222</div>
<ul>
<li v-for="item in datalsit">
{{item.title}}--
<span v-if="item.state == 0">未付款</span>
<span v-else-if="item.state == 1">待发货</span>
<span v-else-if="item.state == 2">已发货</span>
<span v-else>已完成</span>
</li>
</ul>
</div> -->
<div id="box">
<template v-if="isCreated">
<div>111</div>
<div>222</div>
<div>333</div>
</template>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
isCreated: true
//template 就是一个包装元素,不会真正创建在页面上
}
})
</script>
</body>
十、列表渲染
<body>
<div id="box">
<ul>
<li v-for="item of datalist">
{{item}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
datalist: ["111", "222", "333"]
}
})
</script>
</body>
十一、key设置
<div id="box">
<ul>
<li v-for="(item,index) of datalist" :key="item">
{{item}}--{{index}}
</li>
</ul>
<ul>
<li v-for="(item,key) of obj">
{{key}} - {{item}}
</li>
</ul>
<ul>
<li v-for="item in 10">
{{item}}
</li>
</ul>
</div>
<script>
var vm = Vue.createApp({
data() {
return {
datalist: ["1111", "2222", "3333"],
obj: {
name: "zzy",
age: 100,
}
}
}
}).mount("#box")
</script>
十二、检测数组变动
<div id="box">
<!-- input change事件区别 -->
<input type="text" @input="handleInput" v-model="mytext" />
<ul>
<li v-for="data in datalist" :key="data">
{{data}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
mytext: "",
datalist: ["aaa", "add", "bbb", "bbc", "ccc", "ddd", "eee", "ade"],
originList: ["aaa", "add", "bbb", "bbc", "ccc", "ddd", "eee", "ade"]
},
methods: {
handleInput() {
console.log("input", this.mytext)
// es5 filter
setTimeout(() => {
this.datalist = this.originList.filter(item => item.includes(this.mytext))
}, 2000)
// console.log(newlist)
}
}
})
var arr = ["aaa", "add", "bbb", "bbc", "ccc", "ddd", "eee", "ade"]
var newlist = arr.filter(item => item.includes("a"))
console.log(newlist, arr)
</script>
十三、事件处理
<div id="box">
{{count}}
<button @click="handleAdd1($event,1,2,3)">add-1-函数表达式</button>
<button @click="handleAdd2">add-2-函数名</button>
<button @click="count++">add-3-表达式</button>
<input type="text" @input="handleInput" />
<ul @click.self="handleUlClick">
<li @click.stop="handleLiClick">1111</li>
<li @click="handleLiClick">2222</li>
<li @click.once="handleLiClick">3333</li>
</ul>
<a href="http://www.baidu.com" @click.prevent>跳转</a>
<input type="text" @keyup.enter.ctrl="handleKeyup" />
<input type="text" @keyup.65="handleKeyup" />
<!-- .esc , .up .down .left .right ,.space .ctrl .shift .delete -->
</div>
<script type="text/javascript">
new Vue({
el: "#box",
data: {
count: 1
},
methods: {
handleAdd1(evt, a, b, c) {
console.log(evt, a, b, c)
this.count++
},
handleAdd2(evt) {
this.count++
console.log(evt.target)
},
handleInput(evt) {
console.log("input", evt.target.value)
},
handleLiClick(evt) {
console.log("li")
// evt.stopPropagation()
},
handleUlClick() {
console.log("ul")
},
handleKeyup(evt) {
// console.log("keyup",evt.keyCode)
// if(evt.keyCode===13){
console.log("li add ", evt.target.value)
// }
}
}
})
</script>
十四、模糊框
<style>
#overlay {
background: rgba(0, 0, 0, 0.6);
width: 100%;
margin: auto;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
#center {
background: #ffff;
border-radius: 5px;
/* 边框圆角 */
padding-top: 15px;
padding-left: 30px;
padding-bottom: 15px;
width: 290px;
height: 160px;
position: fixed;
margin: auto;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
</style>
</head>
<body>
<!-- //模态框 -->
<div id="box">
<button @click="isShow=true">show</button>
<!-- <div id="overlay" v-show="isShow" @click="isShow=false">
<div id="center" @click.stop>
<div>用户名:<input type="text"/></div>
<div>密码:<input type="password"/></div>
<div>
<button>登录</button>
</div>
</div>
</div> -->
<div id="overlay" v-show="isShow" @click.self="isShow=false">
<div id="center">
<div>用户名:<input type="text" /></div>
<div>密码:<input type="password" /></div>
<div>
<button>登录</button>
</div>
</div>
</div>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
isShow: false,
}
})
</script>
十五、表单绑定
<div id="box">
{{mytext}}
<textarea v-model="mytext"></textarea>
<div>
<div>用户名:<input v-model="mytext" /></div>
<input type="checkbox" v-model="isRemember" /> 记住用户名
<button @click="handleLogin">登录</button>
</div>
<div>
<h2>注册页面-兴趣爱好</h2>
<input type="checkbox" v-model="checkList" value="vue" /> vue
<input type="checkbox" v-model="checkList" value="react" /> react
<input type="checkbox" v-model="checkList" value="wx" /> 小程序
</div>
{{checkList}}
<div>
<h2>性别选择</h2>
<input type="radio" v-model="select" value="a" /> 男
<input type="radio" v-model="select" value="b" /> 女
</div>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
mytext: localStorage.getItem("username"),
isRemember: true,
checkList: [],
select: "a"
},
methods: {
handleLogin() {
if (this.isRemember) {
localStorage.setItem("username", this.mytext)
}
console.log(this.mytext, this.checkList, this.select)
}
}
})
</script>
<1>.购物车
<div id="box">
<input type="checkbox" v-model="isAll" @change="handleAllChecked" />全选/全不选
<ul>
<li v-for="(item,index) in datalist" :key="item.id">
<input type="checkbox" v-model="checkList" :value="item" @change="handleItemChecked" />
<img :src="item.pic" />
<div>
<div>{{item.name}}</div>
<div style="color:red;">¥{{item.price}}</div>
</div>
<div>
<button @click="item.number--" :disabled="item.number===1">-</button>
<span>{{item.number}}</span>
<button @click="item.number++" :disabled="item.number===item.limit">+</button>
</div>
<div>
<button @click="handleDeleteClick(index,item.id)">删除</button>
</div>
</li>
</ul>
<div>总金额:{{ sum() }}</div>
{{checkList}}
</div>
<script type="text/javascript">
var obj = {
data() {
return {
isAll: false,
checkList: [], //勾选购物车的数据
datalist: [{
name: "商品1",
price: 10,
number: 1,
id: 1,
limit: 5, //限购
pic: "https://static.maizuo.com/pc/v5/usr/movie/44dc08914d508fc47c8267c6ca73f2d8.jpg"
},
{
name: "商品2",
price: 20,
number: 2,
id: 2,
limit: 10, //限购
pic: "https://static.maizuo.com/pc/v5/usr/movie/44dc08914d508fc47c8267c6ca73f2d8.jpg"
},
{
name: "商品3",
price: 30,
number: 3,
id: 3,
limit: 15, //限购
pic: "https://static.maizuo.com/pc/v5/usr/movie/44dc08914d508fc47c8267c6ca73f2d8.jpg"
}
]
}
},
methods: {
sum() {
var total = 0
//累加计算 checkList 数组的每一项的 价格*数量
this.checkList.forEach(item => {
total += item.price * item.number
})
return total
},
handleDeleteClick(index, id) {
// console.log(index)
// 删除的是datalist-靠 index
this.datalist.splice(index, 1)
// 删除checklist-靠id
// console.log(id)
this.checkList = this.checkList.filter(item => item.id !== id)
//同步一下状态
this.handleItemChecked()
},
//全选
handleAllChecked() {
// console.log(this.isAll)
if (this.isAll) {
this.checkList = this.datalist
} else {
this.checkList = []
}
},
//每项选择
handleItemChecked() {
if (this.checkList.length === this.datalist.length) {
// console.log("全选")
this.isAll = true
} else {
// console.log("未全选")
this.isAll = false
}
}
}
}
var vm = Vue.createApp(obj).mount("#box")
</script>
<2>.修饰符
<div id="box">
<!-- lazy修饰符 -->
<input v-model.lazy="mytext" />
{{mytext}}
<input type="number" v-model.number="myage" />
<input type="text" v-model.trim="myusername" />
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#box",
data: {
mytext: "",
myage: 0,
myusername: ""
}
})
</script>
十六、计算属性
<div id="box">
{{ myname.substring(0,1).toUpperCase() + myname.substring(1) }}
{{ myComputedName }}
{{ myComputedName }}
{{ myComputedName }}
{{ myMethodName() }}
{{ myMethodName() }}
{{ myMethodName() }}
</div>
<script>
//计算属性(防止模板过重,难以维护),负责逻辑放在计算属性中来写。
// 计算属性 有缓存, 基于依赖的缓存
var vm = new Vue({
el: "#box",
data: {
myname: "zzy",
},
//方法:
methods: {
myMethodName() {
console.log("myMethodName-方法")
return this.myname.substring(0, 1).toUpperCase() + this.myname.substring(1)
}
},
//计算的
computed: {
myComputedName() {
console.log("myMethodName-计算属性")
return this.myname.substring(0, 1).toUpperCase() + this.myname.substring(1)
}
}
})
/*
0. data => 状态,被拦截。
1. 方法==》 事件绑定, 逻辑计算。可以不用return,没有缓存
2. 计算属性(重视结果)=》 解决模板过重问题,必须有return ,只求结果 ,有缓存,同步。
3. watch (重视过程), 监听一个值的改变。 不用返回值 ,异步同步
*/
</script>
十七、模糊查询
<div id="box">
<!-- input change事件区别 -->
<input type="text" v-model="mytext" />
<ul>
<li v-for="data in computedList" :key="data">
{{data}}
</li>
</ul>
<!-- {{ test() }} -->
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
mytext: "",
datalist: ["aaa", "add", "bbb", "bbc", "ccc", "ddd", "eee", "ade"],
},
//计算属性
computed: {
computedList() {
//ajax 不好用了,,,,,
return this.datalist.filter(item => item.includes(this.mytext))
}
}
})
</script>
十八、watch
<div id="box">
<!-- input change事件区别 -->
<input type="text" v-model="mytext" />
<ul>
<li v-for="data in datalist" :key="data">
{{data}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
mytext: "",
datalist: ["aaa", "add", "bbb", "bbc", "ccc", "ddd", "eee", "ade"],
originList: ["aaa", "add", "bbb", "bbc", "ccc", "ddd", "eee", "ade"]
},
watch: {
mytext(newval) {
console.log("改变了", newval)
setTimeout(() => {
this.datalist = this.originList.filter(item => item.includes(newval))
}, 1000)
}
}
})
</script>
十九、fetch
<style>
li {
overflow: hidden;
list-style: none;
padding: 10px;
}
li img {
float: left;
width: 100px;
}
</style>
</head>
<body>
<div id="box">
<button @click="handleFetch">ajax-fetch11</button>
<ul>
<li v-for="data in datalist" :key="data.filmId">
<img :src="data.poster" />
{{data.name}}
</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el: "#box",
data: {
datalist: []
},
methods: {
handleFetch() {
fetch("./json/maizuo.json")
.then(res => res.json())
.then(res => {
console.log(res.data.films)
this.datalist = res.data.films
})
.catch(err => {
console.log(err)
})
// fetch("https://m.vip.com/server.html?rpc&method=pageCache&f=www&_=1563946036520",{
// method:"post",
// headers:{
// "Content-Type":"application/json"
// },
// body:JSON.stringify({
// name:"kerwin",
// age:100
// })
// }).then(res => res.json()).then(res => {
// console.log(res)
// });
}
}
})
/*
/*
get url路径 ?name=kerwin&age=100
post body请求体 ,
(1)x-www-formurlencoded , name=kerwin&age=100
(2) json , `{"name":"kerwin",age:100}`
// post-1
fetch("**",{
method:'post',
headers: {
"Content‐Type": "application/x‐www‐form‐urlencoded"
},
body: "name=kerwin&age=100",
}).then(res=>res.json()).then(res=>{console.log(res)});
// post-2
fetch("https://m.vip.com/server.html?rpc&method=pageCache&f=www&_=1563946036520",{
method:'post',
headers: {
"Content‐Type": "application/json"
},
body: JSON.stringify({
name:"kerin",
age:100
})
}).then(res=>res.json()).then(res=>{console.log(res)});
*/
/*
函数表达式, --模糊查询,购物车金额===>计算属性-根据依赖计算结果的
函数表达式传参 --图片转换 ====> 过滤器-数据格式化
*/
</script>
</body>
二十、axios
<div id="box">
<button @click="handleClick()">ajax - axios</button>
<ul>
<li v-for="data in datalist" :key="data.filmId">
<img :src="data.poster" />
<div>{{data.name}}</div>
<div>观众评分:{{data.grade}}</div>
</li>
</ul>
</div>
<script type="text/javascript">
new Vue({
el: "#box",
data: {
datalist: []
},
methods: {
handleClick() {
axios.get("./json/maizuo.json").then(res => {
// console.log()
this.datalist = res.data.data.films
})
}
}
})
/*
get url路径 ?name=zzy&age=18
post body请求体 ,
(1)x-www-formurlencoded , name=zzy&age=18
(2) json , `{"name":"zzy",age:18}`
axios.post("****","name=zzy&age=18") // (1)
axios.post("****",{name:"zzy",age:18}) //(2)
*/
</script>
二十一、猫眼数据
<body>
<div id="box">
<button @click="handleAjax">click-ajax</button>
<ul>
<li v-for="item in datalist" :key="item.id">
<img :src="handleImg(item.img)"/>
{{item.nm}}
</li>
</ul>
</div>
<script >
new Vue({
el:"#box",
data:{
datalist:[]
},
methods:{
handleAjax(){
axios.get("./json/maoyan.json").then(res=>{
console.log(res.data.movieList)
this.datalist = res.data.movieList
//for 处理
})
},
handleImg(url){
return url.replace('w.h/','')+'@1l_1e_1c_128w_180h'
}
}
})
</script>
</body>
二十二、全局与局部
<div id="box">
<zzy-navbar>
<div>aaaaaaaaaaaaaaaaaaaaaa</div>
</zzy-navbar>
<child></child>
<zzy-child></zzy-child>
</div>
<script>
//定义一个全局的组件
Vue.component("zzyNavbar", {
//dom, js ,css
template: `<section style="background:red;border:5px solid black;">
<button @click="handleLeft">left</button>
猫眼电影-{{myname}}
<button @click="handleRight">right</button>
<child></child>
<zzy-child></zzy-child>
</section>`,
methods: {
handleLeft() {
console.log("left")
},
handleRight() {
console.log("right")
}
},
computed: {},
watch: {},
//data必须是函数写法
data() {
return {
myname: "11111111"
}
},
//局部
components: {
"zzyChild": {
template: `
<div>child-{{myname}}</div>
`,
data() {
return {
myname: "child-11111"
}
}
}
}
})
Vue.component("child", {
template: `
<div style="background:yellow">公司标语</div>
`
})
//根组件
new Vue({
el: "#box",
data: {
}
})
// 1. 起名字 :js驼峰, html 链接符-
// 2. dom片段 没有代码提示 没有高亮显示 - vue单文件组件解决
// 3. css 只能写成 行内。- vue单文件组件解决
// 4. template 包含一个根节点
// 5. 组件是孤岛,无法【直接】访问外面的组件的状态或者方法。- 间接的组件通信来交流。
// 6. 自定义的组件 data 必须是一个函数,
// 7. 所有的组件都在一起, 太乱了 --- vue单文件组件解决
</script>
二十三、组件-父传子
<div id="box">
<div style="background:yellow;">根组件标题</div>
<navbar myname="电影" :myright="false" :myparent="parent">
</navbar>
<navbar myname="影院" :myparent="parent"></navbar>
<navbar myname="登录" :myparent="parent"></navbar>
</div>
<script>
Vue.component("navbar", {
// props:["myname","myright"], //接受myname属性, this.myname
// props:{
// myname:String,
// myright:Boolean
// },//接受myname属性, 属性验证
props: {
myname: {
type: String,
default: ""
},
myright: {
type: Boolean,
default: true
},
myparent: {
type: String,
default: ""
}
},//接受myname属性, 属性验证, 默认属性
template: `<div>
<button>left</button>
<span>{{myname}}--{{myparent}}</span>
<button v-show="myright">right</button>
</div>`
})
new Vue({
el: "#box",
data: {
parent: "11111111111111111111111111"
}
})//创建根组件
</script>
二十四、组件-子传父
<div id="box">
<navbar @myevent="handleEvent"></navbar>
<sidebar v-show="isShow" ></sidebar>
</div>
<script>
Vue.component("navbar", {
template: `
<div style="background-color: red;">
<button @click="handleClick()">点击</button>-导航栏
</div>
`,
methods:{
handleClick(){
// console.log("子传父, 告诉父组件 ,取反您的isShow")
this.$emit("myevent",1000000000)
}
}
})
Vue.component("sidebar", {
template: `
<div style="background-color: yellow;" >
<ul>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
</ul>
</div>
`
})
new Vue({
el: "#box",
data: {
isShow: true
},
methods:{
handleEvent(data){
console.log("父组件的定义的事件",data)
this.isShow = !this.isShow
}
}
})
/*
父传子---属性
子传父---事件
*/
</script>
二十五、组件-抽屉
<div id="box">
<navbar @myevent="handleEvent"></navbar>
<sidebar v-show="isShow"></sidebar>
</div>
<script>
Vue.component("navbar",{
template:`
<div>
nabbar-<button @click="handleClick">click</button>
</div>
`,
methods:{
handleClick(){
// 通知父组件 取反 isShow - 子传父 依靠 事件
this.$emit("myevent")
}
}
})
Vue.component("sidebar",{
template:`
<ul style="background-color: yellow;width: 200px;height: 500px;" >
<li>首页</li>
<li>钱包</li>
<li>设置</li>
</ul>
`
})
new Vue({
el:"#box",
data:{
isShow:false
},
methods:{
handleEvent(){
console.log("父组件","1111111")
this.isShow = !this.isShow
}
}
})
</script>
二十六、组件-refs
<div id="box">
<input type="text" ref="mytext" />
<input type="password" ref="mypassword" />
<div ref="mydiv">111111</div>
<button @click="handleAdd">add</button>
<child ref="mychild"></child>
</div>
<script>
Vue.component("child", {
data() {
return {
myname: "child-111111111111111111111"
}
},
template: `<div>
child---{{myname}}
</div>`
})
new Vue({
el: "#box",
methods: {
handleAdd() {
// console.log(this.$refs.mytext,this.$refs.mypassword,this.$refs.mydiv)
// console.log(this.$refs.mychild.myname)
this.$refs.mychild.myname = "child-2222222222222222"
}
}
})
/*
ref -绑定dom节点,拿到的就是 dom对象
ref -绑定组件,拿到的就是 组件对象
*/
</script>
二十七、中间人模式
<style>
.item {
overflow: hidden;
padding: 10px;
width: 400px;
border: 1px solid red;
}
.item img {
width: 100px;
float: left;
}
.film {
border: 1px solid black;
height: 1500px;
}
.filminfo {
width: 300px;
min-height: 200px;
background: yellow;
position: fixed;
right: 50px;
top: 100px;
border: 1px solid blue;
}
</style>
<script src="lib/vue.js"></script>
</head>
<body>
<div id="box">
<button @click="handleAjax">ajax</button>
<film-item v-for="item in datalist" :key="item.filmId" :mydata="item" @event="handleEvent"></film-item>
<!-- {{filmData}} -->
<film-detail :film-data="filmData"></film-detail>
</div>
<script>
Vue.component("filmItem", {
props: ["mydata"],
template: `
<div class="item">
<img :src="mydata.poster"/>
{{mydata.name}}
<div>
<button @click="handleClick">详情</button>
</div>
</div>
`,
methods: {
handleClick() {
// console.log(this.mydata.synopsis)
this.$emit("event", this.mydata.synopsis)
}
}
})
Vue.component("filmDetail", {
props: ["filmData"],
template: `
<div class="filminfo">
{{filmData}}
</div>
`
})
new Vue({
el: "#box",
data: {
datalist: [],
filmData: ""
},
mounted() {
fetch("./json/test.json")
.then(res => res.json())
.then(res => {
console.log(res.data.films)
this.datalist = res.data.films
})
},
methods: {
handleAjax() {
fetch("./json/test.json")
.then(res => res.json())
.then(res => {
console.log(res.data.films)
this.datalist = res.data.films
})
},
//自定义事件处理器
handleEvent(data) {
console.log("父组件定义", data)
this.filmData = data
}
}
})
</script>