一、创建vue项目
第一步:安装vue
sudo npm install -g @vue/cli(没有权限问题不需要写sudo)
第二步:选择配置
Please pick a preset: Default (Vue 3) ([Vue 3] babel, eslint)
第三步:依次输入下图命令即可启动vue项目,我的项目叫做 newstart
报错 Parsing error: x-invalid-end-tag vue/no-parsing-error
网上查到解决方案:
方法一:
vscode里面选择 设置 搜索 vetur.validation.template 把对勾去掉(我的vscode里面没有搜到)
方法二:
打开项目中的package.json文件,找到并在rules中添加
“vue/no-parsing-error”: [2, { “x-invalid-end-tag”: false }]
另一种可能出现该错误的问题就是,你的开闭标签不一致,看看有没有写错!
二、模版语法
1、v-if和v-show的区别
v-if 和v-show的区别,当条件是false的时候,v-if的内容不会出现在dom中,而v-show会被渲染到dom解构中,只不过是display为none
2、v-for 循环显示列表
<ul>
<li v-for="(v, i) of fruits" :key="i">{{ v }}</li>
</ul>
3、组件嵌套
开发多页面应用,需要嵌套多个组件,将这些组件写到项目的components目录下,需要在父组件中引入子组件,并且注册该组件
<template>
<div>//外层包裹所有要引入的组件
<HelloWord/>
//引入外部组件之后要在该组件中使用,否则会报错如下图
<p>{{myData}}</p>
</div>
</template>
<script>
import HelloWord from "./components/HelloWorld.vue";//引入外部组件
export default {
components: {//注册组件
HelloWord,
},
data() {
return {
fruits: ["apple", "banana", "peal"],
};
}
};
</script>
引入的组件,在使用的时候可以将名称用“-”连接使用,例如引入MenuList,在使用时可以写成:< Menu-List/ >、< Menu-list/ >、< menu-List/ >、< menu-list/ >,不区分大小写,但是为了规范还是推荐使用< Menu-List/ >
三、组件传值
父级向子级传值:使用属性传值==
在父组件中:import引入子组件 + v-bind 给子组件绑定属性
子组件:在export default { }中添加props生命传递过来的属性
export default {
props:['msg'] //这里的msg是父级给子组件传递的属性名
}
子组件向父组件传值:使用自定义方法
第一步:在父级中定义一个自定义事件
第二步:在父组件中将自定义的子组件的方法传递出去,子组件中使用
this.$emit( ‘自定义函数名’ , [要传递的值] )
附上代码:
//父级组件
<template>
<div>
<HelloWord :msg='message' @myClick='changeData'/> <!-- 绑定自定义事件 -->
<p>{{myHelloData}}</p>
<hr/>
<Child :msg='myData' @clickChild='changeChildData' />
<p>{{myChildData}}</p>
</div>
</template>
<script>
import HelloWord from "./components/HelloWorld.vue";
import Child from './components/Child.vue';
export default {
components: {
HelloWord,
Child,
},
data() {
return {
message: "hi hello world",
myData:'初始值父级',
myHelloData:'waiting hello data',
myChildData:'waiting child data'
};
},
methods: {
changeData(data){
this.myHelloData=data
},
changeChildData(data){
this.myChildData=data
}
},
};
</script>
//两个子组件
//子组件一:Child.vue
<template>
<div>
<p>{{msg}}</p>
<button @click="sendData" >child传递数据给父组件</button>
</div>
</template>
<script>
export default {
props: ["msg"],
data() {
return {
message: "I`m Child",
};
},
methods: {
sendData() {
this.$emit("clickChild", this.message);
},
},
}
</script>
//子组件二:HelloWorld.vue
<template>
<h1>{{ msg }}</h1>
<button @click="changeData">改变数据</button>
</template>
<script>
export default {
props: ["msg"],
data(){
return{
time:'2022-02-08'
}
},
methods:{
changeData(){
this.$emit('myClick',this.time)
}
}
};
</script>
分别点击按钮实现子传父,改变父级数据
动图在线制作:https://gif.55.la/
数据共享
利用store,兄弟组件之间通过引入store.js文件,共享状态和方法
四、计算属性与侦听器
一、计算属性
计算属性computed和data属性都可以直接绑定在表达式中,当有多步计算时候为了避免在表达式中出现复杂逻辑,我们将计算逻辑写在计算属性中,直接在表达式中绑定计算属性即可,如下简单🌰
<template>
<p>单价:{{ price }}</p>
<p>
<button @click='sub'>-</button> 数量:{{ quantity }}<button @click='add'>+</button></p>
<p>折扣:{{ discount }}</p>
<p>总价:{{ total }}</p>
</template>
<script>
export default {
data() {
return {
price: 99,
quantity: 0,
discount: 0.5,
};
},
computed: {
total() {
return this.price * this.discount * this.quantity;
},
},
methods:{
add(){
this.quantity++
},
sub(){
if(this.quantity>0){
this.quantity--
}
}
}
};
</script>
![](https://img-blog.csdnimg.cn/9a25b98409d94a3fa4788d00f49660b3.gif#pic_center)
二、监听器
监听器和计算属性类似,代码只需做以下改动
......
data() {
return {
price: 99,
quantity: 0,
discount: 0.5,
total:0 //添加total属性值
};
},
// computed: {
// total() {
// return this.price * this.discount * this.quantity;
// },
// },
watch:{
//添加监听器监听quantity的变化,一旦发生改变就会触发函数执行
quantity(val){
this.total=this.price * this.discount * val;
}
},
......
计算属性和侦听器的对比
当多个数据变化影响单个值的变化,就用计算属性(为了得到一个值)
当一个值改变影响多个值变化(或者处理多件事),一般用侦听器(为了观察一个值)
但是实际开发中大部分问题用计算属性就可以解决!
五、生命周期钩子
create()在组件初始化完成时候自动调用(先)
mounted()模版已创建时候调用(后)
以下代码用定时器模拟异步请求,2秒时候初始化完成调用created函数,实现页面展示fruits列表内容的功能
created() {
this.getdata();
},
methods: {
getdata() {
setTimeout(() => {
this.fruits = ["apple", "peal", "orange"];
this.isloading = false;
}, 2000);
},
插槽、DOM操作、过滤器
一、插槽
粗俗的理解:插槽用来占坑,具名插槽就是萝卜对号入座
萝卜:有几个坑(插槽slot)就有几个萝卜(template)
< template v-slot:对应插槽(坑)的名称 />
坑:< slot name=‘自定义的名称’/>
<template v-slot:header>
<h1>头部</h1>
</template>
<template v-slot:content>
<h1>内容</h1>
</template>
<template v-slot:footer>
<h1>尾部</h1>
</template>
<p><slot name='header'></slot></p>
<p><slot name='content'></slot></p>
<p><slot name='footer'></slot></p>
二、DOM操作
利用ref获取真实dom
给组件设置ref属性,使用 this.$refs.属性名 来绑定该组件,使用getComputedStyle( )获取到样式
mounted(){
let myRef=this.$refs.myRef
let width=getComputedStyle(myRef).width
console.log('width',width)
}
三、过滤器
在2.x中,开发人员可以使用过滤器来处理常见的文本格式。
< h1> {{ date | dateFormate}}< /h1>
" | "前面是要加工的数据,后面是过滤器,过滤器函数写在filters对象里面,将处理后的结果返回。
filters:{
dateFormate(){
…
return ${year}年${month}月${d}日
}
},
在3.x中,过滤器被删除,不再受支持。 相反,我们建议用方法调用或计算属性替换它们。