1、插值表达式&属性绑定
html
<!--template展示给用户,相当于MVVM模式中的V-->
<template>
<div class="first_div">
//插值表达式
<p>{{ message }}</p>
//这里的参数是从父组件的template里传过来的
<p>{{data_1}}</p>
//v-开头的是vue中的指令,使用v-bind来绑定属性(单向绑定,只能将model中的数据传给绑定的属性)
),可以动态改变属性值
<span v-bind:title="dream">学好vue不是梦!</span>
</div>
</template>
<!--<script>模块是m和vm结合的地方-->
<script>
export default {
name: "greeting.vue",
//函数
data() {
//return返回的是一个对象,可以是后端返回的数据
return {
message:"这是一个插值表达式的值",
dream:"小目标"//把这个绑定为标签属性值用到v-bind:
}
},
props:{
data_1:String
}
}
</script>
<!--设置元素样式的模块-->
<style scoped>
.first_div p{
color: red;
}
</style>
html
<div id="app">
<pre><a v-bind:href="url">菜鸟教程</a></pre>
</div>
<script>
new Vue({
el: '#app',
data: {
url: 'http://www.runoob.com'
}
})
</script>
在这里 href 是参数,告知 v-bind 指令将该元素的 href 属性与表达式 url 的值绑定。
v-bind 缩写
Vue.js 为两个最为常用的指令提供了特别的缩写:
html
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
2、v-if和v-show
html
<!-- v-if 指令将根据表达式 ifgao 的值(true 或 false )来决定是否插入 p 元素,会对DOM的新建和删除操作,增加前端开销 -->
<p v-if="ifgao">我是最帅的人~!!</p>
<!-- v-show 每次不会重新删除或者创建,只是改变了元素的可见属性display:none,一般会使用v-show而不是v-if-->
<p v-show="ifgao">我是最帅的人~!!</p>
<!-- v-if\v-else-if\v-else的用法-->
<p v-if="age>=70">{{username}},老人家你该休息了~</p>
<p v-else-if="age>=18">{{username}},欢迎光临,请开始吃鸡!~</p>
<p v-else>{{username}},小朋友,你的作业写完了吗!~</p>
data() {
return {
message: "这是一个插值表达式的值",
dream: "小目标",
ifgao:true,
username:"帅哥",
age:16
}
3、v-on_element_ui
v-on 指令,它用于监听 DOM 事件:
html
<a v-on:click="doSomething">
在这里参数是监听的事件名。
v-on
html
<template>
<div class="first_div">
<!-- v-on:可以缩写成@-->
<p v-on:click="username='大佬们'">{{username}},我是v-on~</p>
<p @click="username='大佬们menmen'">{{username}},我是v-on~的缩写@</p>
<p v-on:click="changeusername">{{username}},我是v-on的函数变量~</p>
</div>
</template>
<script>
export default {
name: "greeting.vue",
data() {
return {
message: "这是一个插值表达式的值",
dream: "小目标",
ifgao:true,
username:"帅哥",
age:16
}
},
props:{
data_1:String
},
methods:{
changeusername:function (){
this.username="dalao"
}
},
created() {
console.log("实例创建之后,能够获取到this");
console.log("username为:",this.username);
},
mounted() {
console.log("vue实例挂载到dom之后")
}
}
</script>
v-on 缩写
html
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
4、v-for
html
<table>
<tr>
<th v-for="(header_name,key) in project_header" v-bind:key="key">{{ header_name }}</th>
</tr>
<tr v-for="(item,key) in projects" v-bind:key="key">
<td>{{ item.name }}</td>
<td>{{ item.leader }}</td>
<td>{{ item.app_name }}</td>
</tr>
</table>
</template>
<script>
export default {
name: "projectlist",
data(){
return{
project_header:["项目名称","负责人","应用名称"],
projects:[
{name:"吊炸天的项目",leader:"飞天小子",app_name:"很牛逼的应用"},
{name:"非常厉害的项目",leader:"小旋风",app_name:"很神秘的应用"},
{name:"很完美的项目",leader:"阿童木",app_name:"666的应用"}
]
}
}
}
</script>
5、v-bind:使用v-bind来绑定属性
单向绑定,只能将model中的数据传给绑定的属性
v-model:
双向绑定:既能将model中的数据传给绑定的属性,也能将绑定的属性值传给model;
只能在input,textarea,select元素中使用;
1、插值表达式1 子组件中使用{{ msg}}插值,在<script>的export default中使用data(){return{msg:""}}传值;
2、插值表达式2 父组件中传入msg="",在子组件中使用{{ msg}}插值,在<script>的export default中使用props:{msg:String}
3、创建全局组件,在main.js文件中创建
java
import loginNew from "@/components/loginNew";
//创建全局组件
Vue.component('login-New',loginNew);//这样就不用在父组件内导入(import)和声明(components)子组件了
然后在App.vue根组件中调用就可以了,(不需要再去导入和声明了)
<login-New></login-New>
6、插槽
6.1 普通插槽
1、在父组件中直接调用子组件的标签,是可以渲染出子组件的内容;如果在子组件标签中添加了内容,父组件就渲染不出来了;
2、如果父组件调用的子组件标签中和子组件中的插槽中都有文本内容,那么父组件中的会覆盖子组件插槽中的内容;
index.js
以父组件为loginnew,子组件为hello-world为例;
html
<!--父组件loginnew.vue->>
<hello-world></hello-world>
<hello-world>这是个hello-world插槽位</hello-world>
<!--如果想要渲染出父组件中调用子组件标签中的内容,就要在子组件中添加插槽-->
<!--子组件hello-world.vue文件-->
<!--如果父组件调用的子组件标签中和子组件中的插槽中都有文本内容,那么父组件中的会覆盖子组件插槽中的内容-->
<slot><p>hello-world:我们一起学猫叫</p></slot>
6.2 具名/命名插槽
父组件loginNew.vue:
html
<template>
<div>
<el-form :model="ruleForm" status-icon ref="ruleForm" label-width="70px" class="demo-ruleForm"
:label-position="labelPosition">
<el-form-item label="用户名" prop="username">
<el-input type="username" v-model="ruleForm.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
<!-- 如果父组件调用的子组件标签中和子组件中的插槽中都有文本内容,那么父组件中的会覆盖子组件插槽中的内容-->
<!-- <hello-world>这是个hello-world插槽位</hello-world>-->
<!-- 如果父组件调用的子组件标签中和子组件中的插槽中都有文本内容,那么父组件中的会覆盖子组件插槽中的内容-->
<!-- <hello-world></hello-world>-->
<hello-world>
<!-- 方法二 命名插槽-->
<!-- 在vue2.6之前版本-->
<p slot="part1">一起喵喵喵</p>
<!-- 在vue2.6之后版本-->
<template v-slot:part2>
<p>在你面前撒个娇</p>
</template>
<!-- v-slot:可以简写成"#" -->
<template #part3>
<p>还是喵喵喵喵</p>
</template>
<!-- 插槽作用域:父组件调取子组件的插槽内部要获取子组件的属性-->
<!-- 2.6 之前-->
<p slot="part4" slot-scope="scope">
{{ scope.user }}我得心脏砰砰跳
</p>
<template slot="part5" slot-scope="scope">
<p>{{ scope.user }}我得心脏砰砰跳aaaaaa</p>
</template>
<!-- 2.6 之后-->
<template v-slot:part6="scope">
<p>{{scope.user}}都是你的味道</p>
</template>
<template v-slot:part7="{user}">
<p>{{user}}都是你的味道</p>
</template>
</hello-world>
</div>
</template>
<script>
export default {
name: "loginNew",
data() {
return {
username: "daxiao",
password: "123456",
labelPosition: "right",
ruleForm: {
username: "111",
password: "222",
}
}
},
}
</script>
<style scoped>
.el-form {
width: 350px;
margin: 50px auto;
}
</style>
子组件HelloWorld.vue:
html
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h>{{ msg1 }}</h>
<p>这是一个hello-world页面</p>
<div>
<el-image
style="width: 300px; height: 200px"
:src="url"
fit="cover"></el-image>
</div>
<!-- 第一种方式-->
<!-- <slot></slot>-->
<!-- 第二种方式-->
<slot><p>我们一起学猫叫</p></slot>
<!-- 第三种方式 命名插槽-->
<slot name="part1"></slot>
<slot name="part2"></slot>
<slot name="part3"></slot>
<!-- 插槽作用域-->
<slot name="part4" :user="username"></slot>
<slot name="part5" user="六啊"></slot>
<slot name="part6" user="七啊"></slot>
<slot name="part7" user="八啊"></slot>
<!-- <slot ></slot>-->
</div>
</template>
<script>
// import axios from 'axios';
import {dogs} from '../api/api'
export default {
name: 'HelloWorld',
props: {
msg: String
},
data() {
return {
url: '',
username: "木子"
}
},
mounted() {
//方法一:不推荐
// axios.get('https://dog.ceo/api/breeds/image/random')
// //如果请求成功,就会执行.then回调函数
// .then(function (response) {
// console.log('data:',response.data)
// console.log('response:',response)
// //此时的this指的是当前函数的应用
// this.url=response.data.message
// })
// //如果请求失败,就会执行.catch回调函数
// .catch(function (err) {
// console.log(err)
// });
// axios.get('https://dog.ceo/api/breeds/image/random')
// //如果请求成功,就会执行.then回调函数
// //方法二:使用箭头函数
// .then(response => {
// console.log('data:', response.data)
// console.log('response:', response)
// //此时的this指的是当前函数的应用
// this.url = response.data.message
// })
// //如果请求失败,就会执行.catch回调函数
// .catch(function (err) {
// console.log(err)
// });
dogs()
//如果请求成功,就会执行.then回调函数
//方法二:使用箭头函数
.then(response => {
console.log('data:', response.data)
console.log('response:', response)
//此时的this指的是当前函数的应用
this.url = response.data.message
})
//如果请求失败,就会执行.catch回调函数
.catch(function (err) {
console.log(err)
});
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>