Vue基本用法:组件
局部组件的使用:
如果实例化对象Vue对象中既有el,又有 template,并且 template 中定义了模板的内容,那么 template 模板的优先级大于el 。
示例代码:
<!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">
</div>
</body>
<script src="./vue.js"></script>
<script>
// 如果实例化对象Vue对象中既有el,又有 template,并且 template 中定义了模板的内容,那么 template 模板的优先级大于el
new Vue({
el: "#app",
data(){
return {
msg: "NEO"
}
},
template:`
<div>
<h2>{{ msg }}</h2>
</div>
`
// 由于 template 的优先级高于 el, 所以浏览器上会优先渲染 template 中的内容
})
</script>
</html>
浏览器效果示例:
组件三步走:
1、 声明子组件2、 挂载子组件: 在 components 中挂载子组件
3、 使用子组件: 在 html标签中,或 其它子组件的 template 中使用子组件,并且 在template中定义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">
</div>
</body>
<script src="./vue.js"></script>
<script>
// App 组件: header组件、 aside组件、 content组件
// 1. 声明子组件: Vue中组件的名字首字母要大写(跟标签做区分)
let App = { // 声明App组件,其对应的是一个对象,该对象跟 Vue 实例化的时候一样,唯一不同的是没有 el
data(){
// 在这个 data 中绑定当前组件()的数据属性
return {
myText: "neoneoneo"
}
},
// 渲染页面的时候, template 中的内容会替换到 <App /> --- 该组件(App)会渲染到页面
template:`
<div id="aa">
<h2>{{ myText }}</h2>
</div>
`,
}
// 如果实例化对象Vue对象中既有el,又有 template,并且 template 中定义了模板的内容,那么 template 模板的优先级大于el
new Vue({
el: "#app",
data(){
return {
msg: "NEO"
}
},
// 3. 使用子组件; <App /> 相当于一个自定义标签,你也可以把这个自定义标签定义为Div,为了和 <div> 标签区分,所以自定义的标签首字母要大写
template:`
<div id="bb">
<App />
</div>
`,
// 由于 template 的优先级高于 el, 所以浏览器上会优先渲染 template 中的内容
// 2. 挂载子组件
components:{
App // 等价于 App: App; key 和 value 一样的时候,可以只写一个 key
}
})
</script>
</html>
浏览器效果示例:
局部组件:Vue中没有 template 且 子组件挂载子组件
示例代码:
<!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">
<!-- 使用子组件 -->
<App />
</div>
</body>
<script src="./vue.js"></script>
<script>
let Vheader = {
data(){
return {
}
},
// 所有template 中的html内容,都要用一对闭合标签包裹起来,如: <div></div>
template:`
<div>
<h2>HELLO</h2>
<h2>WORLD</h2>
</div>
`
}
// 声明子组件
let App = {
data(){
return {
myText: "neoneoneo"
}
},
// template 用于定义模板的内容
// 把 Vheader 子组件在下面的template中使用
template:`
<div id="aa">
<h2>{{ myText }}</h2>
<Vheader />
</div>
`,
// 挂载子组件
components:{
Vheader
}
}
new Vue({ // 没有 template
el: "#app",
data(){
return {
msg: "NEO"
}
},
// 2. 挂载子组件
components:{
App // 等价于 App: App; key 和 value 一样的时候,可以只写一个 key
}
})
</script>
</html>
浏览器效果示例:
全局组件:
Vue全局组件用 Vue.component 去声明
示例代码:
<!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">
<App></App>
</div>
</body>
<script src="./vue.js"></script>
<script>
// 全局组件的注册: Vue.component(),第一个参数是组件的名字,第二个参数 options参数。全局组件可以在全局任意地方使用
Vue.component("VBtn",{
data(){
return {
}
},
template:`<button>按钮</button>`,
})
let Vheader = {
data(){
return {
}
},
// 全局组件使用的时候,,不需要再挂载
template:`
<div>
<h2>HELLO</h2>
<h2>WORLD</h2>
<VBtn></VBtn>
<VBtn />
</div>
`
}
let App = {
data(){
return {
myText: "neoneoneo"
}
},
// 全局组件使用的时候,,不需要再挂载
template:`
<div id="aa">
<h2>{{ myText }}</h2>
<Vheader />
<br/>
<VBtn />
</div>
`,
components:{
Vheader
}
}
new Vue({
el: "#app",
data(){
return {}
},
components:{
App
}
})
</script>
</html>
浏览器效果示例:
slot 组件:
<slot></slot> slot 是Vue 提供的内置组件,它能够分发内容
示例代码:
<!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">
<App></App>
</div>
</body>
<script src="./vue.js"></script>
<script>
Vue.component("VBtn",{
data(){
return {
}
},
// slot 标签是 Vue 的内置组件,<VBtn></VBtn>中的内容能够被分发到 slot 处
template:`
<button>
<slot></slot>
</button>
`,
})
let Vheader = {
data(){
return {
}
},
// <VBtn></VBtn> 中的“登陆”、“注册”能够被分发到 slot 处
template:`
<div>
<h2>HELLO</h2>
<h2>WORLD</h2>
<VBtn>登陆</VBtn>
<VBtn>注册</VBtn>
</div>
`
}
let App = {
data(){
return {
myText: "neoneoneo"
}
},
template:`
<div id="aa">
<h2>{{ myText }}</h2>
<Vheader />
<br/>
<VBtn />
</div>
`,
components:{
Vheader
}
}
new Vue({
el: "#app",
data(){
return {}
},
components:{
App
}
})
</script>
</html>
浏览器效果示例:
父子组件传值:
父组件向子组件传值:1. 在子组件中使用 props 声明自定义属性,这些自定义属性就可以直接在子组件中任意使用;
2. 父组件中要定义这些属性(步骤1中 props 声明的属性)
示例代码:
<!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">
</div>
</body>
<script src="./vue.js"></script>
<script>
// 全局组件 VBtn 从 父组件 Vheader 中获取值
Vue.component("VBtn",{
data(){
return {
}
},
template:`
<button>
按钮 {{ btid }}
</button>
`,
props: ['btid']
})
let Vheader = {
data() {
return {
}
},
// props 挂载父组件的属性;props 对应的是一个数组; props 中声明的属性就相当于在 data 中绑定了
// mypro 这个属性要在父组件中定义传值
props: ['mypro', 'post'],
// 在 template 中可以使用 mypro 这个自定义属性
template: `
<div>
<h2>HELLO</h2>
<h2>WORLD</h2>
<h6>{{ mypro }}</h6>
<p>{{ post.title }}</p>
<VBtn :btid="post.id"></VBtn>
</div>
`
}
// 声明子组件
let App = {
data() {
return {
myText: "我是父组件App中的数据",
child_pro: "要传给子组件的值",
post: {
id: 1,
title: 'My Journey with Vue'
}
}
},
// 父组件要把子组件自定义属性的值传过去,通过 v-bind
template: `
<div id="aa">
<h2>{{ myText }}</h2>
<Vheader :mypro='child_pro' v-bind:post="post"></Vheader>
</div>
`,
components: {
Vheader
}
}
new Vue({
el: "#app",
data() {
return {
msg: "NEO"
}
},
template: `<App />`,
components: {
App
}
})
</script>
</html>
浏览器效果示例:
props 传值官方文档:https://cn.vuejs.org/v2/guide/components-props.html#%E4%BC%A0%E9%80%92%E9%9D%99%E6%80%81%E6%88%96%E5%8A%A8%E6%80%81-Prop
子组件往父组件传值:
触发父组件中自定义声明的事件,需要使用 Vue 提供的内置 $emit 方法
示例代码:
<!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">
</div>
</body>
<script src="./vue.js"></script>
<script>
/* 想要实现的效果:点击 VBtn 中的按钮,修改App 中post对象的id值 */
Vue.component("VBtn",{
data(){
return {
// 把 父组件传递过来的 btnid 赋值给 bid
bid: this.btnid
}
},
// 给 button 添加一个点击事件
template:`
<button @click="vbtnToHeader">
按钮 {{ bid }}
</button>
`,
// props 中声明的属性,即相当于绑定到了 data 中
props: ['btnid'],
// 给button 中的点击事件添加对应的方法
methods: {
vbtnToHeader(){
console.log(this) // 每个组件中的 this 都是指该组件对象,即一个 VueComponent 对象
this.bid++;
console.log(this.btnid)
// $emit 是 Vue 提供的内置方法,用于触发父组件中自定义声明的事件。 this.$emit("父组件中自定义声明的事件", "要传递的值")
// vheaderClickHandler 是 VBtn 的父组件 Vheader 中对应的 自定义事件;后面的参数是传递到 vheaderClickHandler 对应的方法中
this.$emit('vheaderClickHandler', this.bid);
}
}
})
let Vheader = {
data() {
return {
}
},
props: ['mypro', 'post'],
// vheaderClickHandler 是自定义的事件(属性能自定义,事件也能自定义),该自定义事件绑定了一个方法 clickHandler
template: `
<div>
<h2>HELLO</h2>
<h2>WORLD</h2>
<h6>{{ mypro }}</h6>
<p>{{ post.title }}</p>
<VBtn :btnid="post.id" @vheaderClickHandler="clickHandler"></VBtn>
</div>
`,
methods:{
clickHandler(val){
alert(val);
// 这个 this 表示 Vheader 当前组件 VueComponent 对象
this.id = val; // 到这一步,就已经实现点击 VBtn 按钮修改按钮中id数据;但此时 post对象中id的值并没有改变;所以, 如果想要修改 post对象中id的值,就要接着往父组件emit
// 继续往父组件 emit 来修改 post 中id的值
this.$emit('updatePost', val)
}
}
}
let App = {
data() {
return {
myText: "我是父组件App中的数据",
child_pro: "要传给子组件的值",
post: {
id: 1,
title: 'My Journey with Vue'
}
}
},
template: `
<div id="aa">
<h1>post中的id :{{ post.id }}</h1>
<h2>{{ myText }}</h2>
<Vheader :mypro='child_pro' v-bind:post="post" @updatePost="updatePostHandler"></Vheader>
</div>
`,
components: {
Vheader
},
methods:{
updatePostHandler(val){
this.post.id = val;
}
}
}
new Vue({
el: "#app",
data() {
return {
msg: "NEO"
}
},
template: `<App />`,
components: {
App
}
})
</script>
</html>
浏览器效果示例:
平行组件传值:
假如 A 组件要向 B组件传值,即 A ==> B,那么接收方B要用 $on 声明事件, 发送方要用 $emit 触发事件。$on('事件的名字', function(val){}) // val 是要传过来的数据
$emit('A组件中声明的事件名', val) // val 是要传递过去的数据
// $on 和 $emit 这两个方法必须绑定在同一个实例化对象中(bus 对象)
平行组件的这种传值方式,不仅能用于平行组件之间传值,同样也能用于父传子、子传父。
示例代码:
<!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">
<!-- 使用 App 组件 -->
<App />
</div>
</body>
<script src="./vue.js"></script>
<script>
// $emit 和 $on 要绑定在同一个实例化对象中;该示例中我们绑定到一个全局变量 Vue 实例
let bus = new Vue(); // 这是一个新的 Vue 对象,和下面的Vue 对象不是同一个内存地址
// Test01 和 Test02 是平行的关系;现在想要实现的效果是点击按钮,就把 Test01 中的数据传递级给 Test02
Vue.component('Test02', {
data(){
return {
passedData:''
}
},
template:`
<h2>{{ passedData }}</h2>
`,
created(){
// 注意:要把 $on 绑定到 bus 上,而不能绑定到 this上;
bus.$on('passDataEvent', (val) => {
this.passedData = val;
console.log(this); // VueComponent
/*
注意:$on的第二个参数回调函数,不能用 function(){},要用箭头函数。如果用 function(){},那么函数中的 this 指的是当前对象,即 bus (Vue 对象);
用 箭头函数,this 的指向会发生改变,改为 声明了该对象的上下文,即 Test02 组件。
判断 this 指的是谁,只需要看是谁调用的该函数即可
*/
})
}
})
Vue.component('Test01', {
data(){
return {
msg:"我是 Test01 中的数据,我要去Test02"
}
},
template:`
<button @click="passDataHandler">传递</button>
`,
methods:{
passDataHandler(){
// $emit 绑定到 bus 上;注意:不能绑定到 this 上
bus.$emit('passDataEvent', this.msg); // 第一个参数是 $on 中声明的事件名,第二个参数是要传递的数据
}
}
})
let Vheader = {
data(){
return {
}
},
template:`
<div class="vheader">
<Test01 />
<Test02 />
</div>
`,
}
let App = {
data(){
return {
}
},
template:`
<div class="apps">
<Vheader />
</div>
`,
// 挂载
components:{
Vheader
}
}
new Vue({
el: "#app",
data(){
return {
}
},
// 挂载 App组件
components:{
App
}
})
</script>
</html>
浏览器效果示例:
点击按钮前:
点击按钮后:
以上是 Vue基本用法:组件 的全部内容, 来源链接: utcz.com/z/375911.html