哇,好久没有记录自己写代码的总结了,今天记录下,点赞,订阅,转发,感谢各位老铁的支持与厚爱。
给你七年时间,你会干什么?我想不出我会干什么耶,我只有确定的一件事情就是我会全国各地跑一遍
装饰器教程
Based on vue3.0.0, vant3.0.0, vue-router v4.0.0-0, vuex^4.0.0-0, vue-cli3, mockjs, imitating Jingdong Taobao, mobile H5 e-commerce platform! 基于vue3.0.0 ,vant3.0.0,vue-router v4.0.0-0, vuex^4.0.0-0,vue-cli3,mockjs,仿京东淘宝的,移动端H5电商平台!
ionic-5 vue3 starter with pwa and tailwind setup
响应式编程入门指南 - 通俗易懂 RxJS
RxJS系列教程(四) Observable
Angular7入门辅助教程(五)——Observable(可观察对象)
RXJS教程
RxJS——给你如丝一般顺滑的编程体验(篇幅较长,建议收藏)
动画学习 rxjs
有人开源躺平
开源躺平
Angular 笔记
Angular In Depth
三种价格设置
<template>
<div class="test">
<a-radio-group name="radioGroup" :default-value="1" v-model="selected">
<a-radio :value="1"> 零售价 </a-radio>
<a-radio :value="2"> 批发价 </a-radio>
<a-radio :value="3"> 团购价 </a-radio>
</a-radio-group>
<a-form-model ref="ruleForm" :model="ruleForm" layout="inline">
<div v-show="selected === 1">
<a-form-model-item label="销售价" prop="price">
<a-input placeholder="请输入销售价" />
</a-form-model-item>
<a-form-model-item label="吊牌价" prop="priceTag">
<a-input placeholder="请输入吊牌价" />
</a-form-model-item>
<a-form-model-item label="是否设置为默认价格">
<input type="radio" name="radio" :value="value" />
</a-form-model-item>
</div>
<div v-show="selected === 2">
<a-form-model-item label="销售价" prop="price">
<a-input placeholder="请输入销售价" />
</a-form-model-item>
<a-form-model-item label="吊牌价" prop="priceTag">
<a-input placeholder="请输入吊牌价" />
</a-form-model-item>
<a-form-model-item label="是否设置为默认价格">
<input type="radio" name="radio" :value="value" />
</a-form-model-item>
</div>
<div v-show="selected === 3">
<a-form-model-item label="销售价" prop="price">
<a-input placeholder="请输入销售价" />
</a-form-model-item>
<a-form-model-item label="吊牌价" prop="priceTag">
<a-input placeholder="请输入吊牌价" />
</a-form-model-item>
<a-form-model-item label="是否设置为默认价格">
<input type="radio" name="radio" :value="value" />
</a-form-model-item>
</div>
</a-form-model>
</div>
</template>
<script>
export default {
name: "test",
data() {
return {
ruleForm: {},
selected: 1,
labelCol: { span: 4 },
wrapperCol: { span: 14 },
value: true,
};
},
};
</script>
function cartesianProductOf(...args) {
return args.reduce(
(total, current) => {
let ret = [];
total.forEach(a => {
current.forEach(b => {
ret.push(a.concat([b]));
});
});
return ret;
},
[
[]
]
);
}
// main.js
const components = require('./components/index')
for (let componentName in components) {
Vue.component(componentName, components[componentName])
}
// vue.config.js
const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
chainWebpack: config => {
config.resolve.alias
.set('components', resolve('src/components/index.js'))
},
}
// index.js
const componentFiles = require.context('./', true, /index.js$/)
const components = componentFiles.keys().reduce((files, filePath) => {
const fileName = filePath.replace(/^\.\/(.*)\/index\.\w+$/, '$1')
const value = componentFiles(filePath)
if (value.default) {
const componentName = fileName.split('/')[0]
files[componentName] = value.default
} else {
for (let key in value) {
console.log("key===>", key, value[key])
files[key] = value[key]
}
}
return files
}, {})
module.exports = components
// entryTemplate.js
module.exports = {
entryTemplate: (compoenntName) => {
return `
import ${compoenntName} from './src'
export default ${compoenntName}
`
}
}
// genVueTpl.js
// index.js
const chalk = require('chalk')
const path = require('path')
const fs = require('fs')
const resolve = (...file) => path.resolve(__dirname, ...file)
const log = message => console.log(chalk.green(`${message}`))
const successLog = message => console.log(chalk.blue(`${message}`))
const errorLog = error => console.log(chalk.red(`${error}`))
// 导入模板
const {
vueTemplate
// entryTemplate
} = require('./template')
// 导入入口
const {
entryTemplate
} = require('./entryTemplate')
// 生成文件
const generateFile = (path, data) => {
if (fs.existsSync(path)) {
errorLog(`${path}文件已存在`)
return
}
return new Promise((resolve, reject) => {
fs.writeFile(path, data, 'utf8', err => {
if (err) {
errorLog(err.message)
reject(err)
} else {
resolve(true)
}
})
})
}
log('请输入要生成的vue文件夹名称 views: xxx、comp: xxx、pageComp: xxx、 它们会生成在对应的文件目录下')
let componentName = ''
process.stdin.on('data', async chunk => {
// 组件名称
const inputName = String(chunk).trim().toString().split(':')[1]
// 判断放在那个文件夹里面
let pathName = String(chunk).trim().toString().split(':')[0]
let componentPath = null
let entryFile = null
switch (pathName) {
case 'views':
pathName = 'views'
componentPath = resolve(`../src/${pathName}`, inputName)
break
case 'comp':
pathName = 'components'
componentPath = resolve(`../src/${pathName}`, inputName, 'src')
entryFile = resolve(`../src/${pathName}`, inputName, 'index.js')
break
case 'pageComp':
pathName = 'pageComponents'
componentPath = resolve(`../src/${pathName}`, inputName, 'src')
entryFile = resolve(`../src/${pathName}`, inputName, 'index.js')
break
}
// Vue页面组件路径
// vue文件
const vueFile = resolve(componentPath, 'index.vue')
// 入口文件
// 判断组件文件夹是否存在
const hasComponentExists = fs.existsSync(componentPath)
if (hasComponentExists) {
errorLog(`${inputName}页面组件已存在,请重新输入`)
return
} else {
log(`正在生成 ${inputName} 的目录 ${componentPath}`)
await dotExistDirectoryCreate(componentPath)
if (pathName === 'views') {
log(`正在生成页面子组件 components 的目录 ${componentPath}\\components`)
await fs.mkdir(`${componentPath}\\components`, err => {
log(err)
})
}
}
try {
// 获取组件名
if (inputName.includes('/')) {
const inputArr = inputName.split('/')
componentName = inputArr[inputArr.length - 1]
} else {
componentName = inputName
}
log(`正在生成 vue 文件 ${vueFile}`)
await generateFile(vueFile, vueTemplate(componentName))
log(`正在生成 entry 文件 ${entryFile}`)
if (entryFile) {
await generateFile(entryFile, entryTemplate(componentName))
}
successLog('生成成功')
} catch (e) {
errorLog(e.message)
}
process.stdin.emit('end')
})
process.stdin.on('end', () => {
log('exit')
process.exit()
})
function dotExistDirectoryCreate(directory) {
return new Promise((resolve) => {
mkdirs(directory, function () {
resolve(true)
})
})
}
// 递归创建目录
function mkdirs(directory, callback) {
var exists = fs.existsSync(directory)
if (exists) {
callback()
} else {
mkdirs(path.dirname(directory), function () {
fs.mkdirSync(directory)
callback()
})
}
}
// template.js
module.exports = {
vueTemplate: compoenntName => {
return `<template>
<div class="${compoenntName}__wrapper"></div>
</template>
<script>
export default {
name: '${compoenntName}',
components: {},
mixins: [],
props: {},
data() {
return {}
},
computed: {},
watch: {},
created() {},
mounted() {},
destroyed() {},
methods: {}
}
</script>
<style lang="scss" scoped>
.${compoenntName}__wrapper {
}
</style>
`
}
}
/*第一层if判断生产环境和开发环境*/
if (process.env.NODE_ENV === 'production') {
/*第二层if,根据.env文件中的VUE_APP_FLAG判断是生产环境还是测试环境*/
if (process.env.VUE_APP_FLAG === 'pro') {
//production 生产环境
axios.defaults.baseURL = 'http://api.xinggeyun.com';//路径
} else {
//test 测试环境
axios.defaults.baseURL = 'http://192.168.0.152:8102';//路径
}
} else { //dev 开发环境
axios.defaults.baseURL = 'http://192.168.0.152:8102';//路径
}
<a-form-item label='地址' :colon="false">
<a-cascader
:allowClear="false"
v-decorator="['area',{rules: [{ required: true, message: '请选择地址' }]}]"
:options="areaList"
placeholder="请选择地址"
:loadData="loadAreaData"
@change="onAreaChange"
:getPopupContainer="(trigger) => {return trigger.parentElement}"
></a-cascader>
</a-form-item>
data () {
return {
areaList: [], // 地区数据
}
},
async mounted () {
// 获取省数据
this.areaList = await this.getAreaList() || []
},
methods: {
/**
* 获取区域
*/
getAreaList (code) {
return new Promise((resolve, reject) => {
getAreaData({
code: code ? String(code) : ''
}).then(res => {
console.log('获取区域------', res)
if (res.code === '0') {
let arr = res.data.map(item => {
return {
value: item.code + '',
label: item.name,
isLeaf: item.level === '3'
}
})
return resolve(arr)
} else {
return resolve([])
}
}).catch((err) => {
return reject(err)
})
})
},
// 获取下一级数据
async loadAreaData (selectedOptions) {
if (!this.areaList.length) {
this.areaList = await this.getAreaList() || []
} else {
const targetOption = selectedOptions[selectedOptions.length - 1]
targetOption.loading = true
let children = await this.getAreaList(targetOption.value) || []
if (children.length) {
targetOption.loading = false
targetOption.children = children
} else {
targetOption.loading = false
targetOption.isLeaf = true
}
}
this.areaList = cloneDeep(this.areaList)
},
// 选择区后
onAreaChange (val, selectedOptions) {
this.provinceCode = selectedOptions[0] ? selectedOptions[0].value : ''
this.province = selectedOptions[0] ? selectedOptions[0].label : ''
this.cityCode = selectedOptions[1] ? selectedOptions[1].value : ''
this.city = selectedOptions[1] ? selectedOptions[1].label : ''
this.regionCode = selectedOptions[2] ? selectedOptions[2].value : ''
this.region = selectedOptions[2] ? selectedOptions[2].label : ''
},
}
mounted () {
const userAgent = navigator.userAgent
if (userAgent.indexOf('Edge') > -1) {
this.$nextTick(() => {
this.collapsed = !this.collapsed
setTimeout(() => {
this.collapsed = !this.collapsed
}, 16)
})
}
const oMenus = document.querySelector('.ant-menu.ant-menu-inline.ant-menu-root.ant-menu-dark')
oMenus.addEventListener('click', (e) => {
const url = e.target.getAttribute('href')
if (url) {
this.$router.push({
path: url + '?t=' + new Date().getTime()
})
}
setTimeout(() => {
this.$router.push(url)
}, 16)
console.log('url====>', url)
})
// first update color
// TIPS: THEME COLOR HANDLER!! PLEASE CHECK THAT!!
if (process.env.NODE_ENV !== 'production' || process.env.VUE_APP_PREVIEW === 'true') {
updateTheme(this.settings.primaryColor)
}
},
<router-view :key="getPath"/>
computed: {
...mapState({
// 动态主路由
mainMenu: state => state.permission.addRouters
}),
getPath () {
return this.$route.fullPath
}
},