数据双向绑定和组件
表单输入绑定
数据双向绑定
v-model 只能应用在input textare select 表单控件中
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!--在vue里表单控件不需要value 改为v-model 这里的v-model="msg"就是input框的值
而p标签的值也是用的msg 所以input框的值改变 p标签的值也会改变-->
<input type="text" v-model="msg">
<p>{{ msg }}</p>
</div>
<script src="vue.js"></script>
<script>
// 双向的数据绑定 使用v-model
new Vue({
el:"#app",
data(){
return {
msg:""
}
}
})
</script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<!--在vue里表单控件不需要value 改为v-model 这里的v-model="msg"就是input框的值
而p标签的值也是用的msg 所以input框的值改变 p标签的值也会改变-->
<input type="text" v-model="msg">
<p>{{ msg }}</p>
<textarea placeholder="add multiple lines" v-model="msg"></textarea>
<br /><br /><br />
<!--单个复选框,绑定到布尔值-->
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<br /><br /><br />
<!--多个复选框 使用数组保存 -->
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
<br> <br> <br>
<!--单选按钮-->
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>
<br> <br> <br>
<!--选中option的值他就是select的值-->
<select v-model="selected">
<!--disabled 不能被选中-->
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
<br> <br> <br>
<!--多选时 (绑定到一个数组)-->
<!--multiple按住ctrl就可以实现多选 -->
<select v-model="selected1" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected1: {{ selected1 }}</span>
<br> <br> <br>
<!--修饰符 lazy number trim -->
<!-- 在“change”时而非“input”时更新 (意思是输入完以后回车就更新)-->
<input v-model.lazy="msg">
<br> <br> <br>
<!--如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符 (意思是只能输入数值类型的)-->
<input v-model.number="age" type="number">
<br> <br> <br>
<!--如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符 (意思清楚前后空格)-->
<input v-model.trim="msg">
</div>
<script src="vue.js"></script>
<script>
new Vue({
el:"#app",
data(){
return {
msg:"",
checked: false,
checkedNames: [],
picked:"",
selected:"",
selected1:[],
age:0
}
}
})
</script>
</body>
</html>
组件化开发
组件数

