首先,贴一张vue脚手架的目录
创建组件及引用组件
【创建组件】要在项目目录的components文件夹下(建议新建组件文件命名时,首字母大写)
--------新建User.vue组件--------
<template> <!-- 当前组件的具体内容 -->
<div class="Users">
<ul>
<li v-for="every in arr" :key="every.id">
{{every}}
</li>
</ul>
</div>
</template>
<script>
export default {
name: "Users", //当前组件暴露出去的名称
data(){
return {
arr:["亚索","剑姬","卡萨","露露"]
}
},
}
</script>
<style scoped></style> //scoped--域,使css样式仅在当前组件生效
【引用组件】引用User.vue组件
***引用组件方法一:在App.vue中直接引用(一般用这种方法)
<template>
<div id="app">
<c-users></c-users> //3、使用组件
</div>
</template>
<script>
import Users from './components/Users' //1、引入组件
export default {
name: 'App',
data(){
return {
}
},
components:{
"c-users":Users, //2、在components中注册当前组件,可以在注册的同时命名,如这里的"c-users":Users,也可以直接注册组件如直接写Users,
},
}
</script>
<style></style>
***引用组件方法二:在main.js中将当前组件注册为全局组件再引用(方法二用的少)
import Vue from 'vue'
import App from './App'
import router from './router'
import Users from './components/Users.vue' //1、引入Users组件
Vue.config.productionTip = false
Vue.component("c-users",Users); //2、注册为全局组件并命名为c-users,之后在App.vue中调用<c-users></c-users>即可
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
属性传值
视频详解:https://www.bilibili.com/video/BV1Zy4y1K7SH?p=80&spm_id_from=pageDriver&vd_source=68c192f46144033a83d392c1229dc275
文章详解:https://juejin.cn/post/6844903887162310669
属性传值(父组件向子组件传值。传值:string boolean number 传引用:array object)
当一组数据有多个子组件复用的时候,我们可以在父组件中定义,并在子组件需要的时候传递给子组件,以简化代码
【父组件App.vue】
<template>
<div id="app">
<c-users v-bind:transValue="oldValue"></c-users> <!-- 1、绑定oldValue数据,并将数据命名为transValue,绑定后传递到子组件 -->
</div>
</template>
<script>
import Users from './components/Users'
export default {
name: 'App',
data(){
return {
oldValue:[Jack,Honey,Tandin,Lucy] ,
}
},
components:{
"c-users":Users,
},
}
</script>
<style></style>
【子组件User.vue】
<template>
<div class="Users">
<div>{{newValue}}</div>
</div>
</template>
<script>
export default {
name: "Users",
props:{ /*2、子组件拿取父组件传递的数据 */
transValue:{
type:Boolean, /*多种可能的类型[Array,String],type可以是String,Number,Boolean,Array,Object,Date,Function,Symbol*/
required:true, /*是否必需*/
default:true, /*设置默认值(可不写)*/
},
list:{
type: Array,
required:false,
default: ()=>[], //注:类型为Object/Array的必须使用函数返回默认值,()=>[a,b,c]或function(){return [a,b,c]}
}
},
data(){
return {
newValue:this.transValue, /*【这里传的是引用,所以赋值给新变量以解决传引用引起的问题】*/
}
},
}
</script>
<style></style>
******提个醒儿******:因为vue的父子组件数据传递是单向的数据流。故子组件应避免直接改变父组件传入的数据,否则会引起报错(虽然功能上没什么问题)
通过【传引用】方式传入的数据在当前子组件中更改后,在其他子组件中也会相应改变。而通过【传值】方式传入的数据则各自独立互不干扰。
引用类型:保存在堆中,占用空间不固定,保存和复制的是指向对象的一个指针;值类型:保存在栈中,占用空间固定,保存和复制的是值本身
当数据格式是Number Boolean String时,是传值。当数据格式是Array Object时,是传引用
******如何解决******:将父组件传递过来的值赋值给一个新的变量,在子组件中操作新的变量即可。
******解决异步传值问题******
问题:子组件从父组件拿到的是空值
原因:父组件的值是需要通过异步请求拿到的,但在异步请求还未获取到结果时,已经初始化加载了子组件,所以传了data里定义的空值。
解决:在父组件未拿到值之前,不执行子组件的初始化加载,异步请求成功后,再执行加载,如下
<Son v-if="flag" :datalist="datalist"></Son>
data(){
return{
flag:false,
datalist:[],
}
}
this.$axios.get(`${api.base}/getdata`).then(res=>{
if(res.data.code==200){
this.datalist=res.data.data
this.flag=true //在异步请求拿到值后,设置flag为true,此时开始加载子组件
}
}).catch(err=>{})
属性传值(子组件向父组件传值)
即子组件改变父组件的值,父组件反过来又影响子组件
【User.vue】子组件
<template>
<div class="Users">
<button v-on:click="dataTrans">子向父传值</button> <!-- 1、定义子向父传值的dataTrans点击事件 -->
</div>
</template>
<script>
export default {
name: "Users",
data(){
return {
}
},
methods:{
dataTrans:function(){ /* 2、dataTrans子向父传值事件执行,开始去往父组件寻找dataSend事件 */
this.$emit("dataSend","我是一个值")
}
},
}
</script>
<style></style>
【App.vue】父组件
<template>
<div id="app">
<c-users v-on:dataSend="dataChange($event)" ></c-users>
<!-- 3、寻找到dataSend事件,再往下寻找dataChange事件,dataChange中的$event必须要这么写 -->
</div>
</template>
<script>
import Users from './components/Users'
import Mans from './components/Mans'
export default {
name: 'App',
data(){
return {
title:"我是父组件原本的title"
}
},
components:{
"c-users":Users,
},
methods:{
dataChange(val){ /* 4、寻找到dataChange事件,将步骤2中的数据"我是一个值"传递进来(val是形参,命名随意) */
this.title=val /* 5、将步骤2中的数值赋值给父组件中的title,此时title就改变了,子向父传值完成 */
}
}
}
</script>
<style></style>
解决vue跨域请求的问题,以及使用fetch,axios请求数据
当浏览器报类似于这样的错误时:localhost/:1 Failed to load http://www.thenewstep.cn/test/testToken.php: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
1、我们需要找到config/index.js页面,然后搜索proxyTable
2、将proxyTable重设:
proxyTable: {
'/apis': {
// 测试环境
target: 'http://www.thenewstep.cn/', // 接口域名,改成自己请求的接口域名即可
changeOrigin: true, //是否跨域
pathRewrite: {
'^/apis': '' //需要rewrite重写的,
}
}
3、我们去使用fetch写请求:
在如App.vue中请求数据
<script>
export default{
created(){
fetch {"/apis/test/testToken.php",{ /*这里的apis就是proxyTable里定义的代理*/
method:"post",
headers:{
"Content-type":"application/json",
token:"32erqwdf3rtw3rwef313ewet",
},
body:JSON.stringify({username:"二狗子",password:"123456"})
}}.then(result=>{
return result.json()
}).then(data=>{
console.log(data)
})
}
}
</script>
我们也可以使用axios写请求:
安装xios包:npm install axios
在main.js中引入axios, import axios from "axios"
在main.js中重定义axios,Vue.prototype.$axios=axios (这样做是为了能够全局使用)
在main.js中设置axios的请求头和content-type:
axios.default.headers.common['token']="32ed3wqefd432442f231ewq"
axios.default.headers.post['Content-type']="application/json"
在如App.vue中请求数据
<script>
export default{
created(){
this.$axios.post("/apis/test/testToken.php",{username:"二狗子",password:"123456"}).then(data=>{
console.log(data)
})
}
}
</script>
4、一定一定要重新启动项目
</script>
vue-cli3.0关于webpack的配置文件config,build已经被删除,若是需要进行配置需要自己手动建立一个vue.config.js
具体参考官方文档:https://cli.vuejs.org/zh/config/#vue-config-js
示例【vue.config.js】
module.export={
publicPath:'/', /*根路径*/
outputDir: 'dist1', /*构建输出目录*/
assetsDir: 'assets', /*静态资源目录(js,css,img,fonts)*/
lintOnSave:false, /*是否开启eslint保存检测(严格模式),有效值:true||false||'error'*/
devServer:{
open:true, /*项目启动时是否自动打开网页*/
host:'127.0.0.0', /*域名*/
port:9000, /*端口号*/
https:false, /*https设置*/
proxy:{ /*跨域配置*/
'apis':{
target: 'http://www.thenewstep.cn/', // 接口域名,改成自己请求的接口域名即可
changeOrigin: true, //是否跨域
pathRewrite: {
'^/apis': '' //需要rewrite重写的,
}
}
},
}
vue-cli2.0使用less
1、安装less依赖:npm install less less-loader --save
2、修改webpack.base.conf.js文件,配置loader加载依赖,让其支持外部的less,在原来的代码上添加:
module:{
rules:[
/*添加less配置代码*/
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader",
options: { sourceMap: true } // 可以在控制台中看到当前标签样式来自于哪个less文件
},
{
test:/\.vue$/,
loader:'vue-loader',
options:vueLoaderConfig
},
。。。。。。
]
}
3、在style中使用,添加lang="less"
<style scoped lang="less"></style>
除vue定义好的按键修饰符(如enter,space等)之外,自定义按键修饰符
<template>
<input type="text" @keyup.f6="add()" />
</template>
<script>
Vue.config.keyCodes.f6=117
</script>
针对vue中外部样式不生效问题
使用>>>操作符穿透scoped。
但有些Sass,less之类的预处理器无法正确解析 >>>。可以使用 /deep/ 操作符( >>> 的别名)
如
<style scoped lang="less">
/deep/ .demo{
margin-bottom:10px;
color:#ccc;
}
</style>
解决浏览器缓存导致异步请求后页面不更新的问题
一般在请求静态资源的时候,浏览器检测不是新数据的话,则会从缓存中读取而不会去进行更新,从而导致后台提交数据后前台不更新的问题。
解决方法1:ctrl+shift+delete呼出浏览器缓存选项,清除缓存即可。但这样的操作对用户不友好,不推荐
解决方法2:控制台中Network里选中Disable cache使浏览器不保存缓存,仅适合开发人员用。
解决方法3:在请求接口的时候带上随机数或者时间戳即可(推荐使用)
getContent(content){
this.$axios.get(`${common.base}/getDemoList?t=${Math.random()}`).then(res=>{ //添加随机数 `t=${Math.random()}` 或 时间戳 `t=${new Date().getTime()}`
this.demoList=res.data.list
}).catch(err=>{})
},