-
全局组件
打油诗:声子 用子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--3.用子 <App /> 就是我们自定义的标签 你也可以写成<App></App>--> <!--不放在template可以放在el里一样的但是子组件要写template因为这样你才能够看清楚子组件的结构--> <App /> </div> <script src="vue.js"></script> <script> // 全局组件 // 第一个参数是组件的名字, 第二个参数options 它是全局组件 // <slot></slot> slot是vue中提供的内容组件 它会去分发内容 Vue.component('VBtn', { data(){ return{ } }, template:` <button><slot></slot></button> ` }) // 局部组件 // 声子 let Vheader = { data(){ return { } }, // Component template should contain exactly one root element // 意思是需要一个根元素吧他们包裹起来 // VBtn全局组件里面的字会替代slot template:` <div> <h2>日天</h2> <h2>alex</h2> <VBtn>登入</VBtn> <VBtn>注册</VBtn> <VBtn>提交</VBtn> <VBtn>删除</VBtn> </div> ` } // App header aside content // 子组件没有el 其他功能都有 // 1.声子 定义组件开头字母必须是大写, 因为这样才能跟标签区分, 组件中的data必须是函数 一定要有返回值 // 局部组件 let App = { data(){ return { text: "我是日天" } }, template:` <div> <h2>{{ text }}</h2> <Vheader></Vheader> <VBtn>退出</VBtn> </div> `, components:{ // 挂子 Vheader } } // 如果仅仅是实例化vue对象中 既有el 又有template, 如果template中定义模板的内容 // 那么template模板的优先级大于el new Vue({ el:"#app", data(){ return { msg:"alex" } }, components:{ // 2.挂子 // 如果key和value一样 可以只写一个 // App:App App } }) </script> </body> </html> -
局部组件
打油诗: 声子 挂子 用子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> {{ msg }} </div> <script src="vue.js"></script> <script> // 如果仅仅是实例化vue对象中 既有el 又有template, 如果template中定义模板的内容 // 那么template模板的优先级大于el new Vue({ el:"#app", data(){ return { msg:"alex" } }, template:` <div> <h2>{{ msg }}</h2> </div> ` }) </script> </body> </html>- 声明子
// App header aside content // 子组件没有el 其他功能都有 // 1.声子 定义组件开头字母必须是大写, 因为这样才能跟标签区分, 组件中的data必须是函数 一定要有返回值 let App = { data(){ return { text: "我是日天" } }, // 报错Component template should contain exactly one root element // 意思是需要一个根元素吧他们包裹起来, 所以这里用div包裹 template:` <div> <h2>{{ text }}</h2> <Vheader></Vheader> </div> ` }2.挂子
挂在那个组件, 这个组件就是我的父组件
template中的模板一定要有一个根元素
{ ''''''' // 3.用子 template:`<App />` components:{ // 挂子 App } } -
组件的嵌套
数据: 单向数据流
-
父子组件传值
父==>子
1.在子组件中 使用props声明 可以直接在子组件中任意使用
2.父组件 要定义自定义的属性
props
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <App /> </div> <script src="vue.js"></script> <script> Vue.component('VBtn', { data(){ return{ } }, props:["post_id"], template:` <button>{{ post_id }}</button> ` }) let Vheader = { data(){ return { } }, // 在子组件中 使用props声明 可以直接在子组件中任意使用 props:["msg", "post"], template:` <div> <h2>日天</h2> <h2>{{ msg }}</h2> <h3>{{ post.title }}</h3> <VBtn :post_id="post.id"></VBtn> </div> ` } let App = { data(){ return { text: "我是父组件的数据", post:{ id: 1, title: "我是头" } } }, // 父组件 要定义自定义的属性msg template:` <div> <h2>{{ text }}</h2> <Vheader :msg="text" :post="post"></Vheader> </div> `, components:{ // 挂子 Vheader } } new Vue({ el:"#app", data(){ return { msg:"alex" } }, components:{ App } }) </script> </body> </html>子==>父
1.子组件要用到vue里的内置放大$emit(“自定义属性”, 传递的值)
2.父组件自定义属性, 并实现该方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <App /> </div> <script src="vue.js"></script> <script> Vue.component('VBtn', { data(){ return{ } }, props:["id"], template:` <button @click="clickHandler">{{ id }}</button> `, methods:{ clickHandler() { // this.$emit("父组件自定义的时间", "传值") this.id++; this.$emit("clickHandler", this.id); } } }) let Vheader = { data(){ return { } }, // 在子组件中 使用props声明 可以直接在子组件中任意使用 props:["msg", "post"], template:` <div class="child"> <h1>我是header组件</h1> <h2>日天</h2> <h2>{{ msg }}</h2> <h3>{{ post.title }}</h3> <VBtn :id="post.id" @clickHandler="clickHandler"></VBtn> </div> `, methods:{ clickHandler(val){ alert(val); this.$emit("fatherHandler", val); }, } } let App = { data(){ return { text: "我是父组件的数据", post:{ id: 1, title: "我是头" } } }, // 父组件 要定义自定义的属性msg template:` <div> <h2>{{ text }}</h2> <h2>{{ post.id }}</h2> <Vheader :msg="text" :post="post" @fatherHandler="fatherHandler"></Vheader> </div> `, components:{ // 挂子 Vheader }, methods:{ fatherHandler(val){ this.post.id = val; } } } new Vue({ el:"#app", data(){ return { msg:"alex" } }, components:{ App } }) </script> </body> </html>5.平行组件传值
同级子组件传递值 $on 和 $emit不能使用this在平行组件传值时<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <App></App> </div> <script src="vue.js"></script> <script> let bus = new Vue(); // A==>B B要声明事件$on("事件的名字", function(){}) A要触发事件$emit("B组件中声明的事件名", 你要传进去的值) // 前提这两个方法必须绑定在同一个实例化对象(bus) // Test2 和 Test都是Vheader的子组件所以是平行组件 Vue.component("Test2", { data(){ return{ text:"" } }, template:` <h2>{{ text }}</h2> `, methods:{ }, created(){ bus.$on("testData", (val) => { this.text=val; alert(val); }) } }) Vue.component("Test", { data(){ return{ msg:"我是子组件的数据" } }, template:` <button @click="clickHandler">传递</button> `, methods:{ clickHandler(){ alert(1); console.log(bus); bus.$emit("testData", this.msg); } } }) let Vheader = { data(){ return { } }, template:` <div class="header"> <Test></Test> <Test2></Test2> </div> `, } let App = { data(){ return{ } }, methods:{ }, template:` <div class="app"> <Vheader></Vheader> </div> `, components:{ Vheader } } new Vue({ el:"#app", data(){ return { } }, methods:{ }, components:{ App } }) </script> </body> </html>
浙公网安备 33010602011771